Skip to content

SSH Key Signing#

SSH key signing involves using a trusted certificate authority (in this case, Vault) to digitally sign SSH public keys. This process creates SSH certificates, which are then used for authentication instead of raw public keys. The signed SSH certificates include a time to live (TTL) which enables just in time access to servers. SSH key signing via Vault is a much more secure method for connecting to shared linux user accounts instead of adding everyone's public key to the account or sharing the private key.

General Authentication Flow#

  1. A user generates an SSH key pair.
  2. The public key is sent to a certificate authority (Vault).
  3. Vault signs the public key, creating an SSH certificate.
  4. The user presents the certificate when connecting to a server.
  5. The server verifies the certificate using the CA’s public key.

Vault & Server Setup#

Most of these steps are also available via the GUI. The instructions below are dependent on having the vault-enterprise binary installed on your workstation.

Note

This setup is utilizing the cert-authority directive in an individual linux user's .ssh\authorized_keys file. For host wide setup to be utilized by multiple accounts, see Hashicorp's article on client key signing

  1. Login to Vault and enable the ssh secrets engine in Vault

    Bash Session
    # Login to Vault
    export VAULT_ADDR=https://hcp-vault-private-vault-fc507e0d.5d5b1f21.z1.hashicorp.cloud:8200/
    export VAULT_NAMESPACE=admin/<CESI>
    vault login --method=saml --namespace=admin
    
    # Enable ssh secrets engine at path ssh-client-signer (or other path of your choosing)
    vault secrets enable -path=ssh-client-signer ssh
    
  2. Configure the Vault certificate authority. Make note of the public_key, otherwise you can retrieve it later by running vault read -field=public_key ssh-client-signer/config/ca

    Bash Session
    vault write ssh-client-signer/config/ca generate_signing_key=true
    
  3. Create an ssh signer role. Configure the default_user to be the linux username of the shared user and the ttl to be how long signed ssh certificates are valid for.

    Bash Session
    vault write ssh-client-signer/roles/my-role -<<"EOH"
    {
    "algorithm_signer": "rsa-sha2-256",
    "allow_user_certificates": true,
    "allowed_users": "*",
    "allowed_extensions": "permit-pty,permit-port-forwarding",
    "default_extensions": {
        "permit-pty": ""
    },
    "key_type": "ca",
    "default_user": "shared_user",
    "ttl": "30m0s"
    }
    EOH
    
  4. On the linux server that you would like to use SSH key signing with, as the shared user create .ssh directory and authorized_keys file if it does not already exist

    Bash Session
    mkdir ~/.ssh/
    chmod 700 ~/.ssh/
    touch ~/.ssh/authorized_keys
    chmod 600 ~/.ssh/authorized_keys
    
  5. Insert the following line into the ~/.ssh/authorized_keys file created in step 3 (or as a new line if that file existed already)

    Bash Session
    cert-authority ssh-rsa <PUBLIC KEY FROM STEP 2>
    

Authentication via Signed Key#

  1. If you already have an ssh private/public key pair for Vault to sign, you can skip this step, otherwise generate a new key pair.

    Bash Session
    ssh-keygen -t rsa -C "user@example.com"
    
  2. Log in to Vault and request your public key to be signed, and output the the signed certificate as signed-cert.pub. Depending on where you saved your public key in step 1, customize the public_key option.

    Bash Session
    # Login to Vault
    export VAULT_ADDR=https://hcp-vault-private-vault-fc507e0d.5d5b1f21.z1.hashicorp.cloud:8200/
    export VAULT_NAMESPACE=admin/<CESI>
    vault login --method=saml --namespace=admin
    
    # Enable ssh secrets engine at path ssh-client-signer (or other path of your choosing)
    vault write -field=signed_key ssh-client-signer/sign/my-role public_key=@$HOME/.ssh/id_rsa.pub > signed-cert.pub
    
  3. SSH into your server using your private key and signed certificate. Depending on where you saved your private key in step 1, customize the second -i option to reference it.

    Bash Session
    ssh -i signed-cert.pub -i ~/.ssh/id_rsa shared_user@<SERVER>.oit.umn.edu