Managing an SSH server is easy when you only have one or two servers, but what happens when you have thousands of servers? “Authorized keys” and “known hosts” files are hard to manage across large teams with permissions and roles.
Can you tell me the difference between these two images?
Nothing. With the default setup we have to have every host “trust” the certificate.
SSH is a powerful protocol, and it can manage a chain of trust where key A can be signed by key B, and if we trust B, we can then verify and trust key A.
So we can create an SSH Certificate authority and sign SSH Host certificates and User keys. Let’s create one:
$ ssh-keygen -t ed25519 -C "Certificate Key" -f /path/to/ca # Create the CA key
$ ssh-keygen -t ed25519 -C "hostname" -f /path/to/host # Create the Host key
$ ssh-keygen -t ed25519 -C "user@hostname" -f /path/to/user # Create user key
# Now we can sign the pubkey
$ ssh-keygen -s /path/to/ca -I KEYID -n PRINCIPALS -V +1d -z 1 /path/to/user.pub
# We can also sign an host key
$ ssh-keygen -s /path/to/ca -I KEYID -h -V 1d -z 1 /path/to/host.pub
Parameters:
With this, we can point to the CA key in our known hosts file.
@cert-authority *.domain.tld ssh-ed25519.......
And, of course, we can set up the CA on the server in the sshd_config file:
TrustedUserCAKeys /path/to/ca.pub
HostCertificate /path/to/host.pub
Principals are arbitrary strings that can be used on the server to allow access. In a real environment, this could be an LDAP group, team name, or other identifier. Let’s see how we can use that:
We can bring our /path/to/ca.pub into servers and open /etc/ssh/sshd_config:
AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u # %u is the user that ask to login
%u is the user, for example %u = root when you type ssh root@server.tld. AuthorizedPrincipalsFile accept %h, %U, and %u, which are respectively:
SSH also implements AuthorizedPrincipalsCommand. It’s a script that runs on every login, and it has to print out the principals authorized for that host. With this, you can dynamically accept principals, based for example on LDAP, on DB, or something else. See the TOKENS man section for keywords available withAuthorizedPrincipalsCommand.
Okay, so if someone steals my key? SSH implements a revocation list with a RevokedKeys file. You can put your public key here, and a login attempt with that SSH key will not no longer work.
So, we’ve seen how to configure a CA for SSH, host certificate, and user keys. But how can we manage signing and the revocation of the key if we have thousands of people? Stay tuned for the second part…
Did you find this article interesting? Are you an “under the hood” kind of person? We’re really big on automation and we’re always looking for people in a similar vein to fill roles like this one as well as other roles here at Würth Phoenix.