1. 内网穿透的应用场景
1.1. 开发调试
比如企业微信、钉钉等开发,需要一个回调地址,开发的时候,希望回调到开发的电脑上,打断点进行调试,这就需要穿透到内网的开发机器。
1.2. 演示测试
有需要演示或测试的系统,可以直接将内网系统地址暴露到外网,短时间内进行演示或测试,不用再买服务器了
1.3. 访问内部系统
有的系统部署在内网,大部分时间在内网访问,偶尔需要进行外部访问。
1.4. 其他
因为真正的内网穿透技术上成功率非常低,基本上都是通过服务器转发,需要服务器、域名和带宽资源,所以免费的都有限制。像免费版花生壳每月1G的流量,速度和稳定性无法保证。1G流量也不太够用。
2. Ngrok
2.1. 注册账号
在ngrok.com,注册一个账号
进入以后拿到token,并且下载客户端
2.2. 身份验证
ngrok config add-authtoken 你的token
执行后,保存到了ngrok.yml文件
2.3. 映射
首先我们在本地开一个Nginx,端口号30080,确保能访问
启动隧道,意思是启动http隧道,转发到本地的30080端口
执行:ngrok http 30080
可以看到已经,给了随机域名
https://30bb-112-232-222-182.ngrok-free.app/
现在我们访问
这样实现了将内网的服务通过隧道暴露在外网。
但是存在2个问题:
1、免费版域名是随机的,每次都不一样,如果尝试用自己的域名,不行,提示升级
这就尴尬了。比如企业微信对域名的验证比较严格,要验证主体一致,也就是随机给的这个域名没法用
当我们尝试自己在阿里云上添加CNAME,指到Ngrok,也报错了
而升级最便宜的需要8美元1个月,够买一个轻量服务器
2.4. 所以:
免费版也明确提出会有带宽和用量的限制。此种方式适合偶尔将内网系统暴露给外网的情况,比如:给客户一个演示地址。短时间的演示一下。
3. FRP
Frp是github上的一个star超过66.8k的项目,功能和Ngrok类似,但是需要自己搭建,这样的好处是完全可控,只要有相关资源就可以
3.1. 前提条件:
1、一台有固定IP的服务器
2、自己可控的域名
但是在下载的时候杀毒软件直接报毒删掉了,查了下,网上也有很多类似情况,还有安装后中勒索者病毒的。暂时还是不尝试了。
4. DDNS+路由端口映射
这个前提是上网的宽带有外网IP,现在IPV4资源紧张,安装的电信宽带就没有外网IP。如果没有,据说可以给运营商打电话要到。如果有外网IP,即便不是固定的,那也很好了。配置也简单,登录路由器(有权限),做一个端口映射,就可以了
5. IPV6
IPV6已经喊了很多年了。但是现实中存在感有点低,来一张图,可以看到普及还需要时间。
我的电信宽带虽然没有给外网的IPV4,但是给了外网的IPV6,虽然经过了多层的NAT,但是我在手机上可以直接访问到我笔记本。非常Nice。但是当我在公司访问的时候,结果却无法访问。这就Nasty了。原因竟是公司的网络设备不支持IPV6。现实就是这样的。还有很多原有的设备没有进行IPV6的升级。现在国内通过手机流量都已经支持IPV6了。运营商的骨干网也已经支持。但是完全脱离IPV4,直接用IPV6,还不太现实。这个方案看着很香,当前还无法实际应用,但是未来可期。
6. SSH 端口转发
6.1. 前提条件:
需要一台有固定IP的服务器,假设IP为:8.8.8.8,用户名:root,密码:password
6.2. 场景一:将内网的web服务器映射出去
先上一张图,流程大概是这样的
解释:
- 当小强访问http://8.8.8.8:43001的时候
- Nginx将请求转发到本机的42001端口
- 这时候sshd正在监听42001端口。监听到后,通过ssh发给内网的192.168.1.1(192.168.1.1和8.8.8.8已经建立了连接)
- 内网的接收到数据后,转发到本机的80端口
- 数据的相应流程是相反的过程
针对SSH隧道我问了ChatGPT两个问题:
1、ssh客户端也是使用22端口吗
答:
SSH客户端和服务器之间建立SSH连接时,客户端通常是通过将自己的SSH连接请求发送给服务器的22号端口来发起连接。但是,与SSH服务器不同的是,SSH客户端本身并不需要监听或使用22号端口。
换句话说,SSH客户端不会直接使用TCP端口22来进行连接,而只是通过该端口向SSH服务器发送连接请求。实际上,当用户在SSH客户端中执行 ssh 命令时,默认情况下会在本地计算机上创建一个随机的TCP端口来与SSH服务器进行连接,并且随机端口仅用于该次SSH连接
总结下来就是:服务器端用22端口,客户端是随机端口
2、ssh隧道是单独的连接吗?
答:
SSH隧道是通过在一条SSH连接中嵌入其他协议的方法来实现的,因此它不是一个单独的连接,而是在已有的SSH连接之上添加了额外的功能。
在使用SSH隧道时,可以通过在SSH客户端和SSH服务器之间建立一个TCP隧道,将其他协议的数据流量发送到该隧道上。这样,就可以在不直接暴露其他协议的情况下,通过SSH安全地传输数据。
例如,在使用MySQL时,可以通过SSH隧道来加密和保护MySQL的数据传输。为了实现这个过程,可以在SSH客户端中打开一个本地端口,并将其映射到MySQL服务器上的远程端口。然后,在MySQL客户端中连接本地端口,就可以通过SSH安全地传输MySQL数据。
需要注意的是,SSH隧道的性能受到SSH连接的影响,因此在使用SSH隧道时,需要考虑网络环境和SSH连接的稳定性,以确保数据的可靠传输。同时,为了提高安全性,建议使用密钥认证方式进行SSH连接,并设置适当的防火墙和访问控制策略,以防止未经授权的访问
总结下来就是:隧道不是单独的连接。是在已有的SSH连接之上添加的额外功能
具体实现如下
1、服务器上需要安装Nginx,并做如下配置:
server {
listen 43001; #这里监听的为后续访问的云服务器端口,可以设置为任意一个服务器上还不存在的端口号
server_name _; # 这里填你的域名,如果没有域名则填localhost
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://localhost:42001; # 这里的8899相当于一个标识,和后面在本地创建通道相关,可以任意设置一个值
}
}
2、然后内网服务器上执行:
ssh -R 42001:localhost:80 -N root@8.8.8.8
输入密码,也可以用xshell,主页shell连接后也可以
保持连接。xshell有相应的设置。还可以用用AutoSSH来实现稳定的SSH连接
这样我们就建立了隧道:http://8.8.8.8:43001->http://192.168.1.1:80