保持 SSH 端口转发连接处于活动状态

保持 SSH 端口转发连接处于活动状态

我正在通过 SSH 进行永久端口转发。基本上是

while true; do
        ssh <somewhere> \
                -R <dst-port>:localhost:<src-port> \
                -N -n -o ExitOnForwardFailure=yes
        sleep 10
done

但是,这种方式不太可靠。有时,端口根本无法转发(我不确定连接是否正确处于活动状态,但我可以在客户端上看到该过程,并且它已经运行了几个小时),有时连接肯定不再处于活动状态(因为网络接口已关闭),但超时需要很长时间(有时长达 30-60 分钟)。

我怎样才能让它更可靠?我希望超时时间大约为一分钟。


我刚刚发现这个非常相关/相似的问题。但是,第一个答案表明ExitOnForwardFailure应该可以解决它,但是我已经有了它,但是却没有(我现在可以使用ssh此选项看到正在运行的进程,但端口没有转发)。

答案1

我将这些放在 SSH 客户端config文件中:

ServerAliveInterval = 60
ServerAliveCountMax = 3

ssh或者,可以通过命令行传递这些选项-o

某些客户端可能没有这种配置控制,例如各种移动设备的微不足道的客户端。在这种情况下,仍然可以在连接到的每个服务器上进行全局配置,这当然需要服务器计算机上的权限。OpenSSHD 实现似乎没有让用户自定义服务器参数的方法(没有~/.ssh/sshd_config读取文件,可以从服务器端自定义所选参数)。

答案2

我在我的工作机器上使用 autossh 来设置远程 Web 开发:

autossh -M0 -N -R \*:8080:localhost:80 -R \*:5051:localhost:22 home

autossh 是一个程序,如果 ssh 因除“kill -9”之外的任何原因崩溃或停止,它会不断重新启动 ssh。上述命令设置了两个隧道:一个用于将我工作机器上的端口 80 转发到我家用机器上的 8080,另一个将我工作机器上的 ssh 服务器隧道传输到我家用机器。端口前面的 * 使它适用于任何主机名,而不仅仅是 localhost。不过,您可能需要在 sshd_config 上设置“GatewayPorts yes”才能使其正常工作。我的家用机器上的 ~/.ssh/config 和 /etc/hosts 中有主机,以使它更加透明。对于其他系统,需要使用 ProxyCommand (http://sshmenu.sourceforge.net/articles/transparent-mulithop.html),但是我此刻没有启动使用此命令的主机来抓取它。

〜/.ssh /配置:

Host work
    hostname localhost
    port 5051

那么就只是

autossh -M0 -t home 'ssh work'

从任何主机进行连接。

答案3

此版本会频繁向服务器发送一些数据。如果连接断开,管道迟早会断开。

while true; do
        { while true; do echo echo ping; sleep 10; done } | \
        ssh <somewhere> \
                -R <something> \
                -o ExitOnForwardFailure=yes \
                >/dev/null
        sleep 10
done

答案4

正如 Kaz 先前所引用的,该连接似乎不需要任何显式流量来保持活动状态。例如:

ssh you@there 'read ANYTHING' < $PIPE

就可以了。$PIPE 是一个命名管道,当您完成后,您将写入该管道。

好吧,让我们明确一点——$PIPE 比“读取任何内容”更复杂,值得举一个详细的例子。这是我用来在无法直接访问的网络中 rdesktop 一台机器的代码:

p_user=myself
p_bridge=me@there
p_host=192.168.xxx.yyy
p_port=9999

p_size=100%      # or: p_size=1280x1024
p_trace=stderr   # or: p_trace=null

s_trace() {  echo "$*" > /dev/$p_trace; }

PIPE=$TEMP/${0##*/}.$$
mkfifo $PIPE.0
mkfifo $PIPE.1

trap 'rm $PIPE.0 $PIPE.1' 0

# ----------------------------------------------------
ssh $p_bridge \
    -L $p_port:$p_host:3389 \
    'read CONNECT; date; read QUIT' \
  < $PIPE.1 \
  > $PIPE.0 \
  & 
# ----------------------------------------------------

# note: "type -p" is somehow required with xinit
# note: "-p -" reads password from stdin
DESKCMD="$(type -p rdesktop) -P -z -u $p_user -p - -g $p_size localhost:$p_port"

{
  echo connect >&3; read CONNECT <&4; s_trace "CONNECTED: $CONNECT"
  $DESKCMD -f    # or: xinit $DESKCMD -- :1
  echo quit >&3
} \
  3> $PIPE.1 \
  4< $PIPE.0

wait

相关内容