This document assumes you have initialized and started up a
step-ca instance using the steps in Getting Started.
Let's perform some basic operations on X.509 certificates:
Once you have a certificate authority up and running, the
step ca command makes generating keys and obtaining a certificate simple. You need just one command:
$ step ca certificate svc.example.com svc.crt svc.key ✔ Provisioner: email@example.com (JWK) [kid: JxCvTLC67zKCOi-yyMoHpO5vAj_MnXs80PR0nh7IjUg] ✔ Please enter the password to decrypt the provisioner key: ✔ CA: https://127.0.0.1:4337 ✔ Certificate: svc.crt ✔ Private Key: svc.key
The positional arguments in the
step ca certificate command indicate the name you would like associated with the certificate (in this case, the DNS host name of a service) and the output filenames for the certificate and private key.
You can check your work using
step certificate inspect:
$ step certificate inspect svc.crt --short X.509v3 TLS Certificate (ECDSA P-256) [Serial: 7720...1576] Subject: svc.example.com Issuer: Smallstep Intermediate CA Provisioner: firstname.lastname@example.org [ID: JxCv...IjUg] Valid from: 2020-09-22T00:59:37Z to: 2020-09-23T01:00:37Z
Let's make a CSR for this example, using
step certificate create --csr, then we'll use
step ca sign to get a signed certificate from the CA.
$ step certificate create --csr foo.example.com foo.csr foo.key Please enter the password to encrypt the private key: $ step ca sign foo.csr foo.crt ✔ Provisioner: email@example.com (JWK) [kid: yWa7WGfoSt9yJ0OZCndrvR_m65jzDriY7mhPz094fdw] ✔ Please enter the password to decrypt the provisioner key: ... ✔ CA: https://127.0.0.1:4337 ✔ Certificate: foo.crt
Certificate renewal is easy, and is authenticated using the existing private key:
$ step ca renew foo.crt foo.key ✔ Would you like to overwrite foo.crt [y/n]: y Your certificate has been saved in foo.crt.
When it comes time to renew your certificate, do not dawdle: Once a certificate expires, the CA will not renew it. If you use the
step renewal daemon to automate renewals, it will attempt renewal at around 2/3 of a certificate's lifetime.
There is no way to "un-issue" a certificate. Once a certificate has been signed and distributed by the CA, it's valid until it expires.
However, you can ask the CA to block the renewal of a certificate. This is called passive revocation.
Let's revoke the
svc.crt certificate we created earlier.
$ step ca revoke --cert svc.crt --key svc.key ✔ CA: https://localhost:4337 Certificate with Serial Number 30671613121311574910895916201205874495 has been revoked.
For more on this topic, read All About Certificate Revocation.
In this section we'll go over the basics of issuing and renewing SSH certificates for users and hosts.
step-caCertificate Authority with SSH support enabled. Create one by running
step ca init --ssh.
When the CA is initialized with
--ssh, it creates two SSH CA key pairs: one for the host CA, and one for the user CA. The user CA key signs SSH user certificates, and the host CA key signs SSH host certificates.
In this section, we will delegate SSH authentication on both ends of the SSH connection:
First let's delegate user authentication to the SSH CA.
On your host, once you've bootstrapped your CA configuration, run:
$ step ssh config --roots > /path/to/ssh_user_key.pub
Add this to key your SSHD configuration. On your host, run:
$ cat <<EOF >> /etc/ssh/sshd_config # This is the CA's public key for authenticating user certificates: TrustedUserCAKeys /path/to/ssh_user_key.pub EOF
Restart SSHD. Your host will now trust any user certificate issued by the CA.
Let's create an SSH user certificate for the user
$ step ssh certificate firstname.lastname@example.org id_ecdsa ✔ Provisioner: email@example.com (JWK) [kid: yWa7WGfoSt9yJ0OZCndrvR_m65jzDriY7mhPz094fdw] ✔ Please enter the password to decrypt the provisioner key: ✔ CA: https://127.0.0.1:4337 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
The CA issued a private key, a public key, and an SSH certificate, and it added the certificate and private key to our local SSH agent. We only need the private key and certificate to use SSH certificate authentication. Let's inspect the certificate:
$ cat id_ecdsa-cert.pub | tail -1 | step ssh inspect -: Type: firstname.lastname@example.org user certificate Public key: ECDSA-CERT SHA256:EPVTWfml136JG5FNR5xkFz7PRhUvuMUWzRXyQ+2zJfE Signing CA: ECDSA SHA256:yrTW8Ej/0kzGebLRvXIVFclXfA1dF/9VRiGjRnRcXl4 Key ID: "email@example.com" Serial: 7887351871112993341 Valid: from 2020-09-22T11:27:56 to 2020-09-23T03:28:56 Principals: alice Critical Options: (none) Extensions: permit-pty permit-user-rc permit-X11-forwarding permit-agent-forwarding permit-port-forwarding
By default, when using SSH certificates, SSHD will allow you to connect as any of the listed principals. If the list of principals is empty, SSHD will allow you to authenticate as anyone on the host.
Hosts can have SSH certificates, too, instead of the typical host public key pair. Host certificates allow clients who trust the host CA to avoid "Trust this host's fingerprint?" prompts that normally arise when using conventional host keys for the first time.
On your host, run:
$ step ssh certificate --host internal.example.com ssh_host_ecdsa_key ✔ Provisioner: firstname.lastname@example.org (JWK) [kid: yWa7WGfoSt9yJ0OZCndrvR_m65jzDriY7mhPz094fdw] ✔ Please enter the password to decrypt the provisioner key: ✔ CA: https://127.0.0.1:4337 Please enter the password to encrypt the private key: ✔ Private Key: ssh_host_ecdsa_key ✔ Public Key: ssh_host_ecdsa_key.pub ✔ Certificate: ssh_host_ecdsa_key-cert.pub
Let's see what you created:
$ cat ssh_host_ecdsa_key-cert.pub | step ssh inspect -: Type: email@example.com host certificate Public key: ECDSA-CERT SHA256:Dc+Mzy43RzKoIaLrI8GzeHcQLbIa3hQ3mhirIDjbu0s Signing CA: ECDSA SHA256:IG7xVPz9kC6PwUTDDRvn+HIy1xUf/zllPo0InlSfaTg Key ID: "internal.example.com" Serial: 14283430004353679661 Valid: from 2020-09-22T11:34:40 to 2020-10-22T11:35:40 Principals: internal.example.com Critical Options: (none) Extensions: (none)
If you want your host to use this key, move the files to
/etc/ssh and add the following to your SSHD configuration. On your host:
$ mv ssh_host_ecdsa_key ssh_host_ecdsa_key-cert.pub /etc/ssh $ cat <<EOF >> /etc/ssh/sshd_config # This is our host private key and certificate: HostKey /etc/ssh/ssh_host_ecdsa_key HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub EOF
Because the host certificate expires in a month, you'll also need to set up automated renewal of the certificate. Let's add a weekly renewal
cron script that runs
step ssh renew, on your host:
$ cat <<EOF > /etc/cron.weekly/rotate-ssh-certificate #!/bin/sh export STEPPATH=/root/.step cd /etc/ssh && step ssh renew ssh_host_ecdsa_key-cert.pub ssh_host_ecdsa_key --force 2> /dev/null exit 0 EOF chmod 755 /etc/cron.weekly/rotate-ssh-certificate
To get your SSH clients to trust host certificates issued by your CA, you'll need to add the host CA key to SSH's
To view the host key, run:
$ step ssh config --host --roots ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFM2fTh3Utg3eGMqy2mJqa48Qsr7onZfOtIpJRNvvd71+eBUHBQdhnGmo2NPksNV3GxEuUZKAjZMlNv5c13XvfY=
Add this to the
known_hosts file on your SSH client, prepending
@cert-authority * to it to mark it as a Certificate Authority, eg:
@cert-authority * ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFM2fTh3Utg3eGMqy2mJqa48Qsr7onZfOtIpJRNvvd71+eBUHBQdhnGmo2NPksNV3GxEuUZKAjZMlNv5c13XvfY=
Your SSH client will now trust any host with a valid certificate signed by the CA.
You're all done. Now test your SSH connection.
step-cain different contexts and workflows.
step ca helpor
step ssh helpfor many more flags and examples.