Get hands-on training for JIRA Software, Confluence, and more at Atlassian Summit Europe. Register now ›

.noformat pre {
overflow: auto;
.noformat {
border-width: 1px;
border-style: dashed;
padding: 5px;
margin: 10px;

If you’re a developer that deploys stuff to unix systems, then one of the most common tools you interact with is SSH. It never ceases to amaze me, in spite of this, how little developers really know about SSH.

SSH config file

The first thing any developer needs to know is that SSH has a config file that allows you to configure defaults for SSH on a host by host basis. It also allows aliases, and bash completion can use this config file to make sshing into a system much easier. This file lives under the .ssh folder in your home directory, ~/.ssh/config. Here’s a sample of things that I have in my config file.

Host home
Port 2222
User james
Host sshjump
User jamesroper
ForwardAgent yes

So I can SSH home by running ssh home and that will automatically use james as the username, as the host name, and 2222 as the port number. For details on all the configuration just read the man page, man ssh_config. You’ll see that you can configure everything including port forwarding and much more.

Jump boxes

There are a number of times when I need to SSH into a jump box to SSH to another system. The annoying thing about this is to get to a system, I need to run two commands, and scp is even more annoying because I have to copy first to the jump box, then to the remote system.

Enter ProxyCommand. The proxy command config option allows you to specify a command that SSH will run first in order to establish the connection to the remote system, and then it will pipe its communication through that command. Combined with nc on the jump box end to create a TCP connection to the your destination host, this can be used to tunnel an SSH connection through another SSH connection. The configuration in the SSH config file looks like this:

Host *
ProxyCommand nohup ssh sshjump nc -w1 %h %p

The other thing I’ve made use of here is wildcards, and the ability for SSH to substitute the host name and port number for the particular host into option values. Now I can run ssh, and the SSH connection will be piped through an ssh connection to sshjump, which is an alias defined above as I can also scp directly.

Disabling strict host key checking

If you work with cloud services a lot (as I do), you might be in a situation where the host key for systems keeps changing. This causes problems with SSH’s host key checking, where whenever SSH encounters a host key, it stores it in the ~/.ssh/known_hosts file, and then if you SSH again later and the key has changed, it throws the following error:

Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
Please contact your system administrator.
Add correct host key in /Users/jroper/.ssh/known_hosts to get rid of this message.
Offending key in /Users/jroper/.ssh/known_hosts:28
RSA host key for has changed and you have requested strict checking.
Host key verification failed.

SSH has an option that can fix this, StrictHostKeyChecking. I can configure SSH to automatically accept whatever key it’s given, using the StrictHostKeyChecking configuration option. This means I no longer have to worry about manually deleting the line from my known_hosts file, but the error message still appears, it’s just that nothing is done about it.

There is still an issue in that the big warning is still displayed, it just doesn’t block you from accessing it. If you have hashing known host keys turned off (HashKnownHosts no), then a simple sed script, invoked using the LocalCommand option, can be used to remove the key from the known_hosts file after it’s automatically added, and this will prevent there from ever being a conflict:

StrictHostKeyChecking no
PermitLocalCommand yes
LocalCommand sed -Eni '/^%h/!p' ~/.ssh/known_hosts

The sed command has been tested under BSD sed (on OSX), for GNU sed I’m guessing the -E opiton will have to be replaced with -r. If however you are on a system that hashes known hosts, you’ll have to write a shell script that parses the known hosts file and computes the hash of the host you are sshing to, and then removes the correct key. Such a script is beyond the scope of this blog post, but an example of how to parse it in perl can be found here.

Fresh ideas, announcements, and inspiration for your team, delivered weekly.

Subscribe now

Fresh ideas, announcements, and inspiration for your team, delivered weekly.

Subscribe now