环境:
局域网主机A:IP:192.168.18.8(这是一个局域网内部IP),提供Web服务端口:8080,ssh端口:22 阿里云主机B:IP:39.100.100.100(这是一个公网IP,主机A可以SSH连接到主机B,当然,我自己真实服务器的地址不是这个~),ssh端口:22 域名:test.iquanzi.top
需求:
局域网主机A通过端口8080对外提供一个Web服务,用户C使用域名test.iquanzi.top在互联网上访问服务。
问题:
主机A只有局域网IP,A所在局域网的外部IP不固定,且没有权限在A所在的局域网路由器上作端口映射。
解决思路:
(实现A主机服务被外部访问的方案不止一种,本文只介绍SSH透传一种其他方案可自行百度)
借助互联网服务器B进行代理,将域名解析到B服务器,B服务器通过nginx代理转发到主机B的指定端口,主机B的指定端口是主机A与主机B进行数据通信的SSH隧道远程转发端口(A主动连接的B喔,SSH端口转发概念点击了解一下~)。
实现步骤:
1. 在主机A上执行命令:
$ ssh -fCNR 8161:localhost:8080 root@39.100.100.100
回车后,需要输入主机B的密码,输入成功后SSH隧道就建立成功了。
该命令的可以理解为:建立本地主机的8080端口与远端主机的8161端口的隧道。这样依赖,所有向远端主机8161端口发送的数据,会通过该隧道,直接转发到本地主机的8080端口。
参数说明: -f:SSH客户端在后台运行。 -C:压缩数据传输。 -N:仅做端口转发。 -R:该参数有三个部分:
- 8161:远端主机使用的端口;
- localhost:本地主机的主机名或IP地址
- 8080:需要映射的本地主机端口
可以通过netstat命令在主机B上查看ssh监听端口。
2. 在主机B上配置nginx代理
配置好后,nginx需要reload一下。
3. 域名解析,这一步按照一般解析做即可,不需要特殊说明,跳过。
到此,基本上算是配置完成了。
但是,上面的配置还存在两个问题:
其一:每次连接时,都需要输入主机B的密码;参考:《SSH免密登录的实现》
其二:第一步SSH这种反向连接不稳定,遇到各种各样的问题都可能断开,需要主机A 再次向主机B发起连接。此时,我们需要使用另一个武器了–>“autossh”
$ autossh -M 5122 -CNR 8161:localhost:8080 root@39.100.100.100
这里,比使用ssh多了一个-M参数,该参数设定一个监视连接状态的端口,当连接出现问题时,会进行自动重连。