108 lines
3.8 KiB
Markdown
108 lines
3.8 KiB
Markdown
|
+++
|
||
|
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.
|