Skip to main content
RunBook Academy

LinuxXXVI · SSHCertificates

SSH certificates and bastions

Intermediate⏱ ~12 minssh-keygen

What you'll learn

  • Use SSH certificates for large fleets
  • Distinguish user certificates from host certificates
  • Configure and use a bastion host
  • Recognise when certificates or bastions are the right choice

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

For small fleets, SSH publickey authentication with authorized_keys is sufficient. For large fleets (hundreds of hosts, thousands of users), authorized_keys does not scale. SSH certificates and bastion hosts solve different parts of this problem.

SSH certificates

A certificate is a public key signed by a Certificate Authority (CA). The CA can be a one-off key generated for the purpose. Hosts trust any key signed by the CA.

Host certificates

Instead of distributing each host’s public key to every client, the host has its host key signed by the CA:

# Generate the CA key (one-off)
ssh-keygen -t ed25519 -f /etc/ssh/ca_key -C "SSH CA"

# Sign the host key
ssh-keygen -s /etc/ssh/ca_key -h -n host.example.com -I host.example.com \
  /etc/ssh/ssh_host_ed25519_key.pub

The signed certificate replaces the host key in sshd_config:

HostCertificate /etc/ssh/ssh_host_ed25519-cert.pub

Clients trust the CA:

# ~/.ssh/known_hosts or /etc/ssh/ssh_known_hosts
@cert-authority *.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...

All hosts whose host key is signed by the CA are trusted without further configuration on the client.

User certificates

A CA can sign user keys too. The user adds the signed certificate to their ssh-agent:

ssh-keygen -s /etc/ssh/ca_user_key -I "user@host" -n user \
  -V +52w ~/.ssh/id_ed25519.pub

The server trusts the CA:

TrustedUserCAKeys /etc/ssh/ca_user_key.pub

The signed certificate is stored as id_ed25519-cert.pub and presented by the client during auth.

Why certificates?

  • Scalability: one CA per environment. No per-host authorized_keys.
  • Short-lived credentials: a certificate can have an expiry (-V +24h). Stolen certs expire.
  • Revocation: invalidate the CA to revoke all certs, or track serial numbers in a revocation list.
  • Identity: certs include a principal (-n user) that identifies the user.

OpenSSH Certificate Authority at scale

Large organisations use an internal PKI to sign SSH certs: Active Directory Certificate Services, Vault, or smallstep. The CA’s private key is held in an HSM or offline; signing is done by a service.

Bastion hosts

A bastion (or jump host) is a hardened SSH gateway that is the only host with public SSH access. Production hosts are private and only reachable through the bastion.

operator --ssh--> bastion --ssh--> production-1
                          --ssh--> production-2
                          --ssh--> production-3

Implement a bastion

# sshd_config on the bastion
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowGroups bastion-users
AllowTcpForwarding yes
GatewayPorts no

Connect through a bastion

ssh -J bastion user@production-1

-J (ProxyJump) is the modern way to connect through a bastion. The bastion runs no daemon for the connection; it is just a regular ssh login.

In ~/.ssh/config:

Host prod-*
    User admin
    ProxyJump bastion.example.com
    IdentityFile ~/.ssh/prod_key

Host bastion.example.com
    User jumpuser
    IdentityFile ~/.ssh/bastion_key

Now ssh prod-1 automatically goes through the bastion.

Bastion hardening

  • Strong authentication only (publickey, MFA).
  • Logging to a central SIEM.
  • No interactive shell needed (just SSH forward).
  • Disable unnecessary services.
  • Update promptly.

Bastion + certificates

For maximum security, combine:

  • Bastion as the only entry point.
  • User certificates with short expiry.
  • Per-host authorization in the CA’s policy.

Production hosts trust the CA but only accept certs with valid principals (-n user) and not-yet-expired expirations. Combined with short-lived certs (24h or less), the attack window is small.

When to use which

  • Small fleet (<50 hosts): publickey + authorized_keys.
  • Medium fleet (50-500 hosts): certificates for hosts; publickey for users.
  • Large fleet (>500 hosts): certificates for everything; an internal PKI service signs certs.
  • Internet-exposed hosts: bastion pattern.
  • Compliance-bound environments: bastion + certificates + MFA + audit logging.

Knowledge check

Knowledge check · 3 questions

  1. Q1. What is the main advantage of SSH certificates over per-host authorized_keys?

  2. Q2. Production hosts should accept SSH from the public internet via a bastion.

  3. Q3. Which of the following are valid components of the bastion pattern? Select all that apply.

Passing score: 75%. Answers are checked in this browser.