我有一台带有 2 个网络接口的服务器。
由于 NAT 防火墙的限制,它会建立一个到 Internet 上的服务器的 SSH 隧道:
ssh -fNTMS "/tmp/tunnel.socket" host;
ssh -S "/tmp/tunnel.socket" -O forward -R "0:localhost:22" placeholder
通常它通过有线 1GB 以太网连接 (eth0) 进行连接;但它不可靠,因为它是在办公室里,人们到处移动东西,电缆会“掉下来”(不幸的是我不能使用胶水)。
它还具有移动 4G 互联网连接 (eth1),速度较慢且价格较高。
为了确保隧道仍然正常工作,我定期使用以下-O check
命令:
ssh -S "/tmp/tunnel.socket" -O check placeholder
Master running (pid=3430)
echo $?
0
如果-O check
失败,套接字将被关闭(通过-O exit
),并且将建立新的 SSH 连接。
如果故障是由于eth0网线“掉出来”造成的,那么Linux会自动使用eth1。
这确实非常有效。
但是,当 eth0 再次恢复时,我想切换回它。
所以我在想,运行时-O check
,我可以查看隧道当前是否正在使用 eth1 (这个问题的重点),如果 eth0 回来了,则重新连接。
路线信息:
ip route
default via 192.168.1.1 dev eth0 proto dhcp src 192.168.1.225 metric 100
default via 192.168.2.1 dev eth1 proto dhcp src 192.168.2.241 metric 200
请注意 eth1 的度量为 200,因此 eth0 在工作时具有优先权。
我找不到任何东西/proc/3430/
我可以列出与以下的连接lsof
:
lsof -ai -p 3430 -n -P
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ssh 3430 craig 3u IPv4 69362 0t0 TCP 192.168.1.225:43878->1.1.1.1:22 (ESTABLISHED)
并且netstat -tpln
在列出套接字时不显示接口。
答案1
一个可能的解决方案(我正在使用它)是在每一侧创建一个新的界面。然后通过-w
的开关将它们连接起来ssh
。
首先,您应该使用正确的指标设置两条本地默认路由。每当发生变化(eth0 向上或向下)时,您都会失去连接,但这不是问题(继续阅读)。
在每台服务器上创建tun设备并让用户访问它们。就像(你必须交换另一边的地址):
sudo ip tuntap add dev tun3 mode tun user myuser group mygroup
sudo ifconfig tun3 10.9.0.1 pointopoint 10.9.0.2 netmask 255.255.255.255
那么,如果你这样做
ssh -w3:3 myuser@remote_host
您将通过ssh
隧道连接这两个接口,并且能够对它们执行 ping 操作。如果您失去连接,没问题,设备tun
将等待,直到您重新建立连接并恢复。
从此时起,您可以通过“稳定”链接连接远程主机,该链接将根据需要使用 eth0 或 4G,但保留地址 (10.9.0.1/10.9.0.2)。
相反,ssh
我建议您将autossh
(和键)与-M
标志(监视器)一起使用。它将检测到链接丢失并重新连接。
这确实非常接近成熟的 VPN(您可以将路由、策略、防火墙等应用到 tun 接口),但它可以在ssh
您熟悉的老旧 VPN 上运行。
答案2
我很愚蠢......隧道使用具有最低指标的默认接口,它对单个接口并不厌倦。
一旦 eth0 恢复,数据就会通过 eth0 发送。
这会导致连接实际上失败,我需要使用ServerAliveInterval
/ServerAliveCountMax
来通知并关闭连接。