为什么使用端口转发时 SSH 会话的注销会挂起?

为什么使用端口转发时 SSH 会话的注销会挂起?

我使用动态 SSH 端口转发 ( -D) 和常规 SSH 端口转发 (-L-R) 来做很多不同的事情,包括为我的无线网络流量添加一层加密。我使用的命令通常如下所示:

ssh -l raam -D 9000 my-linux-server.com

启动隧道后,我将我的网络浏览器配置为使用带有端口 9000 的 SOCKS v5 代理 127.0.0.1。现在,我的浏览器中的所有流量(DNS 除外)都通过 SSH 隧道传输。

当我准备关闭隧道时(例如,当我将笔记本电脑带到另一个位置时),我只需键入“ logout”。但是,SSH 会话挂起,我必须按CTRL+c才能恢复本地提示。

为什么会发生这种情况?我该如何预防?

(我的猜测是,我通过隧道打开的连接保持打开状态,并且我的本地 SSH 客户端正在等待它们关闭,然后才给我提示。如果是这种情况,当我准备注销时,如何强制关闭所有这些连接?)

答案1

正如您所预料的,发生这种情况的原因是,如果有未完成的连接通过隧道,SSH 就不会退出。

如果您退出浏览器(以及所有其他通过端口 9000 隧道的程序),则 SSH 也应该退出。

SSH 手册页说:

当远程计算机上的命令或 shell 退出并且所有 X11 和 TCP 连接都已关闭时,会话终止。

而且我没有看到任何可以改变这种行为的选项,所以我认为你无能为力。

答案2

您可以在后台 SSH 执行以下操作:

<enter>~&

答案3

正如评论中所述,您可以使用 -f 创建仅隧道连接,但您仍然会遇到连接不会终止的问题,直到使用隧道的所有内容都退出为止。您可以使用 ~# 选项(转义序列和“磅号”)列出在注销之前在给定连接上打开的转发连接。

答案4

而不是输入exit关闭你的但留下了会议直到隧道断开连接,你实际上可以让你的 shell 直接关闭会话这会破坏隧道和外壳。

kill $PPID

您的交互式 shell 的父进程是处理您的会话的 sshd 进程。

这也适用于命令,因此它们不会挂起;

ssh -R 9000:localhost:9000 my-linux-server.com './scriptThatUsesRemotePort.sh; kill $PPID'

如果你没有$PPID环境变量,你可以使用kill `ps --no-headers -eo ppid -fp $$`

相关内容