How to use the same SSH alias with multiple host addresses/ports/etc.?
Here’s the problem: I’m trying to SSH into a system that is accessible from at least 3 different networks—sometimes directly, sometimes via a proxy—at different times.
Connecting directly is far faster and more reliable than connecting via an intermediate host, which is again far faster and more reliable than connecting over the general internet, so I would like SSH to attempt to connect in 3 different ways in a prioritized fashion, picking the first that succeeds.
They’re all the same machine, obviously, so I don’t want to keep having to manually choose between 3 different aliases depending on where I’m connecting from.
However, I can’t find any mechanism for solving this. Is it possible to do this at all, or no?
If not, what do people generally do in such a situation?
You can store a shell alias or a function in your .bashrc
or whatever else is your shell’s config file. For example, for a Bash alias:
alias my_ssh="
ssh mehrdad@"IP1 ||
ssh tomas@IP2 ||
ssh tomas@IP3
"
Then call the alias:
my_ssh
And if IP1 fails, ||
makes the second command execute. And so it goes again, now with the IP3.
I’ve not tested this, but it should be ok. Or at least shows a way.
For SSH options like proxies, see man ssh
.
This function may work, but if Tomas’s alias works I think that’s a better solution.
autossh () {
publicip="11.11.11.11"
privateip="10.10.10.100"
proxyhost="10.10.10.10"
proxyport="9001"
ssh -o ConnectTimeout=10 $1@$privateip 2> /dev/null && exit 0
if [ $? -ge 1 ]; then
ssh -o ConnectTimeout=10 $1@$publicip -o "ProxyCommand=nc -X connect -x $proxyhost:$proxyport %h %p" 2> /dev/null && exit 0
if [ $? -ge 1 ]; then
ssh -o ConnectTimeout=10 $1@$publicip 2> /dev/null && exit 0
if [ $? -ge 1 ]; then
echo "I think your node is down"
fi
fi
fi
}
There can be several solutions, some better than other, and ignoring security implications, or infra-structure (unknown) limitations:
- doing an SSH reverse tunnel (an ugly hack);
- setting up anycast with the help of OSPF or BGP, and sshing to a anycast VIP;
- the remote machine establishing an IPsec tunnel – without the proxy;
- communicating via Tor
- updating a site/page/Redis/MySQL server with the current address, and your ssh script fetching it;
- using HAProxy;
- dynamic DNS.
Do not use aliases for ssh
connections! Use a proper ssh_config
in ~/.ssh/config
. It has some truly powerful features.
Lets say you can identify in which network you are. For example using your IP, which can be pulled for example using hostname -I
. So lets write some configuration:
# in network1 I am getting ip from "10.168.*.*" and I need to connect through proxy
Match Host myalias Exec "hostname -I | grep 10.168."
Hostname real-host-IP
ProxyCommand ssh -W %h:%p proxy-server
# in network2 I am getting IP from "192.168.*.*" and I do not need a proxy
Match Host myalias Exec "hostname -I | grep 192.168."
Hostname real-host-IP
# in network3 I am getting something else