How to build an OpenSSH based Certificate Authority Infrastructure

How to build an OpenSSH based Certificate Authority Infrastructure

linux_openssh_ca_system

In Linux environment using the SSH key based authentication system requires copying the client public key to the host server. In large organization this key based authentication system might not scale well as it would be difficult to generate and manage all the public keys and manually copy them from client workstation to the server to which we want to connect.

This issue can be mitigated by generating public keys certificates signed by some certificate authority and instead of copying these public keys we can just authenticate the validity of the public key certifictes issues by user by verifying it against the signer certificates of the certificaet authority. X.509 Public Key Infrastructure Certificate system can be used to mitigate this issue but it involves submission and validation process, with associated fees.

OpenSSH certificates contain a public key, identity information, and validity constraints. They are signed with a standard SSH public key using the ssh-keygen utility. The ssh-keygen utility supports two types of certificates: user and host. User certificates authenticate users to servers, whereas host certificates authenticate server hosts to users. For certificates to be used for user or host authentication, sshd must be configured to trust the CA public key.

Test Environment

Fedora 36 server
Fedora 36 client
Fedora 36 ca server

Procedure

Step1: Ensure OpenSSH package installed on systems

We need to have the OpenSSH package installed on all the servers to use the openssh based ca system for authentication.

[root@fedca ~]# dnf install openssh
[root@fedclient ~]# dnf install openssh
[root@fedhost ~]# dnf install openssh

Step2: Generating SSH CA Certificate signing keys on CA server

As per this step, we will be generating the SSH keys for user and host separately. The private keys for the user and host respectively will be used to sign the client and server public keys to generate the respective certificates. Note, single key for user and host certificate signing can also be used but for clarity purpose we are using separate keys for user and host.

root@fedca ~]# ssh-keygen -t rsa -f ~/.ssh/ca_user_key
[root@fedca ~]# ssh-keygen -t rsa -f ~/.ssh/ca_host_key

[root@fedca ~]# ls -ltr /root/.ssh/
total 16
-rw-------. 1 root root 2610 Jul 13 00:12 ca_user_key
-rw-r--r--. 1 root root  574 Jul 13 00:12 ca_user_key.pub
-rw-------. 1 root root 2610 Jul 13 00:13 ca_host_key
-rw-r--r--. 1 root root  574 Jul 13 00:13 ca_host_key.pub

Step3: Create the CA server’s own host certificate

Here we are generating the CA server certificate by signing the CA server host public key with the CA host private key which we generated in the earlier step.

[root@fedca ~]# ssh-keygen -s ~/.ssh/ca_host_key -I fedca -h -n fedca.stack.com -V -1w:+54w5d /etc/ssh/ssh_host_rsa_key.pub
Signed host key /etc/ssh/ssh_host_rsa_key-cert.pub: id "fedca" serial 0 for fedca.stack.com valid from 2022-07-06T08:11:03 to 2023-07-31T08:11:03

[root@fedca ~]# ls -ltr /etc/ssh/ssh_host_rsa_key-cert.pub
-rw-r--r--. 1 root root 1868 Jul 13 08:11 /etc/ssh/ssh_host_rsa_key-cert.pub

Now, as you can see the public certificate as been generated for the CA server as shown above.

Step4: Distribute SSH CA Public keys on to Host servers

Now, we are going to configure our host server with the CA user public key for which we need to copy the CA user public key onto the host server as shown below.

[root@fedca ~]# scp /root/.ssh/ca_user_key.pub root@fedhost.stack.com:/etc/ssh/
[admin@fedhost ~]$ ls -ltr /etc/ssh/ca_user_key.pub 
-rw-r--r--. 1 root root 574 Jul 13 00:23 /etc/ssh/ca_user_key.pub

Step5: Trusting the User Signing Key

We need to edit the sshd config file to trust the CA user public key as shown below and restart the sshd service. Please make sure you take a backup of the original sshd config file before modification.

[admin@fedhost ~]$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config_backup_original

[admin@fedhost ~]$ sudo cat /etc/ssh/sshd_config | grep TrustedUserCAKeys
TrustedUserCAKeys /etc/ssh/ca_user_key.pub

[admin@fedhost ~]$ sudo systemctl restart sshd.service 

Step6: Configure client systems to trust servers signed host certificates

In this step we are going to configure the client systems ssh_known_hosts file with the CA host public key for trusting purpose.

[root@fedca ~]# cat ~/.ssh/ca_host_key.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCdnQRuQBsnIh62XVL1eAZtGg6rTdu+ap1aQxr+HT2mAmL1AAgqHmggfMtltHI53PCE/IdBvZisVnx2er1YLFie4o7xoCSnpcVgrIR1/Rkqtu3pI8cmyB2OU6W5gGq44KT9yitMCZi2KvGvENYWBxVMCUklnVolXxrXuy3lw8aIpq4hdj8AknlRftWnSl088KZTh1eJueufeIcisyq+X8fv1T4ASTil9u41X3gbssJBizZXV64HOpR7z1MXr4axaeORnZ+7xIC6sNrCmqUkS5XvyuaFabfkXVTs3+D6Xb11N3hEBqPZA46lp9R0a8hZS5wTubbK6Gs6dsEkSDs8XqQS+eegifUEcxeBM1HlIimYJ2OeNylEdWZm9dPYPYnpImQIIhR+fhSlayH0I04yoyvYugUUsMrgqwrEAbkJ9xLmh+rLGZQygGN7BVsgq2szKZeKR6W1xBr0VDFg0ATPxGZCtIovB1RQOv5gP/akaw41hOOmY4/6Xis8LsYVUNhLcqc= root@fedca.stack.com

Update the ca host key from ca server into the ssh_know_hosts file on the client machine.

[root@fedclient ~]# cat /etc/ssh/ssh_known_hosts
# A CA key, accepted for any host in *.stack.com
@cert-authority *.stack.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCdnQRuQBsnIh62XVL1eAZtGg6rTdu+ap1aQxr+HT2mAmL1AAgqHmggfMtltHI53PCE/IdBvZisVnx2er1YLFie4o7xoCSnpcVgrIR1/Rkqtu3pI8cmyB2OU6W5gGq44KT9yitMCZi2KvGvENYWBxVMCUklnVolXxrXuy3lw8aIpq4hdj8AknlRftWnSl088KZTh1eJueufeIcisyq+X8fv1T4ASTil9u41X3gbssJBizZXV64HOpR7z1MXr4axaeORnZ+7xIC6sNrCmqUkS5XvyuaFabfkXVTs3+D6Xb11N3hEBqPZA46lp9R0a8hZS5wTubbK6Gs6dsEkSDs8XqQS+eegifUEcxeBM1HlIimYJ2OeNylEdWZm9dPYPYnpImQIIhR+fhSlayH0I04yoyvYugUUsMrgqwrEAbkJ9xLmh+rLGZQygGN7BVsgq2szKZeKR6W1xBr0VDFg0ATPxGZCtIovB1RQOv5gP/akaw41hOOmY4/6Xis8LsYVUNhLcqc= root@fedca.stack.com

Step7: Copy the host’s public key to CA server

Here we are going to copy the host server public key to the CA server for signing purpose and generate the host server certificate as shown below.

[admin@fedca ~]$ mkdir keys
[admin@fedca ~]$ pwd
/home/admin
[admin@fedca ~]$ ls -ltr keys/
total 0
[admin@fedca ~]$ chmod o+w keys
[admin@fedca ~]$ ls -ld keys/
drwxr-xrwx. 2 admin admin 6 Jul 13 00:42 keys/
[root@fedhost ~]# scp /etc/ssh/ssh_host_rsa_key.pub admin@fedca.stack.com:~/keys/ssh_host_rsa_key.pub
[admin@fedca ~]$ ls -ltr keys/
total 4
-rw-r--r--. 1 admin admin 554 Jul 13 00:47 ssh_host_rsa_key.pub

Step8: Sign the host’s public key on CA server

This is an important step. Once the host public key is copied onto the CA server we can sign the public key using the CA host private key as shown below.

[root@fedca ~]# ssh-keygen -s ~/.ssh/ca_host_key -I fedhost -h -n fedhost.stack.com -V -1d:+54w /home/admin/keys/ssh_host_rsa_key.pub
Signed host key /home/admin/keys/ssh_host_rsa_key-cert.pub: id "fedhost" serial 0 for fedhost.stack.com valid from 2022-07-12T08:34:18 to 2023-07-26T08:34:18

Step9: Copy the host’s certificate to host server

We will copy the generated host certificate back to the host server as shown below.

[root@fedca ~]# scp /home/admin/keys/ssh_host_rsa_key-cert.pub root@fedhost.stack.com:/etc/ssh/
[root@fedhost ~]# ls -ltr /etc/ssh/ssh_host_rsa_key-cert.pub 
-rw-r--r--. 1 root root 1896 Jul 13 00:54 /etc/ssh/ssh_host_rsa_key-cert.pub

Step10: Update the host’s sshd config to present the host certificate for authentication

Now, we will need to update the sshd config to make the host server present the certificate when user wants to authenticate the host server certificate. Restart the sshd service once the necessary modification done.

[root@fedhost ~]# cat /etc/ssh/sshd_config | grep HostCertificate
HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub

[root@fedhost ~]# systemctl restart sshd.service 

Step11: Validate fedhost access remotely from fedclient

Now, if you validate the remote ssh access to the host server you should notice that you no longer get a warning message that the host server is not authenticated.

[admin@fedclient ssh]$ ssh admin@fedhost.stack.com
admin@fedhost.stack.com's password: 
Web console: https://fedhost.stack.com:9090/ or https://192.168.122.130:9090/

Last login: Wed Jul 13 08:40:18 2022 from 192.168.122.133

Hope you enjoyed reading this article. Thank you..