使用SSH反向隧道实现内网穿透

没有公网 IP?内网服务器成笼中凤凰?果断穿透一波! 手头上有三台机器, 记号如下:

记号位置地址账户
A 位于公网 a.site usera
B 位于 NAT 之后 localhost userb
C 位于 NAT 之后 localhost userc

 

操作

  1. 在机器 A 上:
    • 设置 sshd 设置文件 /etc/ssh/sshd_configGatewayPorts yes
    • sudo systemctl restart sshd
  2. 在机器 B 上: 创建 SSH 密钥, 上传至 A:

    1
    2
    ssh-keygen -t 'rsa'
    ssh-copy-id usera@a.site

     

    一路回车即可.
    • 如果仅作测试, 直接键入命令

      1
      autossh -M 6777 -NR 6766:localhost:22 usera@a.site -i /path/to/id_rsa

       

      即可, 但该命令会在前端等待. 如果需要不间断运行地置于后台, 可使用 nohup 命令:

      1
      nohup autossh -M 6777 -NR 6766:localhost:22 usera@a.site -i /path/to/id_rsa >/dev/null 2>&1 &

       

        其中的 6777 貌似表示守护进程, 也就是如果 6766 端口的进程挂掉之后会导致 autossh 再次开启 (所以可能导致 kill 不掉进程), 如果改为 0 则表示没有守护进程.
    • 如果希望作为系统服务并开机启动, 需进行如下操作:
      1. 编辑文件 /etc/systemd/system/autossh.service,

        autossh.service
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        [Unit]
        Description=autossh ssh
        After=network-online.target

        [Service]
        Environment="AUTOSSH_GATETIME=0"
        ExecStart=/usr/bin/autossh -M 0 -o "ExitOnForwardFailure=yes" -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -NR 6766:localhost:22 usera@a.site -i /path/to/id_rsa

        [Install]
        WantedBy=multi-user.target

         

      2. 一通令之生效的操作:

        1
        2
        3
        4
        sudo systemctl daemon-reload
        sudo systemctl enable autossh
        sudo systemctl start autossh
        sudo systemctl status autossh

         

     
    • *.service 文件中需要写绝对路径
    • systemctl enable 表示设置服务为自动启动

开耍

  • A 连 B: ssh -p 6766 userb@localhost
  • C 连 B: ssh -p 6766 userb@a.site
  • 反向连接时指定动态端口转发(机器 C): ssh -p 6766 -qngfNTD 7677 userb@a.site

问题

  • 防止超时断开:
    • 在 B 和 C 的/etc/ssh/ssh_config后面加上: ServerAliveInterval 60
    • 在 A 机的/etc/ssh/sshd_config后面加上: ClientAliveInterval 60
  • 少数情况下, 问题会出在 ssh 的认证上, 可能需要下列操作:
    • 修改文件 /etc/ssh/ssh_config:
      1
      2
      3
      GSSAPIAuthentication no
      GSSAPIDelegateCredentials no
      StrictHostKeyChecking no

除了利用 autossh 作为反向代理工具, 强大的 ssh 自身就可以实现正向代理以及反向代理. 下面摘自 SSH隧道与端口转发内网穿透.

  • -L port:host:hostport: 将本地机(客户机)的某个端口转发到远端指定机器的指定端口. 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同时远程主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
  • -R port:host:hostport: 将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口. 远程主机上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转向出去, 同时本地主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有用root 登录远程主机才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
  • -D port: 指定一个本地机器「动态的」应用程序端口转发. 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 根据应用程序的协议可以判断出远程主机将和哪里连接. 目前支持 SOCKS4 协议, 将充当 SOCKS4 服务器. 只有 root 才能转发特权端口. 可以在配置文件中指定动态端口的转发
  • -p: 指定登录端口
  • -f: 后台认证用户 / 密码, 通常和 -N 连用, 不用登录到远程主机
  • -N: 不执行远程命令
  • -q: 进入安静模式
  • -C: 压缩数据传输
  • -g: 在 -L/-R/-D 参数中, 允许远程主机连接到建立的转发的端口, 如果不加这个参数, 只允许本地主机建立连接

常用的 SSH 隧道操作:

  • 正向代理: ssh -C -f -N -L listen_port:DST_Host:DST_port user@Tunnel_Host
  • 反向代理: ssh -C -f -N -R listen_port:DST_Host:DST_port user@Tunnel_Host
  • 动态转发: ssh -C -f -N -D listen_port user@Tunnel_Host

为保持长时间连接, 同 autossh 的参数, ssh 可附加的参数有: -o TCPKeepAlive=yes-o ServerAliveInterval=30-o ServerAliveCountMax=3 等.

参考

posted @ 2017-10-21 18:21  木易修  阅读(731)  评论(0编辑  收藏  举报