+++
title = "ssh certificates part 1"
date = "2015-07-19T10:33:11+00:00"
author = "Gibheer"
draft = false
+++

All of my infrastructure SSH access is handled with SSH certificates for more than a year now. As I am asked
every now and then how it works, I will describe how it works in multiple blog posts.

This part will revolve around Client certificates.

What is it good for?
--------------------

With general public key usage one can identify a user by his public key. These get
put into an `~/authorized_keys` file and if a user presents the correct key, they
are let onto the system.
This approach works well, but it is a bit tricky to find out, which key was actually
used. Restricting the user based on his key on any machine also requires to manage
the authorized_keys with options.

Now SSH certificates on the client side grant the possibility to sign a public key
and remove the requirement for an authorized keys file.
The options can be set directly in the certificate and are active on every server
this certificate is used with. As the certificate can also hold an identification
string it is easier to see from the logs, which key for what purpose connected.
The only thing to make this work is to set every server to trust the signee and
no authorized keys file has to be managed anymore.

generating the CA
-----------------

First we need a SSH key for the purpose of a CA. This should not be the same key
as your normal key in a production environment.
The key is generated any other key with ssh-keygen

    ssh-keygen -t ed25519 -C CA -f ca.key

You can choose any key type you want, it works with all types and any type can
 sign any type.
The `-C` flag adds a comment to the key.

Now we can sign a public key.

signing a user key
------------------

First we sign a user public key `foouser.pub`.

    ssh-keygen \
      -s ca.key \
      -I 'foouser' \
      -n foouser \
      foouser.pub

Now what do all these options mean?

* `-s` defines the signing key
* `-I` is an identification for the certificate. This also shows up in the
  auth.log on the server.
* `-n` the principal, which in this case means the username this key will be
  allowed to login with.

To restrict the IP address for the public key, one can use the following line

    -O source-address="127.0.0.1,192.168.42.1"

Any option from `ssh-keygen(1)` requires its own -O options, for example:

    -O clear -O no-pty -O force-command="/opt/foo/bin/do_stufff"

A good source for further options is the ssh-keygen man page.

After the command was executed, a file foouser-cert.pub shows up. The content
can be inspected using ssh-keygen again:

    ssh-keygen -L -f foouser-cert.pub

To get the authentication working with this key, two steps have to be taken.
First is to put the generated certificated in the same directory like the private
key, so that the ssh agent will sent the certificate.
Second is to put the CA onto the server, so that it will trust all created
certificates.

This is done with the following option in the sshd_config

    TrustedUserCAKeys /etc/ssh/ssh_user_certs

where the content of the file _/etc/ssh/ssh_user_certs_ is the ca public key.
It is possible to put multiple CAs into that file.

Now one can connect to the server using the newly created key

    ssh -vvv -I foouser <yourserver>

Which should print a line like

    debug1: Server accepts key: pkalg ssh-ed25519-cert-v01@openssh.com blen 364
    debug1: Offering ED25519-CERT public key: /home/foouser/.ssh/id_ed25519
    debug3: sign_and_send_pubkey: ED25519-CERT SHA256:YYv18lDTPtT2g5vLylVQZiXQvknQNskCv1aCNaSZbmg

These three lines state for my session, that the server accepts certificates and
that my certificate was sent.

With this, the first step to using SSH certificates is done. In the next post
I will show how to use SSH certificates for the server side.
