If you’re not using SSH certificates you’re doing SSH wrong | Episode 3: An ideal SSH flow
Tags: devops, security, opensource, sre
Published: 2020-08-21 19:18:44

In our previous two episodes, we covered the [benefits of SSH certificates](https://dev.to/smallstep/if-you-re-not-using-ssh-certificates-you-re-doing-ssh-wrong-episode-1-keys-versus-certificates-5a0n) and how they can [help developers, operators, and security teams](https://dev.to/smallstep/if-you-re-not-using-ssh-certificates-you-re-doing-ssh-wrong-episode-2-certificates-improve-usability-operability-security-45hg) better manage privileged access. Today we will look at an ideal SSH flow using certificates and your existing identity provider for single sign-on access. 

### An ideal SSH flow

SSH certificate authentication is the foundation of what I think is the ideal SSH flow.

To SSH, users first run a login command in their terminal (e.g., `step ssh login`):

    $ step ssh login
    Your default web browser has been opened for you to login: https://accounts.google.com/...

A browser is opened and an SSO flow is initiated at your organization's identity provider:

![User authenticates in browser via SSO](https://smallstep.com/uploads/1st%20Screenshot@2x.png)

A web-based SSO flow makes it easy to leverage strong MFA (e.g., FIDO U2F) and any other advanced authentication capabilities your identity provider offers. Users login with a familiar flow, and removing a user from your canonical identity provider ensures prompt termination of SSH access.

Once the user completes SSO, a bearer token (e.g., an OIDC identity token) is returned to the login utility. The utility generates a new key pair and requests a signed certificate from the CA, using the bearer token to authenticate and authorize the certificate request.

The CA returns a certificate with an expiry long enough for a work day (e.g., 16-20 hours). The login utility automatically adds the signed certificate and corresponding private key to the user's `ssh-agent`.

Users needn't be aware of any of this detail. All they need to know is that, in order to use SSH, they must first run `step ssh login`. Once that's done they can use SSH like normal:

    $ ssh prod01.example.com
    Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-1036-gcp x86_64)
    
    Last login: Wed Sep 11 04:04:51 2019 from 98.210.132.79
    mmalone@prod01:~$

Like browser cookies, short-lived certificates issued by this flow are ephemeral credentials, lasting just long enough for one work day. Like logging into a website, logging into SSH creates a session. It's a simple process that must be completed, at most, once per day. This is infrequent enough that strong MFA can be used without frustrating or desensitizing users.

New private keys and certificates are generated automatically every time the user logs in, and they never touch disk. Inserting directly into `ssh-agent` insulates users from sensitive credentials. If a user wants to connect from a different device it's easier for them to run `step ssh login` there than it is to exfiltrate keys from `ssh-agent` and reuse them.

There are lots of possible variations of this flow. You can adjust the certificate expiry, use PAM authentication at the CA instead of SSO, generate the private key on a smart card or TPM, opt not to use `ssh-agent`, or move MFA to the actual SSH connection. Personally, I think this combination offers the best balance of security and usability. Indeed, relative to most existing SSH deployments it's operationally simpler, more secure, and more usable.

Critics of SSH certificate authentication say that it's new, not well supported, and the tooling doesn't exist to use certificates in practice. The truth is, **certificate authentication was added in** [**OpenSSH 5.4**](https://www.openssh.com/txt/release-5.4) **almost a decade ago**. It's battle tested and used in production by massive operations. And the tooling required to build this ideal SSH flow is available today.

## Tools

There are lots of existing tools for managing SSH certificates. Here are a few:

* [`step-ca`](https://github.com/smallstep/certificates) is now an SSH CA (in addition to being an X.509 CA)
* [`step`](https://github.com/smallstep/cli) makes it easy for users and hosts to get certificates from `step-ca`
* `ssh-keygen` can generate root certificates and sign user & host certificates
* [`netflix/bless`](https://github.com/netflix/bless) is Netflix's SSH CA that runs in AWS Lambda and uses IAM
* [`nsheridan/cashier`](https://github.com/nsheridan/cashier) is Intercom's SSH CA
* [`uber/pam-ussh`](https://github.com/uber/pam-ussh) lets you use certificates to authorize `sudo` use
* [`hashicorp/vault`](https://github.com/hashicorp/vault) has an [SSH secrets engine](https://www.vaultproject.io/docs/secrets/ssh/index.html)


With the appropriate configuration of `step-ca` you can use `step` to:

### Get a host certificate automatically at startup

To demonstrate, let's create a new EC2 instance with the `aws` CLI tool. The interesting bits are tucked in [some light configuration](https://github.com/smallstep/step-ssh-example/blob/master/host-bootstrap.sh) (using a [user-data startup script](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html)) that gets a host certificate and enables certificate authentication for users:

    $ aws ec2 run-instances --image-id ami-07d0cf3af28718ef8 \
        --count 1 --instance-type t2.micro \
        --key-name mike-test \
        --security-group-ids launch-wizard-7 \
        --user-data file://startup.sh

Note: you should be able to use our [instance identity document support](https://smallstep.com/blog/embarrassingly-easy-certificates-on-aws-azure-gcp/) here, but we've got a few kinks to work out. Stay tuned.

### Get a user certificate using SSO (OAuth OIDC)

Now we'll use `step ssh certificate` locally (you can `brew install step`) to generate a new key pair, get a certificate from the CA [using SSO](https://smallstep.com/blog/easily-curl-services-secured-by-https-tls/#personal-certificates-via-oauth-openid-connect), and automatically add the certificate and private key to `ssh-agent`.

That sounds like a lot, but it's just one command:

    $ step ssh certificate mike@smallstep.com id_ecdsa
    ✔ Provisioner: Google (OIDC)
    Your default web browser has been opened to visit:
    
    https://accounts.google.com/o/oauth2/v2/auth?client_id=650...
    
    ✔ CA: https://ca.internal
    ✔ Private Key: id_ecdsa
    ✔ Public Key: id_ecdsa.pub
    ✔ Certificate: id_ecdsa-cert.pub
    ✔ SSH Agent: yes

Once that's done we can SSH to the instance we just created, using certificate authentication, with no TOFU!

    $ ssh mike@ec2-100-26-100-55.compute-1.amazonaws.com
    Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-1044-aws x86_64)
    
    Last login: Thu Sep 12 02:25:43 2019 from 98.210.132.79
    mike@ip-172-31-70-94:~$

For more info check out our [getting started guide](https://smallstep.com/docs/getting-started/) and [SSH example repo](https://github.com/smallstep/step-ssh-example). Make sure you pass the `--ssh` flag to `step ca init` when you're setting up the CA (the getting started guide doesn't do this).

There's a lot more that can be done to make SSH certificate authentication even more awesome. We're working on that. If you have any ideas, [let us know](https://gitter.im/smallstep/community)!


### Use SSH certificates

SSH certificate authentication does a lot to improve SSH. It eliminates spurious TOFU warnings and host key verification failures. It lets you drop complex key approval & distribution processes and extend SSO to SSH. It makes rekeying possible for hosts and easier than key reuse for users. It makes SSH keys ephemeral, making key management oversights fail-secure.

You can deploy an SSH CA and reconfigure hosts in a matter of minutes. It's easy to transition — you can continue supporting public key authentication at the same time.

SSH certificate authentication is the right way to do SSH.

To learn more about SSH certificates visit [the Smallstep website](https://smallstep.com/sso-ssh?utm_campaign=Dev.to&utm_source=dev.to). You can even try our free hosted offering and experience the value of SSH certificates in under five minutes!