Beyond Password Login With SSH
SSH is an amazing network administration tool and in this tutorial we will look at how we can use several ways to authenticate that are more secure than simple password logins.
By default SSH uses password login. As part of the first step in securing your server you want to completely disable password login.
We can do this by first pushing our ssh public key to the remote machine:
ssh-keygen ~/.ssh/id_rsa
ssh-copy-id user@remote
Set a key password to protect the key itself.
Then we can disable password login by editing the sshd_config file:
sudo nvim /etc/ssh/sshd_config
And changing the following line:
- #PasswordAuthentication yes
+ PasswordAuthentication no
Then restart the ssh service:
sudo systemctl restart sshd
If you want to do this using an ansible task then you can add this to your playbook:
- name: Disable SSH password login
replace:
path: /etc/ssh/sshd_config
regexp: '^#?\s*PasswordAuthentication\s+.*'
replace: 'PasswordAuthentication no'
notify: Reload ssh server
Now you can only login to the remote machine using your ssh key.
This is distinctly different from having a password stored on the server. Instead of storing a hash of the actual password on the server, the server contains a public key. When SSH authenticates, it will negotiate a shared secret without transferring it between machines using the public key of the server and the private key of the client. Thus a secure channel can be established.
Now let’s look at other ways we can work with ssh remotely.
SSH Agent
If you use a password for your key and you do a lot of automation over ssh then you naturally want to avoid entering your password every time. This is where SSH agent comes in.
The SSH agent is a program that runs in the background and stores your private key in memory. When you connect to a remote server, the agent will use your key to authenticate you.
To start the agent, run:
eval $(ssh-agent)
Then add your key to the agent:
ssh-add ~/.ssh/id_rsa
Signed Keys using CA
If you have a lot of servers and you want to manage keys in a more centralized way then you can use a Certificate Authority (CA) to sign your keys.
To do this you need to generate a CA key:
ssh-keygen -t rsa -b 4096 -f ~/.ssh/ca_key
Then you can sign your keys with the CA key:
ssh-keygen -s ~/.ssh/ca_key -I "user@remote" -n user -V +52w ~/.ssh/id_rsa.pub
This will create a signed certificate that you can use to login to the remote machine (id_rsa-cert.pub). This is specifically a signed certificate file and not to be confused with the public key.
In order to make it easy to login to the remote machine you can add the signed certificate to your ssh config file:
Host remote
HostName remote
User user
IdentityFile ~/.ssh/id_rsa
CertificateFile ~/.ssh/id_rsa-cert.pub
On the remote machine you need configure the sshd_config file to accept keys signed by the CA by copying the CA public key to the remote machine and adding the following to your sshd_config file:
- #TrustedUserCAKeys /etc/ssh/ca.pub
+ TrustedUserCAKeys /etc/ssh/ca.pub
And then restart the ssh service:
sudo systemctl restart sshd
This ensures that users who have not been authorized by the CA cannot login to the remote machine. This is even more secure than using authorized keys file because the CA public key can be the same across all machines and each key that is to be signed must be signed by the CA private key. This means that there is no initial access needed to the machine by the user.
Two factor authentication
If you want to add an extra layer of security to your ssh login you can use two factor authentication using google authenticator.
To set this up do as follows:
sudo apt install libpam-google-authenticator
google-authenticator
This will generate a QR code that you can scan with your phone. You can then use the google authenticator app to generate a time based code that you can use in addition to normal authentication to log into the machine.
To make SSH use the Google Authenticator PAM module, add the following line to
the /etc/pam.d/sshd
file:
auth required pam_google_authenticator.so
To disable asking for password you can also comment out the following lines in the
/etc/pam.d/sshd
file:
- @include common-auth
+ #@include common-auth
- @include common-password
+ #@include common-password
You will also need to enable challenge response authentication in sshd config:
+ PasswordAuthentication no
+ ChallengeResponseAuthentication yes
+ KbdInteractiveAuthentication yes
# Choose publickey only if you want to use ssh in automated scripts
+ AuthenticationMethods publickey publickey,keyboard-interactive
And restart the ssh service.
Two factor authentication works by keeping a shared secret between the server and the client. The client generates a code based on the secret and current time and sends it to the server. The server does the same and compares the two codes.
The secret is transferred to the client using the qr code and is stored in the app.
If you have specified both publickey
and publickey,keyboard-interactive
in
your sshd config file then you will be able to login using just the key without
a verification code.