SSH keys are the best way of logging into Linux servers. But traditional keys have their limitations.
They never expire
Organizations commonly have workers that need access access to a system for a limited time, employees, move on etc. Managing this is possible by by removing keys as needed but SSH certificates have an expiry date built right into them.
You even can issue new daily certificates to everyone every morning making them worthless the following day.
Host authentication
The client and server both verify each others identity when a login is made if they both trust the CA.
Identity
SSH certificates have given an identity like an employees name. This is recorded in the auth log and is independent to the server use being logged in as. You can always tell who logged in.
Let’s create a simple SSH certificate.
CLIENT: Create An SSH Key Pair
On the client create an SSH key pair as usual:
ssh-keygen -t ed25519 -f .ssh/user-key
This will create an ed25519
keypair in your .ssh
directory. The keys will have the following names:
Private Key: .ssh/user-key
Public Key: .ssh/user-key.pub
DO NOT PUT THE PUBLIC KEY INTO THE SSH SERVER’S authorized_keys
FILE
If you put the client’s public key into the SSH server’s authorized_keys
file it will not use the CA certificate for authentication.
CA SERVER: Create A CA Certificate
Note, that the CA server can be the same machine as your SSH server or another trusted server.
First, move to /etc/ssh/
and create a new directory for the CA certificate:
cd /etc/ssh
mkdir CA
chmod 600 CA
Next, create the CA certificate:
ssh-keygen -C CA -f CA/ssh-ca
You can choose to set a password or not. This must be entered to sign the the client keys so consider if you intend to automate any of this.
This creates the public and private CA certificates.
Private cert: /etc/ssh/CA/ssh-ca
Public cert: /etc/ssh/CA/ssh-ca.pub
CA Server: Sign the Client public key
Create a new directory for your client keys:
mkdir /etc/ssh/client-keys
Then put a copy of the client public key into it.
The following command will sign the key:
ssh-keygen -s /etc/ssh/CA/ssh-ca -I "James Smith" -n root -V +1w -z 1 /etc/ssh/client-keys/user-key.pub
The options here meas as follows:
-s /etc/ssh/CA/ssh-ca
- The path to the SSH CA private certificate.-I "James Smith"
- The identity associated with the key. Put anything you want.-n root
- A comma separated list of users that this key can log in as. Note, Omit this option to allow for any user.-V +1w
- How long the key is valid for. Time options here arem
,h
,d
,w
,y
and can be added together e.g.-V +1m7d
for one month and 7 days.-z 1
- A serial number. Allows keys to be uniquely identified.
This creates a new signed public key file:
/etc/ssh/client-keys/user-key-cert.pub
Check the details of the key with ssh-keygen -Lf <SIGNED PUBLIC KEY>
:
ssh-keygen -Lf /etc/ssh/client-keys/user-key-cert.pub
/etc/ssh/client-keys/user-key-cert.pub:
Type: ssh-ed25519-cert-v01@openssh.com user certificate
Public key: ED25519-CERT SHA256:lJZ7It7jFLm19yQBZhatw79To029boLvt8p0Du+ea/Y
Signing CA: RSA SHA256:dVk/zfFsADyXv2oti8EF48XFjVJrYai2+54yp3A3Z0g
Key ID: "James Smith"
Serial: 1
Valid: from 2021-09-03T08:31:00 to 2021-09-10T08:32:41
Principals:
root
Critical Options: (none)
Extensions:
permit-X11-forwarding
permit-agent-forwarding
permit-port-forwarding
permit-pty
permit-user-rc
Finally, place a copy of the signed public SSH key, user-key-cert.pub
, in the clients .ssh
directory on their laptop.
SSH Server: Copy and configure the CA public key
Place a copy of the the CA public key you just created into /etc/ssh
.
Next, configure SSH to use the CA public key you just created:
nano /etc/ssh/sshd_config
And add the following line with a path to the CA public key:
TrustedUserCAKeys /etc/ssh/ssh-ca.pub
Check that your edit is valid:
sshd -t
And if it is restart SSH:
systemctl restart sshd.service
Check it works
Log back into the server from the client’s laptop using the user-key
private key. You can specify which key to use using the -i
option:
ssh -i .ssh/user-key root@<SERVER>
Open the auth file on the server (on Ubuntu/Debian /var/log/auth.log
) and look for the entry for the new login:
Sep 4 04:48:59 SSH sshd[1137]: Accepted publickey for root from 1.2.3.4 port 51960 ssh2: ED25519-CERT SHA256:lJZ7It7jFLm19yQBZhatw79To029boLvt8p0Du+ea/Y ID James Smith (serial 1) CA RSA SHA256:ZI4osqO3dKCECeLcQblRPaayxTeSueVrsCq/hpltrkM
You can see that CA RSA SHA256:Z....
was used along with ID James Smith
and the serial (serial 1)
. This confirms that the CA was used to verify the key.