+++ title = "ssh certificates part 2" date = "2015-07-28T21:20:49+00:00" author = "Gibheer" draft = false +++ This is the second part of the SSH certificate series, server side SSH certificates. You can find the first one [here](/118). This post shows, what use server side certificates can be and how they can be created. What use have server side certificates? --------------------------------------- SSH certificates on the host side are used to extend the ssh host keys. These can be used to better identify a running system, as multiple names can be provided in the certificate. This avoids the message of a wrong host key in a shared IP system, as all IPs and names can be provided. SSH certificates can also help to identify freshly deployed systems in that the system gets certified directly after the deployment by a _build ca_. signing a host key ------------------ For this step, we need a CA key. How that can be generated was mentioned in the [first part](/118). We also need the host public key to sign. This can be either copied from /etc/ssh/ from the server or it can be fetch using _ssh-keyscan_. ssh-keyscan foo.example.org It can also take a parameter for a specific type ssh-keyscan -t ed25519 foo.example.org This is needed for some older versions of openssh, where ed25519 public keys were not fetched by default with _ssh-keyscan_. The output returned looks like the following: zero-knowledge.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPIP0JSsdP2pjtcYNcmqyPg6nLbMOjDbRf0YR/M2pu2N The second and third field need to be put into a file, so that it can be used to generate the certificate. A complete command would then look like this: ssh-keyscan foo.example.org | awk '/ssh|ecdsa/ { print $2,$3 }' > host.pub With the resulting file, we can now proceed to create the certificate. ssh-keygen \ -s ca.key \ -V '+52w1d' \ -I 'foohost' \ -h \ -n foo.example.org,bar.example.org \ host.pub The meaning of the options is: * `-s` the key to use for signing (the ca) * `-V` interval the certificate is valid * `-I` the identity of the certificate (a name for the certificate) * `-h` flag to create a host certificate * `-n` all names the host is allowed to use (This list can also contain IPs) The last option is the public key file to certify. This results in a file host-cert.pub, which contains the certificate. It can be viewed like the SSH client certificate, with _ssh-keygen_. ssh-keygen -L -f host-cert.pub This file now has to be placed in the same directory like the public key on that host, with the same `-cert.pub` ending. The last step on the server is to adjust the _sshd_config_, so that it includes the certificate. For that, add the following line for the fitting host key, for example: HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub With a reload, it should load the certificate and make it available for authentication. Now the only thing left to do is to tell the client, that it should trust the CA to identify systems. For that, the public key of the CA has to be added to the file `~/.ssh/known_hosts` in the following format @cert-authority * The _*_ marks a filter, so different CAs can be trusted depending on the domain. With this, you are able to connect to your server only using the certificate provided by the server. When connecting with debugging on, you should get output like the following: $ ssh -v foo.example.com ... debug1: Server host key: ssh-ed25519-cert-v01@openssh.com SHA256:+JfUty0G4i3zkWdPiFzbHZS/64S7C+NbOpPAKJwjyUs debug1: Host 'foo.example.com' is known and matches the ED25519-CERT host certificate. debug1: Found CA key in /home/foo/.ssh/known_hosts:1 ... With the first part and now the second part done, you can already lock up your infrastructure pretty fine. In the next part, I will show some stuff I use to keep my infrastructure easily managable.