几年前家里的拨号上网拨到都是公网IP,可以在家里通过ddns动态域名解析和端口映射的方法实现局域网内服务器的访问。但是随着公网IP越来越少,不少地区拨号后会发现地址变成了10.x.x.x类似的局域网地址。运营商又在我们上网环境之前加了一个网关,这样通过ddns和端口映射的办法基本就废了。顺便吐槽,我们离大局域网的日子也不远了。
什么是反向 SSH 隧道
反向 SSH 隧道的概念非常简单,不多使用这种方案,在你的受限的网络之外,还需要另一台主机(所谓的“中继主机”),一般都是有公网IP的主机。然后从你的家庭网络服务器中建立一个到公网中继主机的永久 SSH 隧道。有了这个隧道,你就可以从中继主机中连接“回”家庭服务器(这就是为什么称之为 “反向” 隧道)。不管你在哪里、你的家庭网络中的 NAT 或 防火墙限制多么严格,只要你可以访问中继主机,你就可以连接到家庭服务器。
创建反向SSH隧道
假设我们有这两台服务器:
A主机:外网,ip:1.2.3.4,sshd端口:22
B主机:内网,sshd端口:2202
在B主机上执行一下命令,连接A主机。
$ ssh -fN -R 10022:localhost:2202 relay_user@1.2.3.4:22
端口 10022 是A主机中任何你可以使用的端口,确保不会被A主机中的程序占用。
“-R 10022:localhost:2202”:定义一个反向隧道。它转发中继服务器A主机 10022 端口的流量到家庭服务器的 2202 号端口。
用 “-fN” 选项,当你成功通过 SSH 服务器验证时 SSH 会进入后台运行。
登录到A主机,确认其 127.0.0.1:10022 绑定到了 sshd。如果是的话就表示已经正确设置了反向隧道。
例如:
到这一步,登录B主机可以这样做,先登录A主机,然后通过A主机登录B主机。因为反向端口监听的地址是本地的。
不过如果你需要外部网络可以通过A主机监听的端口直接访问B主机,那么打开A主机sshd_config配置文件,修改或者添加“GatewayPorts clientspecified”,重启SSH服务。
在B主机执行命令:
$ ssh -fN -R 1.2.3.4:10022:localhost:2202 relay_user@1.2.3.4:22
外部网络通过下面命令可以直接访问B主机。
$ ssh -p 10022 server_B_username@1.2.3.4
反向SSH隧道这样就搭建好了。不过有个问题,这种反向连接(Reverse Connection)不稳定,可能随时断开。
创建永久反向SSH隧道
上面说到SSH自带的命令无法满足“永久”的需求,这时我们需要个“朋友”,帮你在内网B主机执行这条命令。它就是Autossh。
第一步:创建B主机到A主机免密码登录
B主机
# ssh-keygen # ssh-copy-id relay_user@1.2.3.4
第二步:在B主机安装autossh
# apt-get install autossh
第三步:运行autossh
# /usr/bin/autossh -M 2201 -fN -o "PubkeyAuthentication=yes" -o "StrictHostKeyChecking=false" -o "PasswordAuthentication=no" -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R 1.2.3.4:2202:localhost:2202 relay_user@1.2.3.4
“-M 2201” 选项指定中继服务器上的监视端口,用于交换监视 SSH 会话的测试数据。中继服务器上的其它程序不能使用这个端口。
“-fN” 选项传递给 ssh 命令,让 SSH 隧道在后台运行。
“-o XXXX” 选项让 ssh:
使用密钥验证,而不是密码验证。
自动接受(未知)SSH 主机密钥。
每 60 秒交换 keep-alive 消息。
没有收到任何响应时最多发送 3 条 keep-alive 消息。
第四步:添加开机启动
在/etc/rc.local中添加第三步命令,保存。
这样我们就可以在公网通过A主机的2202端口随时访问B主机了,实现B主机的NAT穿透。
参考连接:https://linux.cn/article-5975-1.html
评论列表(0条)
感谢分享 收藏了
😯 博主研究得蛮深入的
比较难 不过得学习
哇哦,好专业的博客。
得慢慢磨了。。
感觉好难的说。
谢谢博主分享