A while ago, I set up my server with SSH certificates (following a guide like this one), and today, I began to wonder: “When do these things expire?”
Host certificate (option 1)
Among the output of ssh -v
(my client is OpenSSH_9.3p1 Ubuntu-1ubuntu3
) is this line about the host certificate:
debug1: Server host certificate: ssh-ed25519-cert-v01@openssh.com [...] valid from 2023-04-07T19:58:00 to 2024-04-05T19:59:44
That tells us the server host certificate expiration date, where it says “valid … to 2024-04-05.” For our local host to continue trusting the server, without using ~/.ssh/known_hosts
and the trust-on-first-use (TOFU) model, we must re-sign the server key and install the new signature before that date.
User certificate
I eventually learned that ssh-keygen -L -f id_25519-cert.pub
will produce some lovely human-readable output, which includes a line:
Valid: from 2023-04-07T20:14:00 to 2023-05-12T20:15:56
Aha! I seem to have signed the user for an additional month-ish beyond the host key’s signature. I will be able to log into the server without my key listed in ~/.ssh/authorized_keys
(on the server) until 2023-05-12.
This looks like a clever protection mechanism left by my past self. As long as I log into my server at least once a month, I'll see an untrusted-host warning before my regular authentication system goes down. (If that happened, I would probably have to use a recovery image and/or the VPS web console to restore service.)
Host certificate (option 2)
There’s an ssh-keyscan
command, which offers a -c
option to print certificates instead of keys. It turns out that we can paste its output to get the certificate validity again. (Lines shown with $
or >
are input, after that prompt; the other lines, including #
, are output.)
$ ssh-keyscan -c demo.example.org
# demo.example.org:22 SSH-2.0-OpenSSH_8.9p1
# demo.example.org:22 SSH-2.0-OpenSSH_8.9p1
ssh-ed25519-cert-v01@openssh.com AAAA[.....]mcwo=
# demo.example.org:22 SSH-2.0-OpenSSH_8.9p1
The ssh-ed25519-cert
line is the one we need. We can pass it to ssh-keygen
with a filename of -
to read standard input, then use the shell’s “heredoc” mechanism to provide the standard input:
$ ssh-keygen -L -f - <<EOF
> ssh-ed25519-cert-v01@openssh.com AAAA[.....]mcwo=
> EOF
Now we have the same information as before, but from the host certificate. This includes the Valid: from 2023-04-07T19:58:00 to 2024-04-05T19:59:44
line again.
Tips for setting up certificates
Document what you did, and remember the passphrases for the CA keys! This is my second setup, and now I have scripts to do the commands with all of my previous choices. They’re merely one-line shell scripts with the ssh-keygen command. But they still effectively record everything like the server name list, identity, validity period, and so forth.
To sign keys for multiple users/servers, it may be convenient to add the CA key to an SSH agent. Start a separate one to keep things extra clean, then specify the signing key slightly differently:
$ ssh-agent $SHELL
$ ssh-add user-ca
$ ssh-keygen -Us user-ca.pub ...
(repeat to sign other keys)
$ exit
Note the addition of -U
(specifying the CA key is in an agent) and the use of the .pub
suffix (the public half of the key) in the signing process.
No comments:
Post a Comment