Mastering SSH Certificate Authentication in Ubuntu: A Comprehensive Guide

Traditional password logins and even regular SSH keys are starting to feel outdated. A stronger and more scalable option is now available: SSH certificate-based authentication.

In this guide, we’ll walk through how to use SSH certificates on Ubuntu. This approach improves security and makes key management easier for both individuals and large infrastructures.

SSH key pairs are already more secure than passwords. But they come with a drawback: every user’s public key must be added to every server they need to access. That quickly becomes hard to manage.

SSH certificates solve this by centralizing trust. You create a Certificate Authority (CA) once. That CA can then sign user and host keys. Any server or client that trusts the CA will automatically trust the signed certificates.

The Core Components: Understanding the Workflow

Before diving into the practical steps, it’s crucial to understand the key players in an SSH certificate authentication setup:

  • Certificate Authority (CA): This is a machine responsible for signing user and host public keys. It holds a private key that should be guarded with the utmost care. The CA’s public key is distributed to all servers and clients that will be part of the trusted network.
  • User Certificate: This is a user’s public SSH key that has been signed by the CA. It contains information about the user, such as their username and a validity period.
  • Host Certificate: This is a server’s public SSH key signed by the CA. It verifies the server’s identity to connecting clients, preventing man-in-the-middle attacks.

The general workflow is as follows:

  1. Create a Certificate Authority.
  2. Generate standard SSH key pairs for users and servers.
  3. Sign the user and server public keys with the CA’s private key to create certificates.
  4. Configure the SSH server to trust the CA and use a host certificate.
  5. Configure the SSH client to use the user certificate for authentication.

Step 1: Creating the Certificate Authority (CA)

The first and most critical step is to set up your Certificate Authority. This should ideally be a secure, offline, or well-protected machine.

  1. Generate the CA Key Pair: On your designated CA machine, create a new SSH key pair that will serve as the CA. It is highly recommended to protect this key with a strong passphrase.
    ssh-keygen -t rsa -b 4096 -f user_ca -C "User Certificate Authority"


    This command creates two files: user_ca (the private key) and user_ca.pub (the public key). You now have a functioning, albeit simple, Certificate Authority.

Step 2: Generating and Signing a User Certificate

Next, you’ll generate a standard SSH key pair for a user and then sign their public key with the CA’s private key.

  1. Generate a User Key Pair: On the user’s local machine, generate a new SSH key pair if they don’t already have one.
    ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -C "[email protected]"


  2. Sign the User’s Public Key: Copy the user’s public key (~/.ssh/id_rsa.pub) to the CA machine. Then, use the ssh-keygen command to sign it with the user_ca private key.
    ssh-keygen -s user_ca -I user_certificate -n <username> -V +52w ~/.ssh/id_rsa.pub


    Let’s break down these options:

    See also: Mastering the Linux Command Line — Your Complete Free Training Guide



    • s user_ca: Specifies the CA private key to use for signing.

    • I user_certificate: A unique identifier for the certificate, useful for logging.

    • n <username>: The “principal” or username that this certificate will be valid for. You can specify multiple comma-separated usernames.

    • V +52w: Sets the validity period of the certificate (in this case, 52 weeks).

    • ~/.ssh/id_rsa.pub: The user’s public key to be signed.


    This will create a new file named id_rsa-cert.pub. This is the user’s signed certificate. This certificate, along with the user’s private key (id_rsa), will be used for authentication.

Step 3: Configuring the Ubuntu SSH Server

Now, you need to configure your Ubuntu server to trust certificates signed by your CA.

  1. Copy the CA Public Key: Transfer the CA’s public key (user_ca.pub) to the SSH server. A good location for this is /etc/ssh/.
  2. Edit the SSH Server Configuration: Open the SSH server’s configuration file, /etc/ssh/sshd_config, with a text editor.
    sudo nano /etc/ssh/sshd_config


  3. Add the TrustedUserCAKeys Directive: Add the following line to the sshd_config file, pointing to the location of the CA’s public key.
    TrustedUserCAKeys /etc/ssh/user_ca.pub


  4. Restart the SSH Service: For the changes to take effect, restart the SSH service.
    sudo systemctl restart sshd


Your server will now trust any user who presents a valid certificate signed by your user_ca.

Step 4: Configuring the Ubuntu SSH Client

The final piece of the puzzle is to configure the user’s SSH client to use the newly created certificate.

  1. Transfer the User Certificate: Move the signed user certificate (id_rsa-cert.pub) back to the user’s local machine, placing it in their ~/.ssh/ directory. The SSH client will automatically detect and use a certificate if it has the same base name as a private key and ends with cert.pub.
  2. Attempt to Connect: The user should now be able to connect to the configured server without needing to have their public key in the server’s ~/.ssh/authorized_keys file.
    ssh <username>@<server_ip>


    If the private key is passphrase-protected, the user will be prompted to enter it.

Enhancing Security with Host Certificates

To further bolster security and eliminate the “The authenticity of host … can’t be established” message, you can also create and use host certificates. This assures clients that they are connecting to the correct server.

  1. Create a Host CA: It’s best practice to use a separate CA for signing host keys.
    ssh-keygen -t rsa -b 4096 -f host_ca -C "Host Certificate Authority"


  2. Sign the Server’s Host Key: Copy the server’s public host key (e.g., /etc/ssh/ssh_host_rsa_key.pub) to the CA machine and sign it.
    ssh-keygen -s host_ca -I server_host_key -h -n <server_hostname_or_ip> -V +52w /etc/ssh/ssh_host_rsa_key.pub


    The -h flag indicates that this is a host certificate.

  3. Configure the Server to Use the Host Certificate: Copy the signed host certificate (ssh_host_rsa_key-cert.pub) back to the server’s /etc/ssh/ directory. Then, add the following line to /etc/ssh/sshd_config:
    HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub


    Restart the SSH service on the server.

  4. Configure the Client to Trust the Host CA: On the client machine, edit the ~/.ssh/known_hosts file and add the following line:
    @cert-authority * <contents_of_host_ca.pub>
    ``` This tells the client to trust any host that presents a valid certificate signed by the `host_ca`.


Conclusion

Implementing SSH certificate authentication on Ubuntu servers marks a significant step towards a more secure and manageable infrastructure.

By centralizing trust in a Certificate Authority, you streamline the process of granting and revoking access, eliminate the need to manage authorized_keys files on individual servers, and enhance overall security posture by verifying both user and host identities.

While the initial setup requires more steps than traditional key-based authentication, the long-term benefits in terms of security, scalability, and ease of management are undeniable.

David Cao
David Cao

David is a Cloud & DevOps Enthusiast. He has years of experience as a Linux engineer. He had working experience in AMD, EMC. He likes Linux, Python, bash, and more. He is a technical blogger and a Software Engineer. He enjoys sharing his learning and contributing to open-source.

Articles: 546

Leave a Reply

Your email address will not be published. Required fields are marked *