反向ssh隧道访问局域网后面的主机

0. 写在前面

最近为了方便远程管理局域网里的主机,上网搜了一下反向ssh隧道通讯的办法,还加上了一点符合自己具体情况的安全设置。可以达到的效果就是:

  1. 在外网可以免登录vps直接ssh连接到内网的主机
  2. 可以用子域名绑定内网主机上某个端口,例如www.micronbot.com指向vps的80端口,但是xxx.micronbot.com指向vps的某个端口最终连接到内网的某个端口。

SSH 端口转发的一种替代方案是 反向 SSH 隧道。反向 SSH 隧道的概念非常简单。使用这种方案,在你的受限的家庭网络之外你需要另一台主机(所谓的“中继主机”),你能从当前所在地通过 SSH 登录到它。你可以用有公网 IP 地址的 VPS 实例 配置一个中继主机。然后要做的就是从你的家庭网络服务器中建立一个到公网中继主机的永久 SSH 隧道。有了这个隧道,你就可以从中继主机中连接“回”家庭服务器(这就是为什么称之为 “反向” 隧道)。不管你在哪里、你的家庭网络中的 NAT 或 防火墙限制多么严格,只要你可以访问中继主机,你就可以连接到家庭服务器。
reverse ssh.jpg
来源:如何通过反向 SSH 隧道访问 NAT 后面的 Linux 服务器

1. 设置可以开机重启动的反向ssh连接

首先,介绍一下当前环境:

    处于外网的VPS一台,称作'hostA', ssh的端口是111
    处于内网的linux服务器一台,称作'hostB', ssh的端口是222

1.1. 在hostA上操作 - 新建一个专门用于接收反向ssh连接的用户

由于内网连接过来的ssh通信需要hostA上的用户名,所以建立一个专门做这件事的用户以隔开对其他应用的影响。再禁止该用户使用bash,这样这个用户名唯一的作用就是接收来自内网主机hostB的反向ssh连接。

$ su
$ adduser hostA_user
$ usermod -s /bin/false hostA_user //或者修改/etc/passwd
$ mkdir /home/hostA_user/.ssh

1.2. 在hostB上操作 - 生成并上传公钥

$ su
$ ssh-keygen    //生成公钥
$ vim ~/.ssh/config    //由于hostA的ssh端口改过,所以需要在这里指定ssh连接hostA的端口
host xxx.xxx.xxx.xxx    //hostA的ip
hostname xxx.xxx.xxx.xxx
port 111
$ scp /home/hostB_user/.ssh/id_rsa.pub [email protected]:/home/hostA_user/.ssh/id_rsa.pub    //上传公钥到hostA储存公钥的目录

1.3. 在hostA上操作

1.3.1. 添加刚刚上传的公钥

$ cat id_rsa.pub >> /home/hostA_user/.ssh/authorized_keys

1.3.2. 修改sshd_conf允许直接通过hostA的端口连接hostB

$ vim /etc/ssh/sshd_conf
GatewayPorts clientspecified    //添加这一行
$ service ssh restart    //重启sshd服务

1.3.3. 修改iptables规则,开放hostA的监听端口hostA_port

$ 略

1.4. 在hostB上操作 - 建立反向ssh隧道

$ ssh -fN -R hostA_ip:hostA_port:localhost:hostB_port [email protected]_ip
$ apt-get install autossh
$ vim /etc/rc.local
autossh -M hostB_autossh_listening_port -fN -o "PubkeyAuthentication=yes" -o "StrictHostKeyChecking=false" -o "PasswordAuthentication=no" -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R hostA_ip:hostA_port:localhost:hostB_port [email protected]_ip    //在 exit 0 前添加这行

需要注意的是:autossh会用hostB_autossh_listening_port监视已建立的通讯,但是其实还会占用另一个端口:hostB_autossh_listening_port+1。所以如果autossh启动不成功,可能是另一个端口被占用。

1.5. 之后的使用

在hostA上或其他任何电脑上:

$ ssh -p hostA_port [email protected]_ip

2. 配置Nginx反向代理内网主机上的爬虫

上面的步骤可以用来建立反向ssh隧道映射内网hostB的sshd端口,也可以映射其他端口,比如爬虫用的端口。为爬虫用的端口重复上面的操作将hostB_spider_port映射到hostA_spider_port,然后在hostA上:

$ vim /etc/nginx/sites-available/sub.domain.com
server {
    listen 80;
    server_name sub.domain.com;

    location / {
        proxy_pass http://localhost:hostA_spider_port;
    }   
}

本文参考了:

    https://linux.cn/article-5975-1.html
    http://blog.csdn.net/a33445621/article/details/51097233