One of the most important tools pretty much any software developer or IT system admin should be familiar with is SSH (Secure Shell). Even though most folks know how to use SSH to remotely connect to a server or VPS, many still struggle to understand how the public-key authentication works. I’ll try to explain.
So, as most of you know SSH is, as it name implies, a secure shell. Basically SSH is a cryptographic network protocol that is used for secure data communication between the server and the client. All the data that goes through it is encrypted using one of many available cryptographic algorithms. Common use-case for SSH is a remote command-line login to a machine thousands of miles away.
Basic ssh remote command-line login
In order to login to a remote machine and get a shell, you would usually type something like this:
ssh <username>@remote-machine.com [-p <PORT_NO>]
SSH will first try to verify the authenticity of a remote machine and add it to your ‘known_hosts‘ file, if you’ve never before connected to it. Assuming you have a user account on remote-machine.com, you will be prompted to enter a password and after you do that you’ll be securely connected to a machine thousands of miles away.
It’s important to note that some SSH Servers do not allow simple password authentication. They would let you in only if you had a valid public-key added to their ‘authorized_keys’ file.
What is a public-key anyway?
Well, if you haven’t taken Cryptography 101 course you’re probably not familiar with different types of cryptographic keys used for information security. I will not go deep into this matter, you can read a great article about public-private key cryptography on wikipedia.
You remember the ‘known_hosts’ file? Every time you try to connect to a remote machine, you need to obtain its public key so you can encrypt all the messages you send there using that particular key. Once the encrypted message is received on a remote side, it is being decrypted using the machine’s private key which is only available to that particular machine. The same goes the opposite way, remote machine needs to encrypt the messages it send to you using your public key and then you decrypt it using your private key. Not so complicated, right?
How to generate public-private key pair?
In order to use SSH public-key authentication you need to generate your own pair of public-private keys. Doing that in any *nix environment is pretty easy. Let me walk you through the process:
- Open your Terminal and check for existing SSH keys. Type:
ls -al ~/.ssh/ # this command lists the contents of .ssh/ folder where keys, known_hosts and authorized_keys files are stored
Check directory listing and see if there’s already a public key there. Key names usually start with something like “id_XXX.pub”. If you already have a public-private key pair there you can skip step 2.
- If you don’t see any of the keys, then let’s generate them. Type:
ssh-keygen -t rsa -C "youremail @ something.com" # Generates a new ssh key, labeling it with your email address Generating public/private rsa key pair. Enter file in which to save the key (/home/manca/.ssh/id_rsa): [Press Enter]
Next, you’ll be asked to enter a passphrase in order to protect your keys. You should choose difficult passphrase, but it is not necessary to enter any at all. I suggest you do, though.
Enter passphrase (empty for no passphrase): [Type a passphrase] Enter same passphrase again: [Type passphrase again]
Finally your keys are ready and you should see something like this:
Your identification has been saved in /home/manca/.ssh/id_rsa. Your public key has been saved in /home/manca/.ssh/id_rsa.pub. The key fingerprint is: 63:6e:36:fb:7c:82:e7:da:41:f3:d1:fd:40:32:a5:a9 youremail @ something.com
- Your keys are ready and now you are all set for the next step.
Public-Key SSH Authentication
Now that you have your public-private key pair, you can configure your SSH client to connect to a remote machine using only the public-key authentication. But if you remember, the remote machine should be aware of your public key. Therefore, you need to add it there. How do you do that?
- Copy the public key you just generated
less ~/.ssh/id_rsa.pub # You'll get something like this: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArKOgBzbNzhzUpKQayqPanSNGufonwo4k/HA2W3dk+25jMLCzfpnpQgSwZ9xOUtPkg9ycaYE/oeoKhgpNtOx7JLGrW68FaFp05vTPWxXFHedkxTMxu+0SZ6081M20ctnEzb8+x9XBofJ9I7UruoOQB+KjNZjz3YtTQ2yonwbMEaGhjTl9xaSqpCjzjx9J7WDaGr9fTc9+XXUBGmsFZv7yIUCsd4wGIq1b0p8aHGrq/4LIXaJF4A5XnDbbzN/MKpuocXEXiKXh39SLGFBl99STxLchnTp6IRHCf/MAv7SYEezjLpudge4rJU48h5kg8utSIpGGvH0tRFn7o24ic4U9SQ== manca @ mancevic.com
Copy this whole long line.
- Connect to a remote machine using basic ssh remote command-line login
- Open a file called ~/.ssh/authorized_keys:
nano ~/.ssh/authorized_keys # Feel free to use any other text editor
- Paste the just copied public key. Make sure it is all in one line (if it’s not use backspace to put it together in one line)
- Save and close the authorized_keys file
- Your remote machine is now aware of you. That means now you can remotely login to it using just your public-private key pair. Let’s test this:
- Logout from your current session (type: logout or simply press CTRL + d)
- Try logging in using the public-key authentication:
ssh <username>@remote-machine.com [-p <PORT_NO>]
That’s it. You are officially ready to use ssh public-key authentication.
But, what if you just wanted to configure your SSH client to connect to a remote machine by just typing:
Would you like to do that? Then, you just need to create a new file, called config in your .ssh folder (on your local machine):
nano ~/.ssh/config # Create a config file for ssh connections
And put some of the configuration parameters for your remote-machine, like so:
Host remote-machine HostName remote-machine.com User username IdentityFile "~/.ssh/id_rsa"
Save the file and you’re done! You can add as many hosts as you want in this particular file and use ssh to very quickly connect to any of them, without the need to type either your username or password.
I hope you enjoyed this article. Feel free to share it with the world.