How I stopped worrying and learned to love public key authentication for SSH
*Editor’s note: This post was originally published on Medium. We are republishing it with Abir’s permission.*
Photo Credit: New Yorker
I remember the first time I used SSH. We were told on campus that we couldn’t
telnet into servers anymore (PS I’m old). I had no idea why at the time
(spoiler: it was hackers). Hard to believe this was over 20 years ago, and I’m
still learning new SSH tricks (sidenote: I feel like I’ve been learning
20 years too). It was only a few years ago I learned that I could save myself
from entering a password by using public key authentication for SSH.
At first it sounded magical, but I worried the process would be really complicated. This deterred me from learning how to do it for the longest time.
Photo Credit: giphy
It turns out that it’s not complicated at all! However, a lot can go wrong and confusing error messages related to SSH drove me mad!
I’ve seen a lot of articles written about how to setup public key authentication for SSH, but I hadn’t seen articles about what to do if things go wrong. So I decided to write one.
Let’s say I’ve got 3 machines:
- professorx.local † - my personal Mac laptop
- wolverine.vm † - centos 7 vm
- deadpool.vm † - ubuntu 16.04 vm
I want to be able to easily access the centos and ubuntu machines from my Mac.
In this example, I’ll want to be able to log in as the
abir user on those
The first thing I need to do create a SSH key on my laptop,
ssh-keygen. To make my life easier, I'm gonna
leave the passphrase blank. If you're concerned about security (and you should
be) you should not leave the passphrase blank. If you want to set a passphrase
I recommend reading this article. For
more information about public key authentication for ssh, check out the
Once I’ve got the public key generated I need to append the contents of it to
.ssh/authorized_keys file on the remote machines. I have 3 ways to get
that public key on those machines:
a. Copy and Paste
I can copy the contents of
into my clipboard.
Pro Tip: If you're on a Mac, you can easily copy the contents of a file into the
clipboard from the command line using the
Now I need to log into wolverine, and take the output from the clipboard and
paste it into
Caution: Copy and pasting the contents can be tricky and error prone.
b. Use scp
To simplify things, I could have also scp’d
id_rsa.pub to wolverine, and then
appended the contents of that file to
I could have also used the
I should be able to ssh into wolverine.vm now.
Woo hoo! Sounds easy, right? Here are common problems that I’ve run into in the past…
Problem #1: Unknown host
If you ping the machine you want to log into and you’re seeing an “Unknown host” error then the hostnames are not resolvable by the client.
I can make wolverine.vm resolvable by appending an entry to my
Let’s try again.
Problem #2: Connection refused
If you try to ssh into the machine using a username and password but you’re getting “Connection refused” then:
- the SSH daemon (
sshd) is not running on the machine and/or
- the port 22 (the default SSH port) isn’t open.
You can use
ssh -v to see if the port is open. If the port wasn't open, the
results would look something like this:
To resolve this issue you’ll need to install and configure
openssh on the
machine, and make sure the machine’s firewall has port 22 open. There are
different ways to set firewall rules and install
sshd on different operating
systems so I’m not going into them here.
Problem #3: Permission Denied
If you try to ssh into the machine you could also get “Permission Denied” error.
This most likely means that you don’t have your SSH creds set up correctly on the remote machine. To resolve this you’ll need to run through “The Basics” from above.
General Troubleshooting Tips
- Pass the
-vflag to the
sshcommand to get more information about what might be happening.
- Try re-creating the public/private key. I had problems when I tried passing
ssh-keygen. When I tried executing simply
ssh-keygenwith no additional parameters and passed in parameters via stdin it worked fine.
- Sometimes the
.ssh/known_hostsfile on the client machine can cause issues. Try removing the remote machine entries from the file, and then try
ssh’ing into those machines again.
- Make sure you generate the public key on the client (professorx.local in my
case) and put it on the remote servers (wolverine.vm and deadpool.vm). A
common mistake is to do the reverse: generate the key on the remote servers and
place them on the client.
Nerdy analogy: Professor X needs permission from Wolverine and Deadpool to read their minds. Think of the
authorized_keysfile as a list of people Deadpool and Wolverine let control their minds.
- Make sure you’ve got the right permissions set on the files in
Once you’ve got public key authentication for SSH set up you can use a tool like Puppet Bolt to easily execute commands on those remote machines. For example, if I want to see the free disk space on wolverine.vm and deadpool.vm I could run:
† All Marvel characters and the distinctive likeness(es) thereof are Trademarks & Copyright © 1941–2017 Marvel Characters, Inc. All rights reserved. Please don’t sue me.
Abir Majumdar is a sales engineer at Puppet.