SSH Certificates with step-ca

DateReadtime 4 minutes Series Part 2 of Step CA tools Tags
ca / tls / ssh

Installation

Follow instructions on the previous post or the step readme

Setup

Create required root and SSH signing keys:

$ step ca init --ssh
✔ What would you like to name your new PKI? (e.g. Smallstep): Whatsdoom
✔ What DNS names or IP addresses would you like to add to your new CA? (e.g. ca.smallstep.com[,1.1.1.1,etc.]): ca.example.com
✔ What address will your new CA listen at? (e.g. :443): :8443
✔ What would you like to name the first provisioner for your new CA? (e.g. you@smallstep.com): you@example.com
✔ What do you want your password to be? [leave empty and we'll generate one]:

Generating root certificate...
all done!

Generating intermediate certificate...

Generating user and host SSH certificate signing keys...
all done!

✔ Root certificate: /home/paul/.step/certs/root_ca.crt
✔ Root private key: /home/paul/.step/secrets/root_ca_key
✔ Root fingerprint: f86a0243f05130bcd159be795ac107fcffde748c9b29bf01a05c3dc41a865eee
✔ Intermediate certificate: /home/paul/.step/certs/intermediate_ca.crt
✔ Intermediate private key: /home/paul/.step/secrets/intermediate_ca_key
✔ SSH user root certificate: /home/paul/.step/certs/ssh_user_ca_key.pub
✔ SSH user root private key: /home/paul/.step/secrets/ssh_user_ca_key
✔ SSH host root certificate: /home/paul/.step/certs/ssh_host_ca_key.pub
✔ SSH host root private key: /home/paul/.step/secrets/ssh_host_ca_key
✔ Database folder: /home/paul/.step/db
✔ Templates folder: /home/paul/.step/templates
✔ Default configuration: /home/paul/.step/config/defaults.json
✔ Certificate Authority configuration: /home/paul/.step/config/ca.json

Your PKI is ready to go. To generate certificates for individual services see 'step help ca'.

FEEDBACK 😍 🍻
    The step utility is not instrumented for usage statistics. It does not
    phone home. But your feedback is extremely valuable. Any information you
    can provide regarding how you’re using `step` helps. Please send us a
    sentence or two, good or bad: feedback@smallstep.com or join
    https://gitter.im/smallstep/community.

You'll notice that this time four additional files were created. We'll use the ssh host and ssh user key pairs in the following steps.

Configuring SSHD

Copy the user ca public key to the SSH directory for all the hosts:

sudo ln /home/paul/.step/certs/ssh_user_ca_key.pub /etc/ssh/
sudo chown root:root /etc/ssh/ssh_user_ca_key.pub
sudo chmod 644 /etc/ssh/ssh_user_ca_key.pub

Sign the host's SSH key, this will help clients to get around those pesky "The authenticity of host" prompts when you connect to a host for the first time:

$ sudo step ssh certificate $HOSTNAME /etc/ssh/ssh_host_ecdsa_key.pub --host --sign
✔ Provisioner: paul@whatsdoom.com (JWK) [kid: S3ayxHbapfYPGIxr7W1PM1BRbAYE5Is4FfE1Cle-9xU]
✔ Please enter the password to decrypt the provisioner key:
✔ CA: https://ca.whatsdoom.com:8443
✔ Certificate: /etc/ssh/ssh_host_ecdsa_key-cert.pub

Edit the SSHD config file (/etc/ssh/sshd_config)) to point to the new user ca and our new host certificate:

TrustedUserCAKeys /etc/ssh/ssh_user_ca_key.pub
HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub

After you make the changes to the config file, ensure it can still be parsed:

sudo sshd -t

Restart the SSH service:

sudo service ssh restart

Configuring SSH on local machine

On the CA server, copy the value of the ssh_host_ca_key.pub file to add your ~/.ssh/authorized_keys file:

$ cat ~/.step/certs/ssh_host_ca_key.pub
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBYVt/6XWuJuNiRdUt/2G/4XEsrJnwW0MqzOKY3+Up5Y0n40nOF1CyBNpFaBbFaWjUfWDvgm+9wVgDnGhW0UXvU=

Add your cert authority configuration to the authorized_keys file on the client machine:

echo "@cert-authority www1.whatsdoom.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPrvMrLPN/zxEfKS5phzZWeAzc6Lv21xxZWkkz7EhDH0VeygkigsU8RYGLKMjTlHXUxc8CQxI8OzrSVUvRJ5//I=" >> ~/.ssh/known_hosts

The previous step helps to avoid messages like:

$ ssh server.example
The authenticity of host 'server.example (server.example)' can't be established.
ECDSA key fingerprint is SHA256:INbyCz7rwqsj1JN/R9CYTaukuI9WsdwmLqKjkO2VZBB.
Are you sure you want to continue connecting (yes/no)?

Perhaps more importantly, you can avoid messages like the following if you ever re-key or recreate a server:

$ ssh server.example
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:INbyCz7rwqsj1JN/R9CYTaukuI9WsdwmLqKjkO2VZBB.
Please contact your system administrator.
Add correct host key in /home/paul/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/paul/.ssh/known_hosts:1
remove with:
ssh-keygen -f "/home/paul/.ssh/known_hosts" -R "server.example"
ECDSA host key for server.example has changed and you have requested strict checking.
Host key verification failed.

Ensure the CA server is running

On your server ensure that the server is running:

$ step-ca $(step path)/config/ca.json
Please enter the password to decrypt /home/paul/.step/secrets/intermediate_ca_key:
Please enter the password to decrypt /home/paul/.step/secrets/ssh_host_ca_key:
Please enter the password to decrypt /home/paul/.step/secrets/ssh_user_ca_key:
2020/02/25 00:46:37 Serving HTTPS on :8443 ...

Generating keys to connect to remote server

Create a new SSH key pair with a certificate:

$ step ssh certificate paul@whatsdoom id_ecdsa
✔ Provisioner: paul@whatsdoom.com (JWK) [kid: S3ayxHbapfYPGIxr7W1PM1BRbAYE5Is4FfE1Cle-9xU]
✔ Please enter the password to decrypt the provisioner key:
✔ CA: https://ca.whatsdoom.com:8443
Please enter the password to encrypt the private key:
✔ Private Key: id_ecdsa
✔ Public Key: id_ecdsa.pub
✔ Certificate: id_ecdsa-cert.pub
✔ SSH Agent: yes

Debugging

If you generated your CA without the SSH keys the output when attempting to generate a certificate will look like this:

$ step ssh certificate paul@whatsdoom id_ecdsa
✔ Provisioner: paul@whatsdoom.com (JWK) [kid: 7KFMEf7OPkG_QBk47O7epR-yWwl7k8H1scbSEhuGgeA]
✔ Please enter the password to decrypt the provisioner key:
✔ CA: https://ca.whatsdoom.com:8443
The requested method is not implemented by the certificate authority. Please see the certificate authority logs for more info.
Re-run with STEPDEBUG=1 for more info.

Other Commands

Pass additional usernames that the certificate allowed to use:

step ssh certificate --principal paul --principal ubuntu paul@whatsdoom id_ecdsa

Renewing the cert for an existing SSH key pair:

$ step ssh certificate --sign --principal admin --principal ubuntu paul@whatsdoom id_ecdsa.pub
✔ Provisioner: paul@whatsdoom.com (JWK) [kid: S3ayxHbapfYPGIxr7W1PM1BRbAYE5Is4FfE1Cle-9xU]
✔ Please enter the password to decrypt the provisioner key:
✔ CA: https://ca.whatsdoom.com:8443
✔ Certificate: id_ecdsa-cert.pub

Checking a signed key using the generated cert file:

$ ssh-keygen -L -f ~/.ssh/id_ecdsa-cert.pub
/Users/paul/.ssh/id_ecdsa-cert.pub:
        Type: ecdsa-sha2-nistp256-cert-v01@openssh.com user certificate
        Public key: ECDSA-CERT SHA256:MYLK470SnLvBqV6zsCS76oYkHj+x0QO96lcbtvvUmTk
        Signing CA: ECDSA SHA256:PRrktIoVIOwFb/V/ckl0FDSMULNP4dVEuGx1ks0417c
        Key ID: "paul@whatsdoom"
        Serial: 6336785949649563520
        Valid: from 2020-02-25T01:07:55 to 2020-02-25T17:08:55
        Principals:
                paul
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc