We’ve extolled the virtues of SSH numerous times, for both security and remote access. Let’s take a look at the server itself, some important “maintenance” aspects, and some quirks that can add turbulence to an otherwise smooth ride.
While we’ve written this guide with Linux in mind, this can also apply to OpenSSH in Mac OS X and Windows 7 via Cygwin.
Why It’s Secure
We’ve mentioned many times how SSH is a great way to securely connect and tunnel data from one point to another. Let’s take a very brief look at how things work so you get a better idea of why things can go weird sometimes.
When we decide to initiate a connection to another computer, we often use protocols that are easy to work with. Telnet and FTP both come to mind. We send out information to a remote server and then we get confirmation back about our connection. In order to establish some type of safety, these protocols often use username and password combinations. That means they’re totally secure, right? Wrong!
If we think of our connecting process as mail, then using FTP and Telnet and the like isn’t like using standard mailing envelopes. It’s more like using postcards. If someone happens to step in the middle, they can see all of the information, including the addresses of both correspondents and the username and password sent out. They can then change the message, keeping the information the same, and impersonate one correspondent or the other. This is known as a “man-in-the-middle” attack, and not only does it compromise your account, but it calls into question each and every message sent and file received. You can’t be sure if you’re talking to the sender or not, and even if you are, you can’t be sure no one’s looking at everything from in between.
Now, let’s look at SSL encryption, the kind that makes HTTP more secure. Here, we have a post office that handles the correspondence, who checks to see if your recipient is who he or she claims to be, and has laws protecting your mail from being looked at. It’s more secure overall, and the central authority – Verisign is one, for our HTTPS example – makes sure that the person who you’re sending mail to checks out. They do this by not allowing postcards (unencrypted credentials); instead they mandate real envelopes.
Finally, let’s look at SSH. Here, the setup is a little different. We don’t have a central authenticator here, but things are still secure. That’s because you’re sending letters to someone whose address you already know – say, by chatting with them on the telephone – and you’re using some really fancy math to sign your envelope. You hand it over to your brother, girlfriend, dad, or daughter to take it to the address, and only if the recipient’s fancy math matches do you assume that the address is what it should be. Then, you get a letter back, also protected from prying eyes by this awesome math. Finally, you send your credentials in another secretive algorithmically-enchanted envelope to the destination. If the math doesn’t match, we can assume that the original recipient moved and we need to confirm their address again.
With the explanation as long as it is, we think we’ll cut it there. If you have some more insight, feel free to chat in the comments, of course. For now, though, let’s look at the most relevant feature of SSH, host authentication.
Host authentication is essentially the part where someone you trust takes the envelope (sealed with magic math) and confirms the address of your recipient. It’s a pretty detailed description of the address, and it’s based on some complicated math that we will just skip right over. There are a couple of important things to take away from this, though:
- Since there is no central authority, the real security lies in the host key, the public keys and the private keys. (These latter two keys are configured when you’re given access to the system.)
- Usually, when you connect to another computer via SSH, the host key is stored. This makes future actions faster (or less verbose).
- If the host key changes, you will most likely be alerted and you should be wary!
Since the host key is used before authentication to establish the identity of the SSH server, you should be sure to check the key before you connect. You will see a confirmation dialog like below.
You shouldn’t worry, though! Often when security is a concern, there will be a special place that the host key (ECDSA fingerprint above) can be confirmed. In entirely online ventures, often it will be on a secure log-in only site. You may have to (or choose to!) phone your IT department to confirm this key over the phone. I’ve even heard of some places where the key is on your work badge or on the special “Emergency Numbers” list. And, if you have physical access to the target machine, you can also check for yourself!
Checking Your System’s Host Key
There are 4 types kinds of encryption algorithms used to make keys, but the default for OpenSSH as of earlier this year is ECDSA (with some good reasons). We’ll focus on that one today. Here’s the command you can run on the SSH server you have access to:
ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key.pub -l
Your output should return something like this:
256 ca:62:ea:7c:e4:9e:2e:a6:94:20:11:db:9c:78:c3:4c /etc/ssh/ssh_host_ecdsa_key.pub
The first number is the bit-length of the key, then is the key itself, and finally you have the file it’s stored in. Compare that middle portion to what you see when you’re prompted to log in remotely. It should match, and you’re all set. If it doesn’t, then something else could be happening.
You can view all of the hosts you have connected to via SSH by looking at your known_hosts file. It is usually located at:
You can open that in any text editor. If you look, try to pay attention to how keys are stored. They’re stored with the host computer’s name (or web address) and its IP address.
Changing Host Keys and Problems
There are a few reasons why host keys change or they don’t match what is logged in your known_hosts file.
- The system was re-installed/re-configured.
- The host keys were manually changed due to security protocols.
- The OpenSSH server updated and is using different standards due to security issues.
- The IP or DNS lease changed. This often means you’re trying to access a different computer.
- The system was compromised in some way such that the host key changed.
Most likely, the issue is one of the first three, and you can ignore the change. If the IP/DNS lease changed, then there may be an issue with the server and you may be routed to a different machine. If you’re not sure what the reason for the change is then you should probably assume it’s the last one on the list.
How OpenSSH Handles Unknown Hosts
OpenSSH has a setting for how it handles unknown hosts, reflected in the variable “StrictHostKeyChecking” (without quotes).
Depending on your configuration, SSH connections with unknown hosts (whose keys aren’t already in your known_hosts file) can go three ways.
- StrictHostKeyChecking is set to no ; OpenSSH will automatically connect to any SSH server regardless of host key status. This is insecure and not recommended, except if you’re adding a bunch of hosts after a reinstall of your OS, after which you will change it back.
- StrictHostKeyChecking is set to ask ; OpenSSH will show you new host keys and ask for confirmation before adding them. It will prevent connections from going to changed host keys. This is the default.
- StrictHostKeyChecking is set to yes ; The opposite of “no,” this will prevent you from connecting to any host that is not already present in your known_hosts file.
You can change this variable easily on the command-line by using the following paradigm:
ssh -o 'StrictHostKeyChecking [option]' user@host
Replace [option] with “no,” “ask,” or “yes.” Be aware that there are single straight quotes surrounding this variable and its setting. Also replace user@host with the username and host name of the server you’re connecting to. For example:
ssh -o 'StrictHostKeyChecking ask' email@example.com
Blocked Hosts Due To Changed Keys
If you have a server you’re trying to access that had its key already changed, the default OpenSSH configuration will prevent you from accessing it. You could change the StrictHostKeyChecking value for that host, but that wouldn’t be entirely, thoroughly, paranoidly secure, would it? Instead, we can simply remove the offending value from our known_hosts file.
That’s definitely an ugly thing to have on your screen. Luckily, our reason for this was a reinstalled OS. So, let’s zoom in on the line we need.
There we go. See how it cites the file we need to edit? It even gives us the line number! So, let’s open up that file in Nano:
Here’s our offending key, in line 1. All we need to do is hit Ctrl + K to cut out the whole line.
That’s much better! So, now we hit Ctrl + O to write out (save) the file, then Ctrl + X to exit.
Now we get a nice prompt instead, to which we can simply respond with “yes.”
Creating New Host Keys
For the record, there’s really not too much of a reason for you to change your host key at all, but if you ever find the need, you can do easily.
First, change to the appropriate system directory:
This is usually where the global host keys are, though some distros have them placed elsewhere. When in doubt check your documentation!
Next, we’ll delete all of the old keys.
sudo rm /etc/ssh/ssh_host_*
Alternatively, you may want to move them to a safe backup directory. Just a thought!
Then, we can tell OpenSSH server to reconfigure itself:
sudo dpkg-reconfigure openssh-server
You’ll see a prompt while your computer creates its new keys. Ta-da!
Now that you know how SSH works a little bit better, you should be able to get yourself out of tough spots. The “Remote Host Identification Has Changed” warning/error is something that throws a lot of users off, even those who are familiar with the command-line.
For bonus points, you can check out How To Remotely Copy Files Over SSH Without Entering Your Password. There, you’ll learn a little more about the other kinds of encryption algorithms and how to use key files for added security.