我下班时使用SSH隧道来绕过各种隐性防火墙(我的老板没关系:))。问题是,一段时间后,ssh连接通常会挂起,并且隧道断开。
如果我至少可以自动监视隧道,则可以在挂起隧道时重新启动它,但我什至没有想办法。
可以告诉我如何防止ssh连接挂起的用户的加分点,当然!
我下班时使用SSH隧道来绕过各种隐性防火墙(我的老板没关系:))。问题是,一段时间后,ssh连接通常会挂起,并且隧道断开。
如果我至少可以自动监视隧道,则可以在挂起隧道时重新启动它,但我什至没有想办法。
可以告诉我如何防止ssh连接挂起的用户的加分点,当然!
Answers:
听起来您需要autossh。这将监视ssh隧道并根据需要重新启动它。我们已经使用了两年了,它似乎运作良好。
autossh -M 20000 -f -N your_public_server -R 1234:localhost:22 -C
有关-M参数的更多详细信息,请参见此处
autossh
?
autossh -f -nNT -i ~/keypair.pem -R 2000:localhost:22 username@myoutsidebox.com
您可能会注意到,我使用-nNT设置了此设置,该设置不会创建远程终端,因此我可以将autossh置于后台,并使用-i选项让SSH使用.pem文件。如果您要一直保持连接打开,我绝对建议您进行额外的设置。
-M
参数:bugs.debian.org/cgi-bin/bugreport.cgi?bug=351162
所有有状态的防火墙在一段时间内都没有看到该连接的数据包后会忘记连接(以防止状态表充满连接,而两端都死了而不关闭连接)。大多数TCP实现会在很长一段时间后发送keepalive数据包,而不会听到对方的声音(2小时是一个常见值)。但是,如果有状态防火墙在发送keepalive数据包之前忘记了连接,那么长寿但空闲的连接将消失。
如果是这种情况,解决方案是防止连接变为空闲。OpenSSH具有一个称为ServerAliveInterval的选项,该选项可用于防止连接空闲太长时间(作为奖励,即使连接处于空闲状态,它也会检测对等端何时较早死亡)。
在您自己的Mac或Linux计算机上,配置ssh使服务器ssh每3分钟保持活动状态。打开一个终端,然后将您不可见的.ssh放入家中:
cd ~/.ssh/
然后使用以下命令创建一个1行配置文件:
echo "ServerAliveInterval 180" >> config
您还应该添加:
ServerAliveCountMax xxxx (high number)
默认值为3,因此ServerAliveInterval 180将在9分钟(ServerAliveInterval指定的3分钟间隔中的3分钟)后停止发送。
ServerAliveInterval 180
给我们6分钟?直觉使我尝试这样:180/60 == 3
。那么,是否ServerAliveInterval
可以30秒的倍数工作?
我使用以下Bash脚本在上一个死亡时继续产生新的ssh隧道。当您不想或无法安装其他软件包或使用编译器时,使用脚本非常方便。
while true
do
ssh <ssh_options> [user@]hostname
sleep 15
done
请注意,这需要一个密钥文件来自动建立连接,但是autossh也是如此。
Systemd非常适合于此。
创建一个/etc/systemd/system/sshtunnel.service
包含以下内容的服务文件:
[Unit]
Description=SSH Tunnel
After=network.target
[Service]
Restart=always
RestartSec=20
User=sshtunnel
ExecStart=/bin/ssh -NT -o ServerAliveInterval=60 -L 5900:localhost:5900 user@otherserver
[Install]
WantedBy=multi-user.target
(修改ssh命令以适合)
sshtunnel
因此请确保该用户首先存在systemctl enable sshtunnel
将其设置为在启动时启动的问题systemctl start sshtunnel
立即开始2018年1月更新:某些发行版(例如Fedora 27)可能使用SELinux策略来阻止从systemd init使用SSH,在这种情况下,将需要创建自定义策略以提供必要的豁免。
systemd
系统。如果使用,Restart=on-failure
则手动终止SSH客户端将不会导致系统成功重启,因为SSH客户端成功退出。
ExecStart
,例如以构建ssh
参数列表,请进行基本检查等,然后像这样从脚本中调用它exec /bin/ssh -N ...
。这是我的命令:exec /bin/ssh -N -oExitOnForwardFailure=Yes -oTCPKeepAlive=no -oServerAliveInterval=5 -oServerAliveCountMax=6 -i "${LOCAL_PRIVATE_KEY}" -L "${TUNNEL_INLET}:${TUNNEL_OUTLET}" "${REMOTE_USER}@${REMOTE_MACHINE}"
其中,TUNNEL_INLET="127.0.0.1:3307"
和TUNNEL_OUTLET="127.0.0.1:3306"
在我看来,您肯定误解了ServerAliveCountMax。据我了解文档,这是在不终止连接的情况下无法应答的服务器活动消息的数量。因此,在类似我们此处讨论的情况下,将其设置为高值只会确保不会检测到并终止挂起的连接!
只需设置ServerAliveInterval就足以解决防火墙忘记连接的问题,而将ServerAliveCountMax设置为低电平将使始发端能够注意到失败并在连接失败时终止。
您想要的是,1)在正常情况下使连接永久保持打开状态,2)检测到连接失败并在发生故障时退出发起方,3)每次重新发出ssh命令退出(您的操作取决于平台,Jawa建议的“ while true”脚本是一种方法,在OS XI上实际设置了启动项)。
ServerAliveInterval
如果隧道问题是由过期的NAT会话生成的,请始终使用SSH选项。
如果连接完全中断,请始终使用重生方法,此处至少有三个选项:
while true do ssh ...; sleep 5; done
)不会删除sleep命令,ssh
可能会很快失败,并且您将重新生成太多进程/etc/inittab
,要访问在NAT之后在另一个国家/地区发货和安装的盒子,而无需将端口转发到盒子,则可以对其进行配置,以创建一条回送给您的ssh隧道:
tun1:2345:respawn:/usr/bin/ssh -i /path/to/rsaKey -f -N -o "ServerAliveInterval 180" -R 55002:localhost:22 user@publicip 'sleep 365d'
Ubuntu上的upstart脚本,该脚本/etc/inittab
不可用:
start on net-device-up IFACE=eth0
stop on runlevel [01S6]
respawn
respawn limit 180 900
exec ssh -i /path/to/rsaKey -N -o "ServerAliveInterval 180" -R 55002:localhost:22 user@publicip
post-stop script
sleep 5
end script
或始终使用两种方法。
我用这个解决了这个问题:
编辑
~/.ssh/config
并添加
ServerAliveInterval 15
ServerAliveCountMax 4
根据ssh_config的手册页:
ServerAliveCountMax
Sets the number of server alive messages (see below) which may be
sent without ssh(1) receiving any messages back from the server.
If this threshold is reached while server alive messages are
being sent, ssh will disconnect from the server, terminating the
session. It is important to note that the use of server alive
messages is very different from TCPKeepAlive (below). The server
alive messages are sent through the encrypted channel and there‐
fore will not be spoofable. The TCP keepalive option enabled by
TCPKeepAlive is spoofable. The server alive mechanism is valu‐
able when the client or server depend on knowing when a connec‐
tion has become inactive.
The default value is 3. If, for example, ServerAliveInterval
(see below) is set to 15 and ServerAliveCountMax is left at the
default, if the server becomes unresponsive, ssh will disconnect
after approximately 45 seconds. This option applies to protocol
version 2 only.
ServerAliveInterval
Sets a timeout interval in seconds after which if no data has
been received from the server, ssh(1) will send a message through
the encrypted channel to request a response from the server. The
default is 0, indicating that these messages will not be sent to
the server. This option applies to protocol version 2 only.
ExitOnForwardFailure yes
是其他建议的好辅助。如果它已连接但无法建立端口转发,则对您来说就像没连接一样毫无用处。
由于autossh
不能满足我们的需求(如果第一次尝试无法连接到服务器,就会出现错误),因此我们编写了一个纯bash应用程序:https : //github.com/aktos-io/link-与服务器
默认情况下,它为服务器上NODE的sshd端口(22)创建反向隧道。如果您需要执行其他任何操作(例如转发其他端口,通过连接发送邮件等),则可以放置脚本on-connect
和on-disconnect
文件夹。
watch
命令在连接上生成虚拟命令以使其“处于活动状态”watch -n1 60 echo "wiiiii"
。除非网络断开或您不使用它,否则隧道不会消失。