OpenSSH 8.2 is coming to the latest Long-Term Service release of Ubuntu, Focal Fossa (20.04), and has some breaking changes for users using an SSH Certificate Authority.
With OpenSSH 8.1 or older, the default certificate type when signing with ssh-keygen
is ssh-rsa
, although ECDSA- and SHA2-based algorithms have been supported since OpenSSH 5.7. As cited in the release notes,
It is now possible[1] to perform chosen-prefix attacks against the SHA-1 hash algorithm for less than USD$50K.
[1] SHA-1 is a Shambles: First Chosen-Prefix Collision on SHA-1 and Application to the PGP Web of Trust
Leurent, G and Peyrin, T (2020) https://eprint.iacr.org/2020/014.pdf
So the SHA-1 based RSA certificate algorithm is no longer considered secure. As a result,
- ssh(1), sshd(8), ssh-keygen(1): this release removes the
ssh-rsa
(RSA/SHA1) algorithm from those accepted for certificate signatures (i.e. the client and serverCASignatureAlgorithms
option) and will use thersa-sha2-512
signature algorithm by default when the ssh-keygen(1) CA signs new certificates.
The immediate effect is, when you attempt to log in to a host that presents an RSA/SHA1 certificate, instead of logging in successfully, SSH will complain with the following message:
check_host_cert: certificate signature algorithm ssh-rsa: signature algorithm not supported
and of course, you’re again asked to trust the host key even if you’ve already trusted the @cert-authority
.
This can be particularly annoying in larger organizations where the deployment of RSA/SHA1 certificates has spanned everywhere, and OpenSSH 8.2 essentially just broke them all.
Rest assured, there’s a way to make everything go back to normal once more. But as suggested by OpenSSH, you should not rely on this and should instead move away from ssh-rsa
certificates soon.
Bring back the compatibility
As described above, the value ssh-rsa
has been dropped from the default list of the CASignatureAlgorithms
, though as of April 8, the man page for ssh_config(5)
contains a small mistake, which claims the default value of CASignatureAlgorithms
is as follows:
CASignatureAlgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
The actual value, of course, is the same as the above list with ssh-rsa
stripped off, and all you need to do is to add it back.
If you just want to fix this for yourself, you can add the following lines to your ~/.ssh/config
file:
Host *
CASignatureAlgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
If you want to fix this for all users on a system, you can add the same lines to /etc/ssh/ssh_config
instead, which will affect all ssh
commands run on that system. Remember this is still not recommended in favor of upgrating the signature algorithm.
Sign new certificates
Good news
You don’t have to generate a new CA and deploy it everywhere. You can still use your RSA private key to generate new certificates for your machines, though it does require a little research first.
Let’s start by looking at the man page for ssh-keygen(1).
ssh-keygen -s ca_key -I certificate_identity [-h] [-U] [-D pkcs11_provider] [-n principals] [-O option] [-V validity_interval] [-z serial_number] file ...
It doesn’t look like there’s a way to control the certificate algorithm. But hold on, have you tried the -t
option that appears in many other subcommands…?
ssh-keygen -s ~/.ssh/ca -I Example -t rsa-sha2-256 id_rsa.pub
# ^^^^^^^^^^^^^^^
This will generate a new certificate at id_rsa-cert.pub
. You might want to examine it at once, and you might probably be disappointed to see that it still begins with [email protected]
.
That simply doesn’t matter. To examine a certificate, you should use the ssh-keygen -L
command:
ssh-keygen -Lf id_rsa-cert.pub
… and check its output:
id_rsa-cert.pub:
Type: [email protected] user certificate
Public key: RSA-CERT SHA256:yP2N3uawwSuoJdww2miEYrsGuBictGYJ6VmkdhvtYcg
Signing CA: RSA SHA256:yP2N3uawwSuoJdww2miEYrsGuBictGYJ6VmkdhvtYcg (using rsa-sha2-256)
Key ID: "Example"
Serial: 0
Valid: forever
Principals: (none)
Critical Options: (none)
Extensions:
permit-X11-forwarding
permit-agent-forwarding
permit-port-forwarding
permit-pty
permit-user-rc
Notice how the fourth line reads using rsa-sha2-256
? It’s now signed with a different algorithm that’s not considered deprecated anymore, which means it’s ready to deploy.
Tip
OpenSSH 8.2 defaults to using the rsa-sha2-256
algorithm when signing new certificates with an RSA private key, so the -t
option is only necessary if you’re using OpenSSH 8.1 or older.
You can try running ssh-keygen -L
on one of your old certificates to see how SSH describes it. This is left as a small quiz for you to figure out for yourself.
Leave a comment