SSH certificate login

SSH is a server login tool. Generally, password login or key login is used.

However, there is a third login method for SSH, which is certificate login. In some cases, it is a more reasonable and safer login method. This article introduces this login method.

Disadvantages of non-certificate login

Both password login and key login have their own shortcomings.

Password login requires entering the server password, which is very troublesome and insecure, and there is a risk of brute force cracking.

Key login requires the server to save the user's public key, and the user also needs to save the fingerprint of the server's public key. This is very inconvenient for large organizations with multiple users and multiple servers. If an employee resigns, his public key needs to be deleted from each server.

What is certificate login?

Certificate login is designed to solve the above shortcomings. It introduces a certificate authority (Certificate Authority, CA for short), which issues server certificates to trusted servers and user certificates to trusted users.

When logging in, the user and the server do not need to know each other's public keys in advance, but only need to exchange their certificates to verify whether they are trustworthy.

There are two main advantages of certificate login: (1) The user and the server do not need to exchange public keys, which is easier to manage and has better scalability. (2) The expiration time of the certificate can be set, but the public key has no expiration time. For different situations, a certificate with a short validity period can be set to further improve security.

The process of certificate login

Before logging in with an SSH certificate, if you do not have a certificate yet, you need to generate a certificate. The specific method is: (1) Both the user and the server send their own public keys to the CA; (2) The CA uses the server public key to generate a server certificate and sends it to the server; (3) The CA uses the user's public key to generate the user The certificate is issued to the user.

With the certificate, the user can log in to the server. The whole process is handled automatically by SSH, and the user has no perception.

In the first step, when the user logs in to the server, SSH will automatically send the user certificate to the server.

In the second step, the server checks whether the user certificate is valid and whether it is issued by a trusted CA. After verification, the user can be trusted.

In the third step, SSH automatically sends the server certificate to the user.

In the fourth step, the user checks whether the server certificate is valid and whether it is issued by a trusted CA. After verification, the server can be trusted.

In the fifth step, the two parties establish a connection, and the server allows the user to log in.

Generate CA key

The premise of certificate login is that there must be a CA, and a CA is essentially a pair of keys, which is no different from other keys. The CA uses this pair of keys to issue certificates.

Although the CA can use the same pair of keys to issue user certificates and server certificates, for security and flexibility, it is best to use different keys to issue separately. Therefore, CA needs at least two pairs of keys. One pair is the key for issuing user certificates, which is assumed to be called user_ca, and the other pair is the key for issuing server certificates, which is assumed to be called host_ca.

Use the following command to generate user_ca.

# Generate the key for the CA to sign the user certificate
$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/user_ca -C user_ca

The above command will generate a pair of keys in the ~/.ssh directory: user_ca (private key) and user_ca.pub (public key).

The meaning of each parameter of this command is as follows.

--t rsa: Specify the key algorithm RSA. --b 4096: The number of bits of the specified key is 4096 bits. When the security requirements are not high, this value can be smaller, but it should not be less than 1024. --f ~/.ssh/user_ca: Specify the location and file name of the generated key. --C user_ca: Specify the identification string of the key, which is equivalent to a comment and can be set at will.

Use the following command to generate host_ca.

# Generate the key for the CA to sign the server certificate
$ ssh-keygen -t rsa -b 4096 -f host_ca -C host_ca

The above command will generate a pair of keys in the ~/.ssh directory: host_ca (private key) and host_ca.pub (public key).

Now, the ~/.ssh directory should have at least four keys.

-~/.ssh/user_ca -~/.ssh/user_ca.pub -~/.ssh/host_ca -~/.ssh/host_ca.pub

CA issues server certificate

With the CA, the server certificate can be issued.

To issue a certificate, in addition to the key of the CA, the public key of the server is also required. Generally speaking, when the SSH server (usually sshd) is installed, the key /etc/ssh/ssh_host_rsa_key is already generated. If not, you can use the following command to generate.

$ sudo ssh-keygen -f /etc/ssh/ssh_host_rsa_key -b 4096 -t rsa

The above command will generate ssh_host_rsa_key (private key) and ssh_host_rsa_key.pub (public key) in the /etc/ssh directory. Then, you need to copy or upload the server public key ssh_host_rsa_key.pub to the server where the CA is located.

After uploading, the CA can use the key host_ca to issue the server certificate for the server's public key ssh_host_rsa_key.pub.

$ ssh-keygen -s host_ca -I host.example.com -h -n host.example.com -V +52w ssh_host_rsa_key.pub

The above command will generate server certificate ssh_host_rsa_key-cert.pub (server public key name plus suffix -cert). The meaning of each parameter of this command is as follows.

--s: Specify the key for the certificate issued by the CA. --I: Identity string, which can be set arbitrarily, which is equivalent to a comment, which is convenient for distinguishing the certificate. You can use this string to revoke the certificate in the future. --h: Specify that the certificate is a server certificate, not a user certificate. --n host.example.com: Specify the domain name of the server, indicating that the certificate is only valid for this domain name. If there are multiple domain names, use commas to separate them. When a user logs in to the domain name server, SSH uses the value of the certificate to distinguish which certificate should be used to issue the user to prove the server's credibility. --V +52w: Specify the validity period of the certificate, here is 52 weeks (one year). By default, the certificate is always valid. It is recommended to use this parameter to specify the validity period, and the validity period should be shorter, and the longest period should not exceed 52 weeks. -ssh_host_rsa_key.pub: server public key.

After the certificate is generated, you can use the following command to view the details of the certificate.

$ ssh-keygen -L -f ssh_host_rsa_key-cert.pub

Finally, set permissions for the certificate.

$ chmod 600 ssh_host_rsa_key-cert.pub

CA issues user certificates

Next, use the CA to sign the user certificate. At this time, the user's public key is required. If not, the client can use the following command to generate a pair of keys.

$ ssh-keygen -f ~/.ssh/user_key -b 4096 -t rsa

The above command will generate user_key (private key) and user_key.pub (public key) in the ~/.ssh directory.

Then, upload or copy the user public key user_key.pub to the CA server. Next, you can use the CA key user_ca to sign the user certificate for the user public key user_key.pub.

$ ssh-keygen -s user_ca -I user@example.com -n user -V +1d user_key.pub

The above command will generate user certificate user_key-cert.pub (user public key name plus suffix -cert). The meaning of each parameter of this command is as follows.

--s: Specify the key of the CA to issue the certificate --I: Identity string, which can be set arbitrarily, which is equivalent to a comment, which is convenient for distinguishing the certificate. You can use this string to revoke the certificate in the future. --n user: Specify a user name, which means that the certificate is only valid for that user name. If there are multiple usernames, separate them with commas. When a user logs in to the server with this username, SSH uses this value to distinguish which certificate should be used to prove his identity and send it to the server. --V +1d: Specify the validity period of the certificate, here is 1 day, forcing users to apply for a certificate once a day to improve security. By default, the certificate is always valid. -user_key.pub: user public key.

After the certificate is generated, you can use the following command to view the details of the certificate.

$ ssh-keygen -L -f user_key-cert.pub

Finally, set permissions for the certificate.

$ chmod 600 user_key-cert.pub

Server installation certificate

After the CA generates the server certificate ssh_host_rsa_key-cert.pub, it needs to send the certificate back to the server. You can use the following scp command to copy the certificate.

$ scp ~/.ssh/ssh_host_rsa_key-cert.pub root@host.example.com:/etc/ssh/

Then, add the following line to the server configuration file /etc/ssh/sshd_config.

HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub

The above code tells sshd which file the server certificate is.

Restart sshd.

$ sudo systemctl restart sshd.service
# Or
$ sudo service sshd restart

The server installs the CA public key

In order for the server to trust the user certificate, the public key user_ca.pub of the user certificate issued by the CA must be copied to the server.

$ scp ~/.ssh/user_ca.pub root@host.example.com:/etc/ssh/

The above command copies the public key user_ca.pub of the user certificate issued by the CA to the /etc/ssh directory of the SSH server.

Then, add the following line to the server configuration file /etc/ssh/sshd_config.

TrustedUserCAKeys /etc/ssh/user_ca.pub

The above approach is to add user_ca.pub to /etc/ssh/sshd_config, which will have a global effect, that is, all accounts of the server will trust all user certificates issued by user_ca.

Another way is to add user_ca.pub to the ~/.ssh/authorized_keys file of an account on the server, and only let the account trust the user certificate issued by user_ca. The specific method is to open ~/.ssh/authorized_keys, add a line, start with @cert-authority principals="...", and then add the content of user_ca.pub, which looks like the following.

@cert-authority principals="user" ssh-rsa AAAAB3Nz...XNRM1EX2gQ==

In the above code, principals="user" specifies the name of the server account that the user logs in, which is generally the account where the authorized_keys file is located.

Restart sshd.

$ sudo systemctl restart sshd.service
# Or
$ sudo service sshd restart

So far, the SSH server has been configured to trust the certificate issued by user_ca.

Client installation certificate

It is very simple to install the user certificate on the client. It is to copy the user certificate user_key-cert.pub from the CA to the client, and save it in the same directory as the user key user_key.

Client installs CA public key

In order for the client to trust the server certificate, the public key host_ca.pub of the server certificate issued by the CA must be added to the client's /etc/ssh/ssh_known_hosts file (global level) or ~/.ssh/known_hosts file (user level).

The specific method is to open the ssh_known_hosts or known_hosts file, add a line, starting with @cert-authority *.example.com, and then paste the content of the host_ca.pub file (that is, the public key) at the back, probably It looks like this.

@cert-authority *.example.com ssh-rsa AAAAB3Nz...XNRM1EX2gQ==

In the above code, *.example.com is the pattern matching of the domain name, which means that as long as the server matches the domain name of the pattern and the CA that issued the server certificate matches the public key given later, it can be trusted. If there is no domain name restriction, it can be written as * here. If there are multiple domain name patterns, you can use commas to separate them; if the server does not have a domain name, you can use host names (such as host1,host2,host3) or IP addresses (such as 11.12.13.14,21.22.23.24).

Then, you can use the certificate to log in to the remote server.

$ ssh -i ~/.ssh/user_key user@host.example.com

The -i parameter of the above command is used to specify the user's key. If the certificate and the key are in the same directory, the certificate will be used automatically when connecting to the server.

Repeal Certificate

The operation of revoking the certificate is divided into two types: the abolition of the user certificate and the abolition of the server certificate.

To revoke the server certificate, the user needs to modify or delete the corresponding line of the @cert-authority command in the known_hosts file.

To revoke the user certificate, you need to create a new /etc/ssh/revoked_keys file on the server, and then add a line to the configuration file sshd_config, with the content as follows.

RevokedKeys /etc/ssh/revoked_keys

The revoked_keys file saves public keys of users who are no longer trusted, and is generated by the following command.

$ ssh-keygen -kf /etc/ssh/revoked_keys -z 1 ~/.ssh/user1_key.pub

In the above command, the -z parameter is used to specify the line of the revoked_keys file where the user's public key is stored. In this example, it is stored in the first line.

If you need to revoke other user public keys in the future, you can use the following command to save it on line 2.

$ ssh-keygen -ukf /etc/ssh/revoked_keys -z 2 ~/.ssh/user2_key.pub