Skip to main content

SSH CA setup

#

DRHECK SSH CERTIFICATE IMPLEMENTATION PLAN

###

ARCHITECTURE & SECURITY 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**ul derives user accounts from Authentik via LDAP (managed via SSSD). When a client presents an SSH certificate, `sshd`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`authorized_keys file is required.
* **Key Storage & Backup:**
 
  * The User CA private key (`drheck_ca_user_key`drheck_ca_user_key) and Host CA private key (`drheck_ca_host_key`drheck_ca_host_key) must **never**never reside on client machines or internet-facing servers (such as **ul**ul).
    * Store the offline CA private keys and passphrases securely in Vaultwarden.
    * Deploy only the CA public keys (`drheck_ca_user_key.pub`pub and `drheck_ca_host_key.pub`pub) to host **ul**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`keygen, enter a strong, unique passphrase to encrypt each CA private key.*

```bash

# 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_user_key, `drheck_ca_host_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`pub to host **ul**ul at `/etc/ssh/drheck_ca_user_key.pub`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`drheck_ca_host_key offline, the host key must be signed on your secure workstation:*

      1.

      1. Copy **ul**ul's public host key `/etc/ssh/ssh_host_ed25519_key.pub`pub to your secure workstation.
        2.
      2. On your workstation, sign the host key (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
           
      ```
      3. Copy the resulting certificate `ssh_host_ed25519_key-cert.pub`pub back to **ul**ul at `/etc/ssh/ssh_host_ed25519_key-cert.pub`pub.
      4. Set secure permissions on **ul**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`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**only the public key (`~/.ssh/id_ed25519.pub`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`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`**I: Certificate identity string printed in the server's authentication logs.
                    * **`-n`**n: Valid principals; **must**must exactly match the target LDAP username on **ul**ul.
                    * **`-V +52w`**52w: Certificate validity duration (e.g., 52 weeks or shorter).

                ####

                4. Deploy the Client Certificate
                *

                  Transfer the generated certificate `id_ed25519-cert.pub`pub back to the client machine and place it in `~/.ssh/id_ed25519-cert.pub`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`pub when utilizing `id_ed25519`id_ed25519 if they are in the same folder).*

                    * **Trusting the Host CA:** Add this line to `/etc/ssh/ssh_known_hosts`ssh_known_hosts (system-wide) or `~/.ssh/known_hosts`known_hosts on your client machines. This tells the clients to trust **ul**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`yes active on **ul**ul to allow standard `.ssh/authorized_keys`authorized_keys logins during client onboarding.
                        * Once all clients are verified and migrated, disable legacy `.ssh/authorized_keys`authorized_keys file lookups system-wide by adding the following line to `/etc/ssh/sshd_config.d/10-drheck-certs.conf`conf:
                           ```text
                            AuthorizedKeysFile /dev/null
                         
                          ```
                          *(This keeps standard certificate authentication fully active, but prevents users from logging in via traditional uncertified public keys).*