一、基本概念
内网穿透 :它是一种网络技术或方法,旨在允许外部网络(如互联网)访问位于内部网络(内网)中的设备或服务。由于内部网络通常处于NAT(网络地址转换)、防火墙或其他安全机制之后,直接从外部访问内网设备变得困难或不可能。内网穿透技术通过各种方式绕过这些限制,实现外部与内网之间的通信。
(内网穿透的核心是解决外网设备访问被 NAT 隐藏的内网设备的问题。具体实现方式包括两种:1、反向代理方式:适用于内网设备无法访问外网,且外网无法直接访问内网的场景。通过反向代理技术,内网设备主动与外网服务器建立连接,并通过这个连接实现外网访问内网;2、长连接中继方式:适用于内网设备能够访问外网,但外网无法直接访问内网的场景。内网设备主动与外网的中继服务器建立长连接,通过该连接实现数据的双向传输。)
基础概念
内网IP :指 局域网(LAN) 内部设备所使用的 IP 地址,也叫 私有 IP 地址,它只在内网范围内有效,不能直接通过互联网访问。按照 RFC 1918 标准,内网 IP 地址被定义在以下范围10.0.0.0 - 10.255.255.255;172.16.0.0 - 172.31.255.255;192.168.0.0 - 192.168.255.255。当设备属于同一局域网且位于同一网络段内可以通过内网ip互相通信
与交换机的关系:交换机是工作在 数据链路层(OSI 第二层) 的网络设备,可以基于 VLAN 配置,将内网 IP 地址分配到不同的 VLAN 中,每个 VLAN 可以视为一个独立的内网或内网中的逻辑子网以实现逻辑上的网络隔离,并且间接通过ARP 协议将目标 IP 地址解析出的 MAC 地址转发数据。
与路由表的关系:路由表是工作在 网络层(OSI 第三层) 的核心组件,用于决定数据包的转发路径,主要作用是基于 IP 地址决定数据包的目标下一跳。如果内网 IP 地址属于同一个子网(如 192.168.1.0/24
),路由器会将数据包直接转发到同一局域网中,不跨越子网或外网。当内网 IP 地址属于不同子网时,路由器会根据路由表查找对应的下一跳,将数据包转发到目标子网。例如,从 192.168.1.0/24
子网到 192.168.2.0/24
子网,需要路由器提供路由规则
(内网穿透的目标是克服内网 IP 的局限性,使外网能够访问内网中的资源,从而实现内外网络的无缝连接。)
公网IP :指分配给设备并在公共互联网上唯一标识的 IP 地址,允许该设备直接与互联网上的其他设备通信。一个公网 IP 地址通常由互联网服务提供商(ISP)分配给家庭、企业或数据中心网络,可以分为动态公网 IP:会随着时间或重启路由器而变化,静态公网 IP:固定分配给用户,始终不变。阿里固定公网ip是指初始分配的,停机重启可能就会变,而弹性公网ip则是可以绑定不同实例,不释放永远占有的固定公网ip
(内网穿透是解决内网 IP 无法被外网直接访问的技术手段,目的是模拟公网 IP 的效果。拥有一个公网 IP 通常可以避免使用内网穿透,但如果公网 IP 被共享(如 ISP 提供的 CGNAT 或路由器分配),内网穿透仍然可能需要)
NAT :即Network Address Translation,中文翻译为网络地址转换。它是一种网络技术,用于将一个网络中的 IP 地址映射到另一个网络中的 IP 地址。NAT 最常见的用途是将私有 IP 地址(内网地址)映射到公网 IP 地址,从而实现内网设备访问互联网。
(NAT 是一种用于地址映射的网络技术,主要用来解决内网和外网之间的通信问题,但其隐藏内网地址的特性导致了外网无法主动访问内网资源的限制。内网穿透正是为了解决这一限制,通过各种技术手段(如中继或直连),绕过 NAT 的阻碍,使外网能够成功访问内网设备或服务。阿里ECS实例通过两种NAT网关实现网络通信,一种是SNAT配置控制内网访问公网,一种是DNAT配置控制公网访问内网,直接将EIP绑定到ECS实例上,相当于直接暴露)
端口映射 :将网络设备(如路由器或防火墙)上的某个端口与内网设备(主机)的一个端口进行关联。这种关联允许外部访问者通过特定的外部端口访问内网中的设备或服务。
(端口映射和内网穿透的目标一致:让外网设备能够访问内网设备或服务。端口映射通过手动配置路由器,创建一种"静态规则",允许外部请求流量到达内网设备,适用于固定公网 IP 环境,而内网穿透则通过第三方工具或服务,绕过路由器和 NAT 的限制,动态建立连接,适用于无权管理路由器或没有公网 IP 的内网环境以及动态 IP 或多级 NAT 的复杂网络)
DDNS :即Dynamic Domain Name System 的缩写,字面含义是 动态域名系统,DNS是将域名解析为IP地址的系统,让人类友好的域名(如 example.com
)能够与计算机使用的IP地址(如 192.168.1.1
或 2001:db8::1
)对应,DDNS 是 DNS 的扩展版本,支持动态更新。当设备的公网 IP 地址发生变化时,DDNS 服务可以自动更新对应域名的解析记录,使用户始终可以通过固定的域名访问设备。
(DDNS 和内网穿透都涉及 让外网用户访问内网设备或服务,但它们解决的是不同层面的问题.DDNS为动态公网 IP 提供稳定的域名解析,让设备可以通过固定域名访问,即使 IP 经常变化,而内网穿透解决没有公网 IP 或无法配置路由器端口映射时,如何从外网直接访问内网设备或服务。二者可以结合使用,在内网穿透中,将 DDNS 配置到内网穿透提供的中继服务器地址上,用户只需记住易读的域名(如 myservice.example.com
),而不需要频繁调整配置,提升用户体验和服务访问的稳定性。)
VPN :即Virtual Private Network,中文翻译为虚拟专用网络,它通过加密隧道连接整个网络,用户可以访问内网的所有资源,就像直接连入内网一样,主要用于创建一个虚拟的专用网络,如远程办公时访问企业内部网络资。
(VPN的核心是建立一个虚拟的加密网络,模拟内网环境;而内网穿透的核心是突破网络限制,让外网访问内网设备。额外:和翻墙工具VPN的联系,VPN本身是一种网络技术,其核心功能是通过加密隧道在公共网络(如互联网)上创建一个安全的虚拟专用网络,让用户能够安全地访问特定的资源。而在翻墙工具中,VPN 技术经常被用作突破网络限制的一种实现手段,但是翻墙工具VPN,除了提供隐私保护,防止网络监控,主要用于流量转发绕过网络限制,访问被限制的内容(如被屏蔽的网站))
反向代理 :字面含义是指代理服务器代表后端服务器接收请求,并将响应返回给客户端。相对于正向代理(Forward Proxy),它代理的是服务器而不是客户端。正向代理:客户端通过代理访问外部资源(如翻墙),代理隐藏了客户端。而反向代理:客户端直接请求代理服务器,代理再与后端服务器通信,代理隐藏了后端服务器。核心功能包括隐藏真实服务器、负载均衡、缓存和加速以及安全性等。
(反向代理和内网穿透有相似之处,但服务目的和使用场景不同,两者都需要一个中间服务器在客户端与目标服务之间进行数据转发,但是反向代理隐藏了后端服务器的地址,使其不直接暴露,而内网穿透通过中间服务器使外网能够访问内网资源,突破 NAT 或防火墙限制。可以说反向代理侧重于优化和保护后端服务,内网穿透侧重于让被隐藏的资源(如内网服务)对外可见)
隧道协议 :从字面上可以理解为一种在其他通信协议中创建"隧道"传输数据的技术,它一种协议的数据包封装在另一种协议的数据包中进行传输。例如,将私有网络的 IP 数据包封装到公共网络协议中(如 HTTP 或 UDP),可以让不支持特定数据协议的网络环境正常传输数据。隧道协议被广泛用于穿越防火墙、绕过 NAT 或实现安全连接
(内网穿透和隧道协议关系密切,隧道协议通常是实现内网穿透的技术手段之一。内网穿透需要解决NAT(网络地址转换)和防火墙的阻隔,使得内网中的服务可以被外部访问。而隧道协议通过建立封装和转发机制,将内网服务的数据流量通过中间网络传递给外部,实现"穿透"效果。内网穿透工具(如 frp、ngrok)本质上就是使用了隧道协议,比如FRP 的原理和隧道协议密切相关,其实现过程中大量依赖隧道协议的思想,本质上是通过建立长连接(如 TCP 隧道)封装内网服务的数据流量,例如,FRP 可以通过 HTTP、WebSocket 等协议建立隧道,这种灵活性允许它在受限网络中运行。)
FRP: 即Fast Reverse Proxy(快速反向代理)。它是一个高性能的反向代理应用,专门设计用于解决 内网穿透 问题。它的核心功能是将内网服务暴露到外网,类似于反向代理服务器,将外部请求转发到内网。FRP 由两个核心组件组成FRP 客户端(frpc):运行在内网设备上,主动向公网服务器发起连接,FRP 服务器(frps):运行在具有公网 IP 的服务器上,用于接收客户端的连接和外部请求。它相较于配置路由或网关代理的穿透方式,更适合于无法直接取得公网IP或不能自行配置NAT的环境,也适合临时/调试/频繁变动等情况。
(FRP 是实现内网穿透的工具之一,主要通过 反向代理和中继 技术,帮助外部设备访问内网中的服务。它实现内网穿透的过程:通过FRP 客户端(内网设备)主动与 FRP 服务器建立长连接绕过了 NAT 和防火墙的限制,因为这是由内网发起的连接,外部设备的请求发送到 FRP 服务器,服务器将请求通过长连接转发到内网设备,内网设备的响应通过 FRP 服务器返回给外部设备。)
二、操作步骤
1、购买ECS
登录阿里云官方并进入云服务器ECS_云主机_服务器托管_计算-阿里云,根据自身需求的服务器配置(地域、操作系统、带宽等)选择适合的云服务器ECS产品。通常建议选用距离访问较近的地域节点以获得更快的网络请求相应速度。购买后,通过远程连接(SSH)登录服务器,按照自身需求更新和配置服务器基础环境(如安装常用工具、更新系统等)。购买之后可在阿里云控制台首页阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台查看已经购买的服务器实例及详情。
(内网穿透必须有一个可以被外部网络访问到的出口,阿里云服务器正好可以承担了这个"中转"的角色,它有独立的公网 IP,能够让外部访问者通过该公网 IP 进行访问,并且云服务器通常提供较为稳定的带宽和网络环境,有助于确保穿透服务的连通性和稳定性。)
2、下载FRP
在github上Releases · fatedier/frp · GitHub下载windows系统的zip包,其中包含了FRPS服务端及FRPC客户端以及各自的默认配置文件,具体配置及说明还可参考概览 | frp
(FRP(Fast Reverse Proxy)是一款开源的反向代理工具,支持 TCP、UDP、HTTP、HTTPS 等多种协议映射,配置方式灵活,适合多种场景下的内网服务暴露,可以将内网服务映射到拥有公网 IP 的机器上,从而实现跨网络访问。包含了不同的主机上应当部署的不同组件FRPS及FRPC)
3、部署FRPS服务端
在云服务器上部署 FRPS 服务端,将下载的FRP压缩包解压并移动到合适位置,编辑编辑 frps.toml
配置文件,然后在解压目录下命令启动 FRPS,.\frps.exe -c .\frps.toml,frps.log中打印出frps started successfully则为启动成功。
启动成功后放开云服务器防火墙端口外,还需要设置服务器安全组规则开放 7000 端口,登录阿里云控制台 -> 找到对应 ECS 实例 -> 网络与安全 -> 安全组 -> 配置规则 -> 添加入方向规则,端口范围填 7000
,协议类型选择 TCP/UDP
(根据需求),授权对象可填 0.0.0.0/0
以允许任何 IP 访问。
frps.toml配置如下:
鉴权配置
auth = {token = "ssim"}
服务端监听地址,用于接收 frpc 的连接,默认监听 0.0.0.0
bindAddr = "0.0.0.0"
bindPort = 7000
通用配置
[log]
to = "./frps.log"
level = "info"
maxDays = 3
(FRPS(服务端)会在云服务器的 7000 端口上监听来自内网服务器(FRPC 客户端)的连接请求,就相当于在云端和内网之间建立了一条数据隧道,可以让内网的 FRPC 可以与外部网络建立并保持通信通道)
4、部署FRPC客户端
与在服务器上安装类似,可以在本地或内网服务器上下载对应版本的 FRP 压缩包并解压,编辑frpc.toml
配置文件,然后在解压目录下命令启动 FRPC,.\frpc.exe -c .\frpc.toml,frpc.log中打印出login to server success则为启动并登录到 FRP 服务端成功。如果由其他配置,还会打印其他配置是否启动成功,比如代理、健康检查等
启动内网服务器内想要外网访问的服务,并将java程序服务端口配置于frpc.toml中
frpc.toml配置如下:
客户端通用配置
serverAddr = "xxx.xxx.xxx.xxx" # 云服务器的公网IP地址
serverPort = 7000
客户端鉴权配置
auth = {token = "ssim"}
通用配置
[log]
to = "./frpc.log"
level = "info"
maxDays = 3
第一个服务代理
[[proxies]]
name = "service1"
type = "tcp" # 根据实际情况选择代理类型,如 http、https、tcp 等
localIP = "127.0.0.1"
localPort = 19001 # 本地服务端口
remotePort = 19001 # 服务端暴露的端口
loadBalancer.group = "my_group" # 负载均衡分组名称,用户请求会以轮询的方式发送给同一个 group 中的代理
loadBalancer.groupKey = "my_key" # 负载均衡分组密钥,用于对负载均衡分组进行鉴权,groupKey 相同的代理才会被加入到同一个分组中
healthCheck.type = "tcp" # 健康检查类型,可选值为 tcp 和 http,配置后启用健康检查功能,tcp 是连接成功则认为服务健康,http 要求接口返回 2xx 的状态码则认为服务健康
healthCheck.timeoutSeconds = 3 # 健康检查超时时间(秒)
healthCheck.maxFailed = 3 # 健康检查连续错误次数,连续检查错误多少次认为服务不健康
healthCheck.intervalSeconds = 10 # 健康检查周期(秒),每隔多长时间进行一次健康检查
第二个服务代理,用于测试负载均衡
[[proxies]]
name = "service2"
type = "tcp"
localIP = "127.0.0.1"
localPort = 19002
remotePort = 19001 # 与第一个代理相同的远程端口
loadBalancer.group = "my_group" # 与第一个代理相同的负载均衡分组名称
loadBalancer.groupKey = "my_key" # 与第一个代理相同的负载均衡分组密钥
healthCheck.type = "tcp"
healthCheck.timeoutSeconds = 3
healthCheck.maxFailed = 3
healthCheck.intervalSeconds = 10
(成功启动服务及FRPC后,内网 FRPC会与云服务器上的 FRPS 服务端建立一个持续的、反向代理的隧道,最终在浏览器中访问域名测试时,能否成功打开页面或服务,都取决于 FRPC 是否和 FRPS 正常连接,并且内网服务端口是否正确映射。)
5、申请域名
以在阿里云、腾讯云或其他域名注册商购买喜欢的域名,比如阿里云万网_域名注册_域名交易_建站_备案_资质_商标_软著-阿里云,注册购买成功后,在网站备案_ICP备案_备案迁移_App备案_小程序备案_备案-阿里云按照步骤完成ICP备案。
备案通过后,在阿里云控制台首页可以查看到自己的域名,进入并设置DNS解析,添加 一条A 记录,将域名解析到你在阿里云购买的服务器的公网 IP
(通过申请及备案域名后,使用域名访问内网服务,更专业,也符合国内政策要求)
6、配置云服务器Nginx
在云服务器上配置安装Nginx,在nginx.conf中增加HTTP(80)或HTTPS(443)的默认端口配置.在配置文件内容的HTTP块中,增加如下配置
server {
listen 80; # 监听 HTTP 80端口
server_name xxx.xxx; # 你的域名
location / {
proxy_pass http://127.0.0.1:19001/; # 转发到本机 19001 端口
还可配置一些头部、超时等,如:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
默认的 server
server {
listen 80 default_server;
server_name _;
return 403; # 或者 444
}
(外部访问者访问 http://xxx.xxx
时,就会被 Nginx 拦截并转发到你指定的后端服务端口,实现统一的域名访问入口、反向代理和安全管理)
7、验证访问
在浏览器中输入 http://www.example.com
(如果配置了 HTTPS,则使用 https://www.example.com
),如果能够成功打开内网服务器上的 Web 服务页面,说明整个 FRP 穿透流程已经成功
总结
使用FRP进行内网穿透,本质就是通过FRP中继服务建立长连接实现数据流量的内外网传输,关键点在于正确配置FRP使得FRPS与FRPC可成功连通
三、额外补充
1、同一内网的FRPC配置
假设处于内网的服务器既不可被公网访问,也不可访问公网,但是与可被公网访问的服务器处于同一内网(可通过阿里云创建,基于已经存在的可公网访问的服务器的VPC,且不分配公网ip的ECS实例模拟),则可以在frpc.toml中配置被公网访问的服务器的私网IP,即将serverAddr = "xxx.xxx.xxx.xxx"改为公网访问服务器的私网IP地址
2、负载均衡
FRP默认采用轮询的策略对注册的同一端口的不同服务进行请求,可参照上面提到的frpc.toml中的配置进行多[[proxies]]的配置,只需要将远程端口及负载均衡分组名称和密匙保持一致即可。为了确保高可用性,您可以为每个代理配置健康检查参数。当某个代理的后端服务出现故障时,frp 会将其从负载均衡组中移除,避免将请求分配给不可用的服务,配置可参照上面提到的frpc.toml中healthCheck.相关的配置
3、通过 SSH 访问内网机器
在需要被访问的内网机器上部署 frpc,将localPort = 22,remotePort = 6000,然后使用以下命令通过 SSH 访问内网机器,假设用户名为 test,ssh -o Port=6000 test@x.x.x.x。x.x.x.x为公网ip地址,frp 将请求发送到 x.x.x.x:6000
的流量转发到内网机器的 22 端口。注意:windows10家庭中文版不支持