Following on from our previous post about SSH Key-Based Authentication. This article will highlight the use and benefits of SSH certificates. Using SSH certificates is a great way to perform "just in time" based authentication. The benefit of this is certificates will only be valid for a certain length of time, thus, providing access to servers for only the duration the certificate is valid.
Lets start by creating a SSH key pair which will essentially be used as the Certificate Authority.
ssh-keygen -f ~/.ssh/ca_user_key
Copy the public key into an appropriate location.
cp ~/.ssh/ca_user_key.pub /etc/ssh/
Update the sshd_config to add the TrustedUserCAKeys option and restart the service.
vi /etc/ssh/sshd_config ... TrustedUserCAKeys /etc/ssh/ca_user_key.pub ... systemctl restart sshd
The server is now all set to allow authentication based on user certificates. However, we must now sign users public keys to allow them to authenticate. This can be done manually but an automated option would be more suitable for large environments. We will sign the public key only allowing it to be used for one hour. This time length is not necessarily recommended but has been used in this example to easily show how authentication is allowed/denied only for the length of time the certificate is valid.
ssh-keygen -s ~/.ssh/ca_user_key -I darren -n darren -V +1h -z 1 darren.pub
This will create an additional file containing -cert in the file name, in this example it is named darren-cert.pub. The new certification needs to be copied to the relevant location that the user public and private key pair are stored. This is typically in ~/ssh/.
[darren@ssh-client ~]$ ls -l ~/.ssh/ total 16 -rw-------. 1 darren darren 411 Oct 4 14:48 id_ed25519 -rw-rw-r--. 1 darren darren 1540 Oct 4 18:42 id_ed25519-cert.pub -rw-r--r--. 1 darren darren 99 Oct 4 14:48 id_ed25519.pub -rw-r--r--. 1 darren darren 176 Oct 4 14:52 known_hosts
The output below shows the details of the certificate and the validity period. The certificate only contains one principal which is their standard user account. User principals will be discussed in greater detail later.
[darren@ssh-client ~]$ ssh-keygen -L -f .ssh/id_ed25519-cert.pub .ssh/id_ed25519-cert.pub: Type: [email protected] user certificate Public key: ED25519-CERT SHA256:6vvK8kFujyIPJTVJELGk4/Ke3FrlZMkNCxp4LiWnX84 Signing CA: RSA SHA256:Ctr9fc86Y6URIyUac6OevNxH93iWiXDbqJUD9gSGRl0 (using ssh-rsa) Key ID: "darren" Serial: 1 Valid: from 2020-10-04T14:55:00 to 2020-10-04T15:56:07 Principals: darren Critical Options: (none) Extensions: permit-X11-forwarding permit-agent-forwarding permit-port-forwarding permit-pty permit-user-rc
When attempting to login the certificate will now be valid for 1 hour. The screenshot below shows the certificate is valid and authentication is successful. The name of the certificate can be seen which is an additional benefit of SSH certificates - along with not needing to distribute all users public keys, having the certificate name displayed can help identify exactly who is accessing certain accounts. While not useful connecting as a standard user it is beneficial should people be logging in to shared accounts or even the root user.
A little while later another attempt is made to login with the existing certificate. However, this time, as expected, authentication is denied as the certificate has expired.
As mentioned in the previous example. Only one principal was added to the certificate. This example will show how principals can be used to allow a user to access a range of servers based on the principal or function they provide. Lets pretend this is a database server. On this server there is a dba user account and we will use a principal named zone-databases to allow access to the dba user account. Any certificate which is created with the zone-databases principal will allow the relevant user access to the dba user.
Firstly add the AuthorizedPrincipalsFile to the sshd_config file and restart the service.
vi /etc/ssh/sshd_config ... AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u systemctl restart sshd
The auth_principals directory also needs to be created. Within here the dba user file will be created with the zone-databases principal present.
mkdir /etc/ssh/auth_principals/ echo "zone-databases" > /etc/ssh/auth_principals/dba
The certificate will now be created with the zone-databases principal added.
ssh-keygen -s ~/.ssh/ca_user_key -I darren -n darren,zone-databases -V +1h -z 1 darren.pub
Attempting to login as the dba user works as expected.
darren@ssh-client ~]$ ssh [email protected] Last login: Sun Oct 4 19:38:33 2020 [dba@ssh-server ~]$
As shown below the authentication attempt is successful and the name of the certificate is displayed. This is incredibly useful if anyone is accessing a shared account.