ssh 实现内网穿透

 

Refer:

场景:

隧道/端口转发

xshell

  1. 在主机 B 上安装 xshell
  2. 使用 xshell 连接主机 C,新建会话,填写自己的外网主机 IP 和端口,和用户身份验证,注意重新连接需要填写。
  3. 打开日志,点击跟踪,勾选协议事件:
  4. 点击隧道,点击添加,按如下图填写转移规则
  5. 使用主机 C 访问主机 A 经过上面操作,打开新建的会话时会有如下提示

此会话 bwg 即是主机 C,在主机 C 上

ssh localhost -p 6634,按照提示输入 yes 和主机 A 的密码即可访问主机 A

主机 D 如何直接访问主机 A

在主机 C 上配置 sshd 配置转发

  1. 在主机 C 上编辑 sshd 配置文件/etc/ssh/sshd_config GatewayPorts yes
  2. 然后重启 sshd sudo systemctl restart sshd
  3. 在其它主机 D 可以直接 ssh 主机 C 的 IP(95.49.4.*) + 监听的端口(6634) 访问主机 A

保持活跃连接

不太管用呢?还需探索,如果有知道的麻烦评论赐教

目前采用后台运行自动重置连接脚本的方法

设置 保持活动状态

设置-连接-重新连接反而会导致建立过多连接,出现 ssh 卡顿或连不上。(不确定是不是这个原因)

Mobaxterm

  1. 选择 tunnel-remote port forward
  2. 参照提示填写 ip 和端口
  3. 开启密钥连接,自动重连和保持连接

xshell 开机自启动并默认打开跳板机会话

  1. 开机自启动:工具-选项-高级
  2. 默认打开会话:工具-选项-常规-启动时打开的会话

其他方法配置过程(比较繁琐,效果不好)

Refer:Linux 下 ssh 反向隧道进行内网穿透

场景一致,容易断连

ssh 反向代理实现内网穿透

公网服务器 a,公网 ip 为 IPa,开放 ssh 转发的端口 Pa,用户名 accountA

内网服务器 b,无法访问外网,用户名 account

连接内网和外网的工位机 c

一、内网服务器配置 ssh 代理

如果服务器 b 访问不了公网服务器 a 的话:

  1. 需要在工位机 c 上的 v2rayN 开启允许局域网的连接,确定代理的 socks 的端口 Pc 和内网 ip IPc

    ssh 只能走 socks 代理

  2. 服务器 b 设置代理(可选,如果需要服务器 b 下载的话)
  3. 设置服务器 b 的 ssh 代理:
mkdir ~/.ssh
cd ~/.ssh
vi config

添加以下内容,替换 IPc,Pc

Host *
    ProxyCommand nc -X 5 -x IPc:Pc %h %p

二、设置 ssh 反向代理

登录服务器 b,输入以下指令:(替换 Pa,accountA,IPa

ssh -f -C -N -R Pa:localhost:22 -o ServerAliveInterval=60 accountA@IPa

接下来输入密码

若要通过公网服务器 a 连接的话,在 a 的 shell 下:

ssh -p Pa accountB@localhost

三、保持连接

也可以直接安装 autossh

① 先设置通过公钥登录

② 新建一个脚本 reverse_ssh.sh,注意替换 Pa 和第 6 行

#!/bin/bash
while true;do
RET=`ps ax | grep "ssh -f -C -N -R Pa:localhost:22" | grep -v "grep"`
if [ "$RET" = "" ]; then
echo "restart ssh server"
ssh -f -C -N -R Pa:localhost:22 -o ServerAliveInterval=60 accountA@IPa
fi
sleep 10
done

③ 设置运行权限

chmod +x reverse_ssh.sh

④ 保持后台运行即可

报错:client_loop: send disconnect: Broken pipe

解决: 修改~/.ssh/config,注意缩进格式否则会影响生效

Host *         
         # 断开时重试连接的次数         
         ServerAliveCountMax 5          
         # 每隔5秒自动发送一个空的请求以保持连接         
         ServerAliveInterval 60

其他

  • 因为 ssh 代理只能走 socks,所以必定是走工位机的梯子服务器流量

而 v2rayN 只支持 http 代理的 pac 模式,不支持 socks 代理

  • 有时可能存在公网服务器监听转发端口进程还在,但是内网服务器已经断连的情况,可能是梯子服务器不稳定的原因

一直连接不稳定

设置内网机all_proxyrsync_proxy后连接不稳定,可能是由于 xshell 会走不稳定的梯子代理——不是这个原因

解决方法

  • xshell 开个 top 维持连接试试

  • 也可能是工位机的 ip 不固定,比如经常切换 wifi 和网线连接

​ Refer:SSh 连接失败,Socket error Event: 32 Error: 10053.

写脚本重置连接

如果监听端口失败,并且开启了断开重连,可以在公网服务器关闭 22 端口的连接进程

原因是 xshell 的 ssh 断开后,公网服务器的 sshd 还有进程占用端口进行转发

手动重置

直接写个脚本,名字可以是stu.sh,注意修改IPPort

linux_shell 自定义命令 - narjaja - 博客园

#!/bin/bash
# 输入1执行脚本  
if [ $1 = 1 ]
then
        netstat -anp | grep ssh|grep "IP\|Port" | awk -F ' ' '{len=split($7,arr,"/");for(i=1;i<len;i++){$7=arr[i];print $7}}'| xargs kill
        echo " success "
fi

然后在 .bashrc 中添加 alias 命令='执行的命令操作'

比如 alias stu='sh /home/king-key/stu.sh

然后终端输入source .bashrc命令

自动重置(最终采用)

写个脚本后台运行,一旦发现工位机的 ip 断开连接,就 kill 掉监听端口的进程

赋值 = 没空格,判断有空格

#!/bin/bash
# 内网服务器的公网ip
IP=104.xxx.xxx.xxx
# 公网服务器的端口
PORT=7777


while true;do
RET1=`netstat -anp | grep $IP| awk -F ' ' '{len=split($7,arr,"/");for(i=1;i<len;i++){$7=arr[i];print $7}}'`
PID=`netstat -anp | grep "0.0.0.0:${PORT}"| awk -F ' ' '{len=split($7,arr,"/");for(i=1;i<len;i++){$7=arr[i];print $7}}'`

ttime=`date +"%Y-%m-%d %H:%M:%S"`

if [ "$PID" = "" ]; then
        echo $ttime
        echo "not listening port"
        netstat -anp | grep ssh|grep "${PORT}\|${IP}" | awk -F ' ' '{len=split($7,arr,"/");for(i=1;i<len;i++){$7=arr[i];print $7}}'| xargs kill
        echo "restart ssh from iie"
else
        # ssh tunnel is connecting, but wrong
        # parent process id
        ppid=`ps -fp $PID |awk '{print $3}'|tail -n1`

        # if $ppid in the list of $RET1
        if [[ ${RET1} == *${ppid}* ]]; then
                :
                                # echo "success"
        else
                echo $ttime
                echo "Trying to listen port failed"
                netstat -anp | grep ssh|grep "${PORT}\|${IP}" | awk -F ' ' '{len=split($7,arr,"/");for(i=1;i<len;i++){$7=arr[i];print $7}}'| xargs kill
                echo "kill all ssh from iie"
        fi
fi
        

sleep 300
done