In one of my projects, I wanted to be able to connect to and run shell commands on a remote Linux host computer without having to be prompted for :
(a) a login password and (b) host key fingerprint verification.
For the first requirement, I discovered a tool called sshpass, which allows me to include the password in the command call to the remote host; but it is not able to return back the status of the remote command calls. For the second, I could setup host SSH certificates but I did not want to the overhead of having to create and maintain the certificates.
The solution to achieve my objectives is described in the sections below. Basically I just needed to generate and sign my user certificate and have it authenticated by the remote SSH host when I ssh into the remote host; after setting up and configuring them, of course.
Create user certificate authority keys
In order to generate user certificates, I need to use user certificate authority (CA) keys. The following steps outlines how to generate these keys.
- On a secure Linux workstation e.g. pc1, log in as a user e.g. pcuser and open up a Terminal. Key in the following commands to generate the user CA, e.g. user_ca.
$ mkdir -p /path/to/ca/
$ cd /path/to/ca/
$ ssh-keygen -t rsa -b 4096 -f user_ca -C user_ca
The private key user_ca and the public key user_ca.pub are generated.
Note: change the certificate fie name prefix from user_ca to your desired prefix if necessary.
Setup the remote SSH host to recognize my user certificates
- On the remote SSH host, e.g. server1, open up a Terminal and copy over the previously generated user CA public key e.g. user_ca.pub.
$ scp pcuser@pc1:/path/to/ca/user_ca.pub /tmp/.
$ cd /etc/ssh/
$ sudo mv /tmp/user_ca.pub /etc/ssh/.
Note: where pcuser is the login used to generate the user CA keys on the workstation pc1.
- Change the owner of the user CA public key file e.g. user_ca.pub to root.
$ sudo chown root user_ca.pub
$ sudo chgrp root user_ca.pub
- Next, use a text editor to append the following TrustedUserCAKeys line into the /etc/ssh/sshd_config file. Save and exit the editor.
$ sudo vi /etc/ssh/sshd_config
- Then type in the following command to restart the SSH daemon.
$ sudo systemctl restart sshd
The remote SSH host is now configured to recognize any user certificates signed using the user CA user_ca key files.
Use the user CA to issue my user certificates
- Back on the secure Linux workstation e.g. pc1, type in the following commands to generate a user certificate.
$ cd /path/to/ca/
$ ssh-keygen -f my-key -b 4096 -t rsa
The private key file my-key and public key file my-key.pub are generated.
- Now, sign the generated public key e.g. my-key.pub with the user CA public key e.g. user_ca.pub.
$ ssh-keygen -s user_ca -I email@example.com -n serveruser1 my-key.pub
The signed user certificate my-key-cert.pub is generated.
Note 1: where -I firstname.lastname@example.org is a string identifier for system logs,
-n serveruser1 is a comma delimited list of login user names on the remote host to be authorized for access.
Note 2: include the -V option if you want to ensure the user certificate has an expiry date.
- Optional. Run the following command to display information about the generated user certificate my-key-cert.pub.
$ ssh-keygen -L -f my-key-cert.pub
Store and use the user certificate
- On the user's workstation, e.g. pc2, open up a Terminal and create a directory to store the generated user certificates e.g. /path/to/my-certs/.
$ mkdir -p /path/to/my-certs/
- Remove the group and others read, write and execute permissions of the newly created directory so that only the owner can access.
$ chmod go-rwx /path/to/my-certs/
- Copy over the user certificates my-key-cert.pub, my-key, my-key.pub generated in the previous section and place them into the /path/to/my-certs/ directory.
- Finally, to ssh into the remote host e.g. server1 with the user certificate my-key, type in the following command.
$ ssh -o StrictHostKeyChecking=no -i /path/to/my-certs/my-key serveruser1@server1
You are authenticated and logged into the remote host server1 as user serveruser1 without any password or fingerprint prompt.