In the last part, there was a lot of planning, and preparation, for setting up SSH to use certificates instead of passwords to authenticate a user. Now comes the configuration and trial-and-error portion.
First thing I’m going to cover is the sshd_config file (config file for the SSH daemon), which is usually found in /etc/ssh/sshd_config. I’ll be going through this one by one on what I changed, why I did so, and any suggestions I can provide.
I highly suggest changing this to something else, simply because it reduces the risk of attack all together. All this does is change the port that SSH listens on. I usually set mine higher than 1024, because a lot of “good” services listen on ports below that, but it’s up to you on how high or low you want to go. Another note here, I’ve read a lot of talk over the years that you should specify the address a program listens on (i.e.: ListenAddress 192.168.1.59). I don’t believe in doing this unless you have more than one NIC in the server, especially if you have a switch in your network. I’ll probably make this another article at some point on this specific topic, but not right now.
Another security measure, that doesn’t really deal with certificates, but is a “better safe than sorry” approach. This restricts “root” from logging in at all when establishing an SSH connection. I usually have this enabled though until I know everything works fine just for the fact I tend to make mistakes. But, in a production environment, I don’t know of any security-aware professional that would say to leave this enabled (“yes”).
RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys
The first two are for enabling certificate-based authentication. RSAAuthentication is basically saying that an RSA key is going to be used, and PubkeyAuthentication uses a public key to authenticate the user. AutherizedKeysFile just simply tells SSH where to look for the RSA and public keys (relative to /home/user/). The reason for enabling the first two is that RSA generates a private and public key. The public keys are generated on the user’s machine, and private keys are created on the server. I’ll get into this more in a bit.
This, by default, is turned on. This is what makes it possible to log in using a password. Now, if you want to completely disable the ability to log in using a password, disable this. Otherwise, when you go to log in, it will ask you for the certificate’s passphrase (if there is one; which I’ll also get into in a bit), and then if fails, it’ll ask for the account’s password. I never see the point of having this enabled, but if you feel more safe allowing both methods to be used, have it there.
If you remember my last SSH security post, you’ll remember I suggested creating a SSH-only group. If you didn’t do this, or want to allow users outside of that group, then AllowUsers will help as well. One problem I’ve seen with this is that you can have a big list (separated by spaces) of groups and/or users you want to grant access to, but most editors tend to break these lines so that the list is on two or more lines. So, to make things easier (and cleaner), if you have a big list, you can have multiple lines of Allow* in the config file. A personal recommendation here, is to not have both of these enabled. Reason being, what happens if you remove a user from AllowUsers, but forget to remove them from the group? They’re still able to log in (this is assuming you didn’t delete the user or lock their account).
Phew, okay, now after you’ve made these changes, you can save the file and close it. Since we’ll be copying the key over before we can use this, I suggest NOT restarting the daemon until later. Now, onto generating the keys needed. First, I’ll cover the server side, as we have to copy the client’s key over at the end.
On the server, there’s similar work that needs to be made. Run this command from inside the /home directory for the SSH account:
mkdir .ssh && touch .ssh/authorized_keys && chmod go= .ssh && chmod 600 .ssh/authorized_keys
This does similar to the client-side command you had to run, with the added “read and write only” permissions on authorized_keys. If this isn’t in place, then SSH tends to basically not allow log in period, as it views it as a security breach if it’s anything beyond 600 (i.e.: 700 or 610). Now, to handle the client side of things.
Assuming AuthorizedKeysFile was left as the default, make the .ssh directory:
mkdir ~/.ssh && chmod go= ~/.ssh
This makes the directory in your home account and then chmod’s the directory as 700 (rwx——). Next, go into that directory and run the following command:
ssh-keygen -t rsa
By default, SSH uses RSA for certificates (even though you can use DSA as well). Next, you’ll be asked a few questions (which most can be used as defaults), such as:
Generating public/private rsa key pair. Enter file in which to save the key (/home/user/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user/.ssh/id_rsa. Your public key has been saved in /home/user/.ssh/id_rsa.pub.
Now, one thing to note here, is the passphrase option. To put it shortly, if you enter a passphrase, you’ll ALWAYS be asked for this when logging in. If you leave it empty, as long as a key matches in the authorized_keys file on the server, authentication is assumed good. Personally, I go the extra mile and add in this little bit of security. After that, you’ll have your private (id_rsa) and public (id_rsa.pub) keys ready to go. Now all that’s left is to copy the key over to the server, and restart the daemon. To copy the key over, just use this command:
After this, restart the daemon on the server, and try to log in to SSH from the client. If you entered a passphrase, you should be asked for the passphrase (and if you didn’t enter a passphrase, you should see the prompt).
If you have any issues, remarks, questions, etc…on this, feel free to leave a comment. This is really a lot easier than it sounds. Another thing I like to do is use the dummy account as a skeleton account for others (-k command in useradd). This will copy over the entire directory for this account to the new one.