Using SSH to Access Multiple Machines at a Single Domain
This is a neat trick for accessing multiple servers via a single domain name or IP(Internet Protocol) address using ssh. If you aren’t using ssh or if you don’t understand anything in that last sentence, this ain’t something you care about.
The problem
I am responsible for running and maintaining four computers on a daily basis: my home office computer, my university office computer, my home web server, and my notebook. All four run on Linux (Ubuntu ‘Dapper’ or ‘Edgy’ depending on the box). When I begin work at one of these computers, I have a script that updates my working documents, desktop, and email, so that the computers always have the same content. My office computer also serves as a backup machine: an automated script backs up my user and web space every four hours using rsback.
This data is moved around using rsync and ssh. I access the computers by IP number or domain name—say something like 145.389.111.994 for work and my.personaldomain.org for my house (these are both made-up examples). So to access files on my work computer I would type ssh 145.389.111.994
and at home I would type ssh my.personaldomain.org
.
The problem is at home. The domain name my.personaldomain.org doesn’t actually point at any computer, it points at a router through which all our home computers access the Internet. So when I type ssh my.personaldomain.org
, I am actually getting the router not any single computer. What I need is some way of getting through to individual machines on the other side!
What I did initially was set each computer to listen for ssh on a different port (you do this by editing the port setting in /etc/ssh/sshd_config
). So my home office computer might listen on port 567, my home web server on port 745, and my notebook on port 907 (the port numbers are not important and are again make-believe). The idea was that I could then ssh into each machine by specifying the port number I wanted using the -p
option: i.e. ssh -p 745 my.personaldomain.com
would bring me to my web server; ssh -p 567 my.personaldomain.org
would bring me to my home office computer.
This would work fine except for a problem with ssh. When you use ssh in Linux, it checks the remote host name against a list in a file called known_hosts
(i.e. $HOME/.ssh/known_hosts
). If the host isn’t listed there there, it asks you if you want it added; if it is already there, but actually refers to another computer behind the router, you will be either refused to access the remote host or asked that you want to change or ignore the listing in the known_hosts
file. It is possible to turn this feature off, but then you leave yourself vulnerable to a security breach known as the man in the middle attack or DNS spoofing if it is on, testing against known_hosts
will either prevent you from accessing the remote machine or ask questions that require human intervention (and hence rule out the use of automated scripts).
What this means in practice is that you can’t ssh to different computers at a single IP address by simply distinguishing the machines by port. Whichever computer you first contact will become the default listing in your known_hosts
file; if you then try to contact other computers at the same address, the security settings would kick in and an error will be thrown. As far as I can tell, there is no way of distinguishing between otherwise identical IP addresses by port number within in known_hosts
.
Officially, at least.
The Solution
This is a common problem and there are a variety of possible solutions, particularly involving changes to the ssh configuration file. Since my scripts (which use the ssh -p
option) already exist, however, I wanted to change the default behaviour of known_hosts
rather than change other aspects of my configuration.
The neatest solution I saw to this problem was posted this past September on linuxquestions.org. Since this was the only place I saw this solution, it is worth reproducing here. The solution depends on the apparent fact that known_hosts
only objects to overwriting existing entries. It apparently doesn’t mind containing more than one reference to the same IP address. And as long as known_hosts
contains a valid entry for the address you are visiting, it will let you through without checking whether it has more than one valid listing. The trick, then, is to get more than one valid reference to the same IP number into the same known_hosts
file.
The basic way to do this is cut-and-paste (the following assumes you are starting from scratch, if you have an already existing known_hosts
file you want to keep, start at step 2).
- Go to one of the servers you want to access using ssh. Accept this entry into your
known_hosts
file when asked. - Change the name (move) the existing
known_hosts
so it is no longer recognised by ssh:mv known_hosts known_hosts.first
- Go to the next computer you want to access using ssh. Accept this entry your (new)
known_hosts
file when asked. - Copy the contents of the new
known_hosts
file into the old:cat known_hosts >> known_hosts.first
- Remove the new
known_hosts
file and rename (move) the original back to its old name:rm .ssh/known_hosts
andmv known_hosts.first known_hosts
- Repeat the above for every computer you need to access at the same IP address.
I’ve tried this out on all my machines, and it works like a charm.
Comment [8]
gatogordo (Thu Jun 7, 2007 (20:52:14)) [PermLink]: perfect. thanks…gg
Gabriel Menini (Fri Jun 22, 2007 (15:44:58)) [PermLink]: Thanks for the tip, man.
Han-Kwang (Tue Aug 21, 2007 (15:11:46)) [PermLink]: It doesn’t work over here. However, the solution on http://wiki.mandriva.com/en/Docs/SysAdmin/Networking/SSH does work. Summary: put an entry for each computer behind the same IP in your ssh_config:
Host my1
Hostname my.mydomain.com
Port 567
HostKeyAlias = my1
CheckHostIP = noThen use “ssh my1” and it will connect to the right one.
mauro (Wed Oct 10, 2007 (09:38:08)) [PermLink]: thanks Han-Kwang!!!
Håkan Johansson (Thu Oct 18, 2007 (01:05:05)) [PermLink]: Great thanks for the information. I was tearing my hear over this problem before coming here.
C.Day (Thu Apr 24, 2008 (01:07:23)) [PermLink]: You’ve provided invaluable insight. My sincere thanks!
Adriano Krauthein (Thu May 8, 2008 (14:22:43)) [PermLink]: My solution is to point to inexistent known_hosts, like:
# ssh -o “UserKnownHostsFile /dev/null”
Pontus (Sat Sep 13, 2008 (16:32:20)) [PermLink]: Another option for people like me who are too lazy to cut-and-paste:
ssh -o UserKnownHostsFile=z user@host
...
cat z >> ~/.ssh/known_hostsVery simple to repeat for many hosts.