1. 动机:没有公网IP的痛
A:大家好,我是 A 机器,我爱 C 机器,但是 C 没有公网 IP,所以我看不见它,暗恋使我心焦+痛苦,谁替我捎给它秋天的菠菜?
C:我是 C 机器,我矜持、羞涩,但我也希望有人,给我带来秋天的菠菜。
B:兄弟们!我是 B 机器,我有公网 IP!我就是天上的鹊桥,是情人们的快递,我,负责运输秋天的菠菜!
2. 反向映射
B:C 妹子,你没有公网 IP ,我看不见你啊,我怎么给你送菠菜?
C:别着急,B大哥,我用 ssh 一直给你写信,你给我回信的时候也寄上菠菜,这样你就不担心找不到我了!
2.1 具体操作
C妹操作:
ssh -CNfR 1111:localhost:22 ubuntu@xx.xx
-C 表示所有传输数据都压缩,可以减少开支
-N 表示只做连接,不干任何别的
-f 表示命令在后台操作
-R 表示反向映射,对 ubuntu@xx.xx 端口 1111 的访问都映射到本机的22端口
2.2 检查
完成以后 B 哥可以做检查:
ssh -p1111 C@localhost
如果正常,B哥将会成功登录C妹。
3. 正向映射
A:B哥,我每次只能把菠菜送到你那,然后由你送到C妹,有没有办法直接接力,一步到位啊。
B:兄弟,这个可以有!你看这个图,刚才不是说,我B的1111端口映射到C妹的22端口了吗,现在我再跟自己做个正向映射,把我B的1234端口与1111端口映射,这样,你每次访问我的1234端口,就自动转到C妹的22端口啦!这一步是为了实现“自动转”,让你更方便!
3.1 具体操作
B哥:
ssh -CNfL *:1234:localhost:1111 ubuntu@xx.xx
其中,-L 表示正向映射,这句话的意思是,把对B机端口1234所有的访问,都转到B机localhost 1111端口的访问,结合前面的反应映射,也就是转到 C 妹 22 端口的访问。
3.2 检查
如果这一步成功,在B机上就可以检查:
ssh -p1234 C@xx.xx
注意,这里端口改为了 1234,地址改为了 B 哥的公网 IP,而用户名是 C 妹的用户名。如果成功登陆C妹,那么基本就成功了。
4. 注意事项
4.1 GatewayPorts
B 机 和 C 机都需要修改 ssh 配置: /etc/ssh/sshd_config 中设置 GatewayPorts yes
4.2 腾讯云机器开放端口
腾讯云服务器“防火墙”->添加规则->自定义,然后开放端口1234,这一步可能是必要的,如下图
另外,还需要B哥开放防火墙对端口1234的限制:
sudo firewall-cmd --zone=public --add-port=1234/tcp --permanent
关于 firewall-cmd 对防火墙端口的管理,可以参考(鸣谢):
https://blog.csdn.net/qq_37349301/article/details/103297315
4.3 稳定链接
4.3.1 设置ssh免密登录
首先需要C妹设置免密登录
ssh-keygen # 生成公钥和私钥,就用默认文件夹 ~/.ssh/ 即可
ssh-copy-id -i ~/.ssh/*.pub B@xx.xx # 把公钥copy到 B机上
ssh B@xx.xx # 即可实现免密登录
成功以后,用C妹的root账户再来一次,保证C妹的root账户也可以免密登录,这很重要(亲测),因为后面设置的开机自启命令实则都是在root账户下进行的。
4.3.2 设置autossh自动重连
如果网络不稳定,C妹建立的反向映射可能中断,C妹可以使用autossh
autossh -M 2222 -CNfR 1111:localhost:22 B@xx.xx
注意,做这一步之前必须先设置免密登录,否则这一行命令是无效的(亲测)。
这个意思是,C妹机器上2222端口(发送)+2223端口(收听)形成对后面ssh指令的监听,如果后面的ssh链接断开,就自动重连。
4.3.3 设置开机自启
先设置 C 妹的 root 账户免密登录 B 机,因为开机自启的命令是在 root 账户下执行的。
设置开机自启命令可以参考如下链接
https://www.cnblogs.com/luyi07/p/11183607.html
设置好以后在 rc.local 里面增加一行
autossh -M 2222 -CNfR 1111:localhost:22 B@xx.xx
即可让 C 妹每次开机都自动建立反向映射,再也不用操心这个问题。
类似地,可以在B机上把ssh正向映射设置为开机自启(注意设置B机的root->B免密登录)。
还有一点可以稍加留意,当 B 宕机时,C 挂上反向映射命令是无效的,B 启动以后,反向映射也不会自动生效,而需要重启一下 rc.local 里的命令:
systemctl restart rc-local.service
这样就建立反向映射了(OMG,老子尝试了n次,总算把这些细节搞清楚了)。
4.4 B哥1234端口不可作为sshd对外开放端口
这个我试了,如果在B哥 /etc/ssh/sshd_config 中有
Port 22
Port 1234
那么,在做正向映射,试图用1234端口映射1111端口时,系统会说,1234端口正在使用。所以,需要删除 Port 1234 这一行。
5. 鸣谢
https://www.cnblogs.com/kwongtai/p/6903420.html
https://blog.csdn.net/autoliuweijie/article/details/80283689