我有一个关于 SSH 反向隧道的问题。
我有一台安装了 sshd 的 Ubuntu 服务器。
我从远程计算机打开 SSH 反向隧道。在该计算机上,每次隧道中断时都会重新启动连接。
每当打开隧道时,我在 SSH 服务器上使用时可以看到两个连接netstat
。一个连接正在监听内部服务器端口。另一个正在监听外部端口。后者是 SSH 隧道。
例如:
给定 203.0.113.10:我的 SSH 服务器和 10.34.23.12 我的远程 PC,5000 是我想要访问的远程 PC 上的端口
ssh -R 1122:localhost:5000 [email protected]
现在服务器端我有两个监听连接,如下所示
tcp6 0 :::1122 :::* LISTEN
tcp6 0 0 203.0.113.10:22 10.34.23.12:62734 ESTABLISHED
我使用/运行nc
来自服务器的命令来检查隧道是否正常工作
nc -z -v -w5 127.0.0.1 1122
有时会发生外部连接中断的情况,因此我的netstat
输出将是
`tcp6 0 0 203.0.113.10:22 10.34.23.12:62734 ESTABLISHED`
有没有办法检查哪个隧道没有外部端口监听?
我的意思是,有没有办法检查我的 1122 端口何时关闭?
我的解决方案是终止绑定到没有任何外部端口的隧道的 sshd 进程 (10.34.23.12:62734)。问题是我在这台机器上还有另一个我不想终止的 SSH 隧道,所以这killall sshd
不是一个选择。
谢谢你!
编辑1:
可能的解决方案:netstat -lptun 命令(以及 Paul 建议的 netstat -pant)实现了我需要的绑定,以尝试解决此问题。现在我正在生产中测试此解决方案。
#!/bin/sh
for pid in `lsof -i -n | egrep '\<ssh\>' | awk '{print $2}'`; do
foundpid="$(netstat -lptun | grep :::11 | grep $pid)"
if [ -z "$foundpid" ]
then
echo PID does not have any external port, killing the pid $pid
kill $pid
fi
done
答案1
“反向”隧道是什么意思?
-R 参数指的是远程发起的隧道,而不是指的是本地发起的隧道的 -L 参数。
因此,从 SSH 客户端的角度来看,-R 参数将监听远程端(即 SSH 服务器)的流量。当运行 SSH 服务器的计算机在指定端口(1122)上接收流量时,该计算机将通过 SSH 软件发送该信息。具体来说,它将通过 SSH 隧道发送该信息。当信息通过 SSH 隧道发送时,它会像所有 SSH 流量一样被加密。此外,还会在该信息中添加一条小注释,即(此处解释为)“将流量发送到本地主机端口 5000”。
当 SSH 隧道另一端的流量(在本例中,我们现在讨论的是运行 SSH 客户端的计算机)接收到流量时,它会看到有关流量将流向何处的说明。然后该计算机到达本地主机端口 5000。这是解析“localhost”主机名的时间点。因此,在本例中,“localhost”将指 SSH 客户端。(相反,如果您改用 -L,则使用“localhost”仍然会被隧道上接收流量的终端解释,因此短语“localhost”将被 SSH 服务器解释。)
现在,最好的办法是找出隧道不断崩溃的原因。我通常使用 -L(本地)隧道,但在决定使用之前(有时)我已经忽略了它们很多天,而且它工作得很好。我推测隧道可能在任一端崩溃。检查两端的日志。您可能需要查看 OpenSSH 的文档,看看是否存在您正在处理的某种超时问题。
如果您想通过终止 sshd 并重新启动来解决问题(而不是解决问题),您可以这样做。如上所述,您不想使用,killall sshd
因为可能还有另一个 sshd 连接。您可以尝试pkill
消除任何连接到 203.0.113.10(或者是 10.34.23.12?)或端口号(1122)的程序,但同样,这可能会导致一些误报。您确实有一种更安全的方法来解决这个问题;它甚至涉及您建议的重新启动服务器的相同方法。
您可以让 sshd 使用自定义配置文件(-f configuration file
),或者您可以在命令行上指定配置信息(使用-o
)。例如:
sshd -o PidFile /var/run/sshd-remPC-tunnel.pid
(此外,您还可以在该命令行中包含其他所需的选项。)
当您启动 sshd 时,这会将进程 ID 号放入该文件中。然后,您可以:
kill $( cat /var/run/sshd-remPC-tunnel.pid )
(注意:您可能需要处理权限。为了让我的答案简单一点,我故意不关心这个。确保sshd
可以创建文件,并且您可以cat
在需要时成功创建它kill
。运行测试,并进行您需要的任何更改。)
注意:您可能不想每 5 分钟自动重启隧道(以自动修复问题)。因为如果您确实有一个成功的连接,这会破坏成功的连接。所以我想这应该是手动完成的事情。