Skip to main content

SSH CA setup

OVERVIEW

  • Authentication Flow: Incoming SSH clients authenticate using an OpenSSH user certificate signed by the trusted DrHeck User Certificate Authority (CA).
  • LDAP & Authentik Integration: Host ul derives user accounts from Authentik via LDAP (managed via SSSD). When a client presents an SSH certificate, sshd validates the certificate signature against the trusted DrHeck CA public key and checks that one of the certificate's valid principals matches the requested LDAP login username. No per-user ~/.ssh/authorized_keys file is required.
  • Key Storage & Backup:   * The User CA private key (drheck_ca_user_key) and Host CA private key (drheck_ca_host_key) must never reside on client machines or internet-facing servers (such as ul).   * Store the offline CA private keys and passphrases securely in Vaultwarden.   * Deploy only the CA public keys (drheck_ca_user_key.pub and drheck_ca_host_key.pub) to host ul and client machines.

PHASE 1: CA GENERATION & VAULTWARDEN BACKUP

Generate CA Keypairs on a secure offline or admin workstation:

When prompted by ssh-keygen, enter a strong, unique passphrase to encrypt each CA private key.

# Generate the User CA keypair
ssh-keygen -t ed25519 -f drheck_ca_user_key -C "drheck-user-ca"

# Generate the Host CA keypair
ssh-keygen -t ed25519 -f drheck_ca_host_key -C "drheck-host-ca"

Secure Storage in Vaultwarden:

  1. Create a secure note or attachment in Vaultwarden containing the private keys (drheck_ca_user_key, drheck_ca_host_key) and their passphrases.
  2. Remove the private CA keys from the unencrypted local storage of your workstation after verifying the backup.

PHASE 2: MAIN SERVER CONFIGURATION (ul)

1. Deploy Trusted User CA Public Key

  • Copy the public CA file drheck_ca_user_key.pub to host ul at /etc/ssh/drheck_ca_user_key.pub.
  • Set secure permissions:   bash   sudo chmod 644 /etc/ssh/drheck_ca_user_key.pub   sudo chown root:root /etc/ssh/drheck_ca_user_key.pub  

2. Configure Host Certificate (Signed by Host CA)

To keep the private drheck_ca_host_key offline, the host key must be signed on your secure workstation:

  1. Copy ul's public host key /etc/ssh/ssh_host_ed25519_key.pub to your secure workstation.
  2. On your workstation, sign the host keykey:
(valid for 52 weeks):    
bash    ssh-keygen -s drheck_ca_host_key -I "drheck-ul-host-cert" -h -n ul,ul.drheck.dev -V +52w ssh_host_ed25519_key.pub
  1. Copy the resulting certificate ssh_host_ed25519_key-cert.pub back to ul at /etc/ssh/ssh_host_ed25519_key-cert.pub.

  2. Set secure permissions on ul:

bash    sudo chmod 644 /etc/ssh/ssh_host_ed25519_key-cert.pub
sudo chown root:root /etc/ssh/ssh_host_ed25519_key-cert.pub

3. Configure OpenSSH Daemon on ul

  • Create the config file /etc/ssh/sshd_config.d/10-drheck-certs.conf:
bash   sudo vim /etc/ssh/sshd_config.d/10-drheck-certs.conf
  • Add the following directives to trust incoming User CA certificates and deploy the host certificate:
text   TrustedUserCAKeys /etc/ssh/drheck_ca_user_key.pub
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub

4. Validate and Reload SSHD on ul

  • Validate the configuration syntax before reloading:
bash   sudo sshd -t
  • If no errors are returned, reload the daemon:
bash   sudo systemctl reload sshd


PHASE 3: CLIENT MACHINE ONBOARDING & SIGNING

1. Client Key Generation

  • On the Linux client machine, generate a standard SSH keypair if one doesn't exist:
bash   ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "client key label"

2. Certificate Signing Request

  • Transfer only the public key (~/.ssh/id_ed25519.pub) and the target LDAP username to the DrHeck CA administrator.

3. Sign the Client Public Key

  • On the secure workstation, sign the client public key using the vaulted drheck_ca_user_key (defining the exact LDAP username as the principal):
bash   ssh-keygen -s drheck_ca_user_key -I "client-hostname-YYYYMMDD" -n <ldap_username> -V +52w id_ed25519.pub
*
  • -I: Certificate identity string printed in the server's authentication logs.
* -n: Valid principals; must exactly match the target LDAP username on ul. * -V +52w: Certificate validity duration (e.g., 52 weeks or shorter).

4. Deploy the Client Certificate

  • Transfer the generated certificate id_ed25519-cert.pub back to the client machine and place it in ~/.ssh/id_ed25519-cert.pub (alongside the private key).
  • Set file permissions on the client:
bash   chmod 644 ~/.ssh/id_ed25519-cert.pub

5. Client SSH Configuration (~/.ssh/config)

  • Configure the host entry on the client machine to use the cert automatically:

text   Host ul
    HostName <ul_fqdn_or_ipv6>
    User <ldap_username>
    IdentityFile ~/.ssh/id_ed25519

  (Note: OpenSSH automatically detects and presents id_ed25519-cert.pub when utilizing id_ed25519 if they are in the same folder).

  • Trusting the Host CA: Add this line to /etc/ssh/ssh_known_hosts (system-wide) or ~/.ssh/known_hosts on your client machines. This tells the clients to trust ul's host certificate automatically without prompting about finger-prints:

text   @cert-authority * ssh-ed25519 <drheck_ca_host_key.pub_content>



PHASE 4: VERIFICATION & MIGRATION

1. Test Certificate Authentication

  • Connect from the client machine with verbose debug output:
bash   ssh -v ul
  • Confirm that the client authenticates using the certificate signature:
text   Server accepts key: pkalg ssh-ed25519-cert-v01@openssh.com

2. Migration Strategy

  • Keep PubkeyAuthentication yes active on ul to allow standard .ssh/authorized_keys logins during client onboarding.
  • Once all clients are verified and migrated, disable legacy .ssh/authorized_keys file lookups system-wide by adding the following line to /etc/ssh/sshd_config.d/10-drheck-certs.conf:
text   AuthorizedKeysFile /dev/null

  (This keeps standard certificate authentication fully active, but prevents users from logging in via traditional uncertified public keys).