问题是这样的:我尝试在不同时间通过 SSH 访问至少可以从 3 个不同网络(有时直接访问,有时通过代理)访问的系统。
直接连接比通过中间主机连接更快、更可靠,而中间主机又比通过一般互联网连接更快、更可靠,因此我希望 SSH 以优先顺序尝试以 3 种不同的方式进行连接,选择第一个成功的。
显然,它们都是同一台机器,所以我不想根据我的连接位置手动在 3 个不同的别名之间进行选择。
但是,我找不到任何机制来解决这个问题。到底有没有可能做到这一点?
如果不是,人们在这种情况下通常会做什么?
答案1
不要使用别名进行ssh
连接!使用正确ssh_config
的~/.ssh/config
.它有一些真正强大的功能。
假设您可以识别自己位于哪个网络中。例如使用您的 IP,可以使用hostname -I
.那么让我们写一些配置:
# 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
答案2
.bashrc
您可以在shell 的配置文件或任何其他配置文件中存储 shell 别名或函数。例如,对于 Bash 别名:
alias my_ssh="
ssh mehrdad@"IP1 ||
ssh tomas@IP2 ||
ssh tomas@IP3
"
然后调用别名:
my_ssh
如果 IP1 失败,则||
执行第二条命令。如此,现在又出现了 IP3。
我没有测试过这个,但应该没问题。或者至少展示了一种方法。
有关代理等 SSH 选项,请参阅man ssh
。
答案3
可能有多种解决方案,其中一些比其他解决方案更好,并且忽略安全影响或基础设施(未知)限制:
- 做一个 SSH 反向隧道(一个丑陋的黑客);
- 在 OSPF 或 BGP 的帮助下设置任播,并 sshing 到任播 VIP;
- 远程计算机建立 IPsec 隧道 - 无需代理;
- 通过 Tor 进行通信
- 使用当前地址更新站点/页面/Redis/MySQL 服务器,以及获取它的 ssh 脚本;
- 使用HAProxy;
- 动态 DNS。
答案4
这个函数可能有效,但如果托马斯的别名有效,我认为这是一个更好的解决方案。
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
}