IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    使用SSH反向隧道进行内网穿透

    bear发表于 2016-10-29 06:42:54
    love 0

    1,前提条件

    环境 系统类型 本地用户 SSH服务端口
    A机位于公司的NAT网络 安装在VMware里的Debian 8 64bit虚拟机 userA 22
    B机是一台有公网IP的VPS CentOS 6 64bit userVPS 1022
    C机位于家庭的NAT网络 Windows系统 – –

    实现目的:使得位于家庭NAT网络内的C机,可以SSH访问位于公司NAT网络内的A机。

    2,原理分析
    这里先讲向SS反向隧道的原理,如果你对原理不感兴趣,可以跳过这一节。

    $ ssh -p 22 -qngfNTR 6766:127.0.0.1:22 usera@VPS的IP  #回车以后没有反应是正常的,隧道已经建立
    

    命令解析:
    从(位于本地NAT网络里的)本机访问VPS,建立一条SSH隧道(本机的随机端口到VPS的22端口)
    同时建立了一条反向隧道,将VPS上的6766端口转发到本机的22端口。

    然后,就可以从VPS的6766端口访问本地的22端口了

    $ ssh -p 6766 userA@127.0.0.1  #从SSH访问位于NAT网络里的linux机器
    

    从SSH访问位于本地NAT网络里的linux机器,这里的userA当然是本地NAT网络里的linux机器用户啦。

    这样做有一个问题,那就是,由本地建立的SSH连接是会超时关闭的,如果连接关闭,隧道无法维持,那么VPS就无法利用反向隧道访问本地NAT网络了,为此我们需要一种方案来提供一条稳定的SSH反向隧道,于是autossh就派上用场了;

    另外有个问题是,如果本地的Linux系统重启,那么autossh建立的隧道仍然会失效。所以这里我们采取的做法是:
    1,将本地Linux系统的public key发给VPS,建立信任机制,这样,本地Linux系统可以无需VPS的密码而建立一条SSH隧道;
    2,将autossh写入系统服务,使之在开机时可以自动建立SSH隧道。

    知道了原理以后,接下来开始实际的操作步骤。

    3,VPS(B机)的操作

    $ vim /etc/ssh/sshd_config  #打开如下选项
    GatewayPorts yes
    
    $ /etc/init.d/sshd reload
    

    4,A机的操作
    前面说了,A机位于公司内部NAT网络内,是一台安装在VMware Workstation Player里的Debian 8 64bit虚拟机。

    $ sudo apt-get install autossh openssh-server
    

    配置A机可以免密码登陆到VPS(B机)
    具体方法为将A机的公钥发给VPS(B机),这样A机开机时就可以自动建立一条到VPS的SSH隧道

    $ su - userA    #这步可省略,但需要确保以下命令是在A机上以userA用户的身份运行的
    
    $ ssh-keygen -t rsa    #连续三次回车,即在本地生成了公钥和私钥,不要设置密码
    $ ssh-copy-id -p VPS的SSH端口 -i ~/.ssh/id_rsa.pub userVPS@VPS的IP
    
    $ sudo touch /var/log/ssh_nat.log && sudo chmod 777 /var/log/ssh_nat.log
    
    $ sudo vim /lib/systemd/system/autossh.service  #将下例内容粘贴复制进去
    
    [Unit]
    Description=Auto SSH Tunnel
    After=network-online.target
    
    [Service]
    User=userA     #改掉这里A机的用户
    Type=simple
    ExecStart=/usr/bin/autossh -M 6777 -NR 8388:127.0.0.1:22 -i ~/.ssh/id_rsa userVPS@VPS的IP -p VPS的SSH端口 >> /var/log/ssh_nat.log 2>&1 &
    ExecReload=/bin/kill -HUP $MAINPID
    KillMode=process
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    WantedBy=graphical.target
    

    解释一下上面的autossh命令:
    添加的一个-M 6777参数,负责通过6777端口监视连接状态,连接有问题时就会自动重连
    去掉了一个-f参数,因为autossh本身就会在background运行

    $ sudo chmod +x /lib/systemd/system/autossh.service    #给予可执行权限
    $ sudo systemctl enable autossh    #设置开机自启
    $ sudo systemctl start autossh     #现在就启动服务
    $ sudo systemctl status autossh  #查看状态,出现Active: active (running)表示正常运行
    

    也可以登陆到VPS(B机)上看看8388端口是否真的有程序在监听

    $ netstat -antp | grep :8388
    tcp        0      0 0.0.0.0:8388                0.0.0.0:*                   LISTEN      20041/sshd          
    tcp        0      0 :::8388                     :::*                        LISTEN      20041/sshd
    

    5,尝试远程登陆
    接下来,我们就可以在家里的电脑(C机)上登陆到位于公司NAT网络里的那台Debian8虚拟机(A机)。

    ssh userA@VPS的IP -p 8388
    

    注意:这里的userA并不是VPS(B机)上的用户,而是Debian8虚拟机(A机)上的用户。

    参考资料:
    使用SSH反向隧道进行内网穿透
    SSH反向连接及Autossh
    Fun and Profit with Reverse SSH Tunnels and AutoSSH



沪ICP备19023445号-2号
友情链接