【问题标题】:reverse ssh tunnel反向ssh隧道
【发布时间】:2012-06-06 00:42:59
【问题描述】:

我在现场有一个嵌入式设备,通过 USB 手机棒连接到互联网。为了能够访问它,我在端口 19996 上建立了一个反向 ssh 隧道,以便能够访问它。

现在我每 10 分钟重新建立一次隧道(通过 cron),以确保我几乎可以不间断地访问,即使提供商决定更改我的 IP。

现在我意识到我的进程列表已经满了

"4383 root     ssh -R 19996:localhost:22 -f -N user@host"

并且 netstat 也加载了连接。我如何确保不会发生这种情况?我一次只需要打开一条隧道,而不是 100 条。

【问题讨论】:

  • Burrow.io 是一个非常酷的工具,如果你需要的是 HTTP 或 HTTPS。免费帐户可让您创建一个隧道 (HTTP),您只需在设备中运行 curl 命令即可。它甚至会证明连接始终处于打开状态,从而无需 Cron 作业。

标签: linux ssh cron tunnel


【解决方案1】:

您可以使用 ssh 命令套接字来检查连接是否仍处于活动状态。它应该是这样的:

#!/bin/bash
if ! ssh -S mysocket -O check user@host ; then
    ssh -M -S mysocket -R 19996:localhost:22 -f -N user@host
fi

然后您可以使用关闭该特定连接

ssh -S mysocket -O exit user@host

ServerAliveInterval 设置为大于0 的值也可能是值得的,-o ServerAliveInterval=N。因为如果连接丢失,它会杀死你的隧道。

【讨论】:

    【解决方案2】:

    我编写了以下脚本,cron 每 5 分钟运行一次。 尽管我希望这可以工作,但我仍然发现连接一直不允许我从远程端进入。 回答上面的评论 - 它似乎并没有从 netstat 中消失。 我检查了 netstat,它仍然会为连接显示“ssh ESTABLISHED”,因此当我的脚本运行时,我得到“套接字似乎已连接。假设反向 ssh 隧道运行良好”的结果。 必须有更好的方法来测试远程端并获得表明它正在工作的结果?

    #!/bin/bash
    
    #$Id: ssh_reverse_tunnel.sh 14 2012-10-13 22:53:21Z root $
    
    REMOTE_USER="user"
    REMOTE_DOMAIN="domain"
    SOCKETS_USED=`netstat -p ssh | grep 'ssh ESTABLISHED' | grep -c $(host $REMOTE_DOMAIN | awk {'print $NF'})`
    
    establish_connecton() {
      echo "establishing reverse ssh tunnel connection..."
      ssh -R 12222:localhost:22 -R12223:localhost:5901 -f -N -T ${REMOTE_USER}@${REMOTE_DOMAIN} &
      echo "done."
      echo
      exit
    }
    
    if [ $(ps -ef | grep "ssh -R 12222" | grep -v grep | wc -l) == 0 ]; then
      echo "no reverse ssh tunnel connection exists."
      establish_connecton
    fi
    
    if [ "$SOCKETS_USED" -lt 1 ]; then
      echo "no reverse ssh tunnel sockets are connected. nuking stale pids and re-establishing connection"
      # check for stale pids and kill them if found.
      if [ $(ps -ef | grep "ssh -R 12222" | grep -v grep | wc -l) -gt 0 ]; then
        # stale pids exist, kill them...
        ps -ef | grep "ssh -R 12222" | grep -v grep | awk {'print $2'} | \
          while read PID; do
            echo "kill -9 $PID"
          done
      fi
      establish_connecton
    else
      echo "sockets appear connected. assuming reverse ssh tunnel is running fine."
    fi
    

    希望有人发现上述内容有用,并可以让我知道在哪里构建更多检查。

    【讨论】:

      【解决方案3】:

      我写了followiung shell script,似乎工作正常!

      #!/bin/sh
      RETVAL=`netstat | grep 'S0106b0487afe2a57'| grep -c 'ssh ESTABLISHED'`
      echo "${RETVAL} open tunnel(s)"
      if [ "$RETVAL" -lt "1" ]
        then
              echo "starting reverse ssh tunnel"
              `ssh -R 19999:localhost:22 -f -N user@host`
              echo "done"
      fi
      

      【讨论】:

      • 我使用了 RETVAL=netstat | grep '<hostname>:ssh' | grep -c 'ssh ESTABLISHED',它似乎工作正常
      【解决方案4】:

      在启动新进程后只需杀死前一个进程(按 ID)。您可以通过 ps 命令获取进程 ID。

      【讨论】:

      • 但是如果我杀死现有的,当前的 ssh 会话将被终止,对吗?如果我每 10 分钟下车就不太方便...
      • 是的,但从技术上讲还有另一个问题。在您已经运行一个进程之后,一个进程不应该能够绑定到同一个本地端口......所以只有一个应该运行,直到它被终止。如果您背靠背运行这些命令,则应该会产生错误并立即终止......所以很多进程的问题似乎不应该出现。也许这里正在发生其他事情。尝试从该框本地背靠背运行它们,看看你得到什么输出。
      • 嗯,事实上,我实际上在我的办公室电脑上做同样的事情(为我的家用电脑建立一个反向隧道),我得到的结果完全一样。在办公室里,我正在运行 Kubuntu 12.04,所以这是一个完全一样的顶级发行版......:o 但是在建立隧道时,我收到错误“警告:监听端口 19999 的远程端口转发失败”但我也可以在我的嵌入式小购买中获得此功能...但它仍然在流程列表中添加了一个流程...这是错误的... :(
      • 有没有一种方法可以检查命令绑定端口是否失败,如果失败则终止挂起进程?这样,实际上保持端口打开的进程将保持打开状态,您不会失去连接。像这里的东西:cyberciti.biz/faq/what-are-the-exit-statuses-of-ssh-command(echo $?,然后根据返回码/状态做一些事情)
      • 与此同时,我编写了一个小 bash 脚本,该脚本 grep 查找某个外国地址和“ssh ESTABLISHED”,如果我得到的连接少于 1 个,我会重新打开它。但是,我不知道如果发生动态 IP 更改,它是否会从 netstat 中消失……我认为至少状态会发生变化,对吗?
      【解决方案5】:

      使用 autossh 代替它会在断开连接时重新建立连接。尝试先在发行版的存储库中搜索,如果找不到,然后在网上搜索。

      【讨论】:

      • 问题在于我的发行版是使用 buildroot(带有busybox)自行组装的。我需要重新编译整个婴儿......如果可以的话,我更喜欢别的东西......但是很好的提示,谢谢! :)
      猜你喜欢
      • 2010-09-27
      • 1970-01-01
      • 2018-09-01
      • 2021-09-06
      • 1970-01-01
      • 2015-07-28
      • 2020-09-15
      • 2015-03-09
      • 2019-08-12
      相关资源
      最近更新 更多