Linux SSH authentication
SSH (Secure Shell Protocol) is a way for us to connect securely to a service as a cryptographic network protocol. It is used mostly for login, command line execution or database access for example.
SSH is an alternative to using passwords for logging in to a service as passwords can be easily brute forced, guessed and human error-prone. A better alternative is to use keys instead of passwords.
Keys are basically a pair of files, private and public, where’s the first should be kept in secret and public would be used for sharing. This makes keys for hacking harder and using them does not require memorizing a password.
We will focus on working with keys in this article to connect from our local machine to a server.
It’s expected that we have a server with an ssh server already running on port 22 and an existing default user for login. If you are using AWS EC2 Ubuntu image you should have these by default.
Otherwise, you would have to install it.
sudo apt-get install openssh-client
Getting started with SSH keys
How to create keys and note you may be prompted to create a passphrase, but you don’t need to, especially if you want to use the key in an automated process:
# Simple version
ssh-keygen -t rsa
# Advanced version that specifies the 4096 of bits in the RSA key to creation (default is 2048) with a comment
# and custom file
ssh-keygen -t rsa -b 4096 -f ~/.ssh/my-web-server.key -C "Key to my web server"
# Make sure only the user has permissions
chmod 600 $HOME/.ssh
These files are usually stored under $HOME/.ssh
directory, default names being id_rsa.pub
for public and id_rsa
for
private.
When creating these keys locally you would upload the public key to your server and append it on the
~/.ssh/authorized_keys
file.
Now you can connect to the server using the new key (private)
# If it's the default ~/.ssh/id_rsa
ssh user@your-server-ip-address
# If it's a custom name you need to specify it
ssh -i ~/.ssh/my-key user@my-server-ip-address
Session with SSH agent
If you will be making multiple commands towards the server via SSH and don’t want to authenticate every single time and/or use a passphrase, you can start a session, add a key to it and use commands from that point normally.
eval $(ssh-agent)
# Load the key into the agent session
ssh-add my-key.key
# Execute SSH commands, copy file to a server and connect to it
scp -r nginx.conf ${SSH_USER}@${SSH_HOST}:/etc/nginx/nginx.conf
ssh ${SSH_USER}@${SSH_HOST}
And if needed you can delete all private keys from the session agent
ssh-add -D
Or you can ensure your shell script kills the agent after finishing
trap "kill $SSH_AGENT_PID" 0
This approach is excellent if you are on a runner within a CI/CD pipeline and want to execute commands on the server.
Quick example
Short example of creating a user use and giving him SSH access (requires sudo user):
sudo -i
# Create user with his home directory
useradd -m -d /home/john john
# Remove password access for the user (because we are using SSH key)
passwd -d john
# Lets create a key and copy the public one to the server and the new user's directory (no passphrase)
ssh-keygen -t rsa -b 4096 -f /home/john/.ssh/john.key -C "My test user"
chmod 700 /home/john/.ssh
cat /home/john/.ssh/john.key.pub >> /home/john/.ssh/authorized_keys
chwon -R john /home/john/.ssh
Now that you have everything set, copy the private key john.key
locally, set it’s access chmod 600
and try to
connect:
ssh -i ~/.ssh/john.key john@my-server-ip
You should be able to connect and verify you are john with whoami
or pwd
.