SSH Certificates

All the Trust, None of the Fuss

Bri Hatch Personal Work
bri@ifokr.org Dropzone.AI

https://www.ifokr.org/bri/presentations/seagl-2025-ssh-certificates/

Copyright 2025, Bri Hatch, Creative Commons BY-NC-SA License

SSH Authentication Options

Username / Password

Classic username/password authentication

laptop$ ssh wbagg@remote
wbagg@remote's password: 🔒 (types password)

Password Auth... ungh

Password Incorrect

Drawbacks

SSH Keys / Identities

Generate local key pair:

laptop$ ssh-keygen -t ed25519 -C "wbagg@example.edu"
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase): 🔒 (types passphrase)
Enter same passphrase again: 🔒 (types passphrase)

Your identification has been saved in ~/.ssh/id_ed25519
Your public key has been saved in ~/.ssh/id_ed25519.pub
...

laptop$ ls ~/.ssh/
id_ed25519
id_ed25519.pub

My pubkey is my passport

Add the public key to the host

laptop$ ssh-copy-id -i ~/.ssh/id_ed25519.pub remote
wbagg@remote's password: 🔒 (types password)

laptop$ ssh wbagg@remote  # Look ma, no password prompt!

remote$ cat ~/.ssh/authorized_keys
ssh-ed25519 Tm8gc2VjcmV0IG1lc3NhZ2UgaGVyZSEhISEhISEK wbagg@example.edu

SSH Key Features

Why keys?


no-port-forwarding,no-user-rc ssh-ed25519 Tm8gc2Vjcm... wbagg@example.edu

SSH Key Anti-Features

Then why not keys?

ssh-ed25519 Tm8gc2VjcmV0IG1lc3NhZ2UgaGVyZSEhISEhISEK wbagg@example.edu
ssh-ed25519 TWF5YmV0aGlzaXNtYWxpY2lvdXM/Pz8/Pz8/

SSH Certificate

What is an SSH certificate?

Making a CA

I can haz authority?

ca-server$ sudo ssh-keygen -t ed25519 \
           -f /etc/ssh-ca/wtf-user-ca \
           -C "Widgets Trade Factory CA"

...
Your identification has been saved in /etc/ssh-ca/wtf-user-ca
Your public key has been saved in /etc/ssh-ca/wtf-user-ca.pub

The key fingerprint is:
SHA256:e4kM7f/6ovfio4S6jM/APdnA5tBAQcO5M Widgets Trade Factory CA

Making a CA (cont)

ca-server$ ls -l /etc/ssh-ca; cat /etc/ssh-ca/wtf-user-ca.pub
total 8
-rw------- 1 root root 419 Nov  5 23:44 wtf-user-ca
-rw-r--r-- 1 root root 106 Nov  5 23:44 wtf-user-ca.pub

ssh-ed25519 VGhpc2lzbid0Zm9vbGluZ2FueW9uZS4u Widgets Trade Factory CA

Enabling user CA trust

Allow cert-based authentication

     TrustedUserCAKeys /etc/ssh-ca/wtf-user-ca.pub

    $ sudo service sshd reload

Generating a User Certificate

The CA signs a user's pubkey

ca-server$ ls
wbagg-id_ed25519.pub

ca-server$ ssh-keygen -s /etc/ssh-ca/wtf-user-ca \
           -I "keyid" \
           -n wbagg \
           -V +1m \
           ./wbagg-id_ed25519.pub

ca-server$ ls
wbagg-id_ed25519.pub
wbagg-id_ed25519-cert.pub

Generating a User Certificate (cont)

ca-server$ ssh-keygen -L -f wbagg-id_ed25519-cert.pub
wbagg-id_ed25519-cert.pub:
    Type: ssh-ed25519-cert-v01@openssh.com user certificate
    Public key: ED25519-CERT SHA256:oWK0HYhl+MAY5bFhGe28bG1cqasObgdfFBI3cb2BjW8
    Signing CA: ED25519 SHA256:e4kM7f/6ovfio4S6jMniJfpkfwzy/APdnA5tBAQcO5M (using ssh-ed25519)
    Key ID: "keyid"
    Serial: 0
    Valid: from 2025-04-19T11:43:00 to 2025-04-19T11:44:00 
    Principals:
            wbagg
    Critical Options: (none)
    Extensions:
            permit-X11-forwarding
            permit-agent-forwarding
            permit-port-forwarding
            permit-pty
            permit-user-rc

Signed, Sealed, Delivered

Using the Certificate

Wendell gets the cert back and puts it aside his normal key

laptop$ ls ~/.ssh/
./id_ed25519
./id_ed25519.pub
./id_ed25519-cert.pub

laptop$ ssh wbagg@remote echo 'I am $(whoami) on $(hostname)'
I am wbagg on remote

laptop$ ssh alice@remote echo 'I am $(whoami) on $(hostname)'
alice@remote's password: 🔒

laptop$ sleep +1m
laptop$ ssh wbagg@remote echo 'I am $(whoami) on $(hostname)'
wbagg@remote's password: 🔒

Logs

What the server said:

sshd[271828] Accepted publickey for wbagg from ::1 port 56992 
     ssh2: ED25519-CERT SHA256:...  ID keyid (serial 0) CA
     ED25519 SHA256:...

...

sshd[314159]: error: Certificate invalid: name is not a
     listed principal

...

sshd[628318] error: Certificate invalid: expired

SSH Certificate Restrictions

Certificate Restrictions

SSH Certificate Restrictions (cont)

ca-server$ ssh-keygen -s /etc/ssh-ca/wtf-user-ca \
           -I "keyid" \
           -n wbagg \
           -V +1m \
           -O force-command=/usr/games/fortune
           ./wbagg-id_ed25519.pub

And then...

laptop$ ssh wbagg@remote
Do what comes naturally. Seethe and fume and throw a
tantrum.

laptop$ ssh wbagg@remote echo Hello World
You never know how many friends you have until you
rent a house on the beach.

Lock it down

Tighten Authentication

While you're here, consider disabling unneeded authentication methods in /etc/ssh/sshd_config and restarting sshd

   ...
   PasswordAuthentication no
   AuthenticationMethods publickey

Wanna set of steak knives?

But wait

Who's hungry?

$ ssh server.example.edu
The authenticity of host 'server.example.edu' can't be established.
ED25519 key fingerprint is SHA256:HanveypyIgIHS08W0KgFX+7w3IdHZg.
Are you sure you want to connect (yes/no)? yes

Who's hungry for TOFU?

$ ssh server.example.edu
The authenticity of host 'server.example.edu' can't be established.
ED25519 key fingerprint is SHA256:HanveypyIgIHS08W0KgFX+7w3IdHZg.
Are you sure you want to connect (yes/no)? yes

TOFU

SSH Host Key Certificates

Host keys can also have certificates!


ca-server$ ssh-keygen -s wtf-host-ca \
  -I server.example.edu \
  -n server.example.edu \
  -h -V +52w   ssh_host_rsa_key.pub

     HostCertificate /etc/ssh-ca/ssh_host_rsa_key-cert.pub

Client Side Trust

Trust the Host CA

Add the host CA entry to your ~/.ssh/known_hosts


laptop$ grep cert-authority ~/.ssh/known_hosts
@cert-authority *.example.edu ssh-rsa AAAABdnA5tBAQcO... wtf-host-ca

Never see this again!

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

Tools For Managing Certificates

Isn't this a lot of work?

There are tools you can use to streamline this

No, there is too much. Let me sum up

Summary

TOFU PITA

TOFU PITA

Thanks!

Presentation: https://www.ifokr.org/bri/presentations/seagl-2025-ssh-certificates/

PersonalWork
Bri Hatch
bri@ifokr.org
Dropzone.AI
www.dropzone.ai

Copyright 2025, Bri Hatch, Creative Commons BY-NC-SA License