内网穿透完全指南(从原理到实战)
1. 什么是内网穿透
内网穿透(NAT Traversal)是一种技术,允许位于内网(无公网IP)的设备被外网(互联网)的用户访问。
典型场景:工控机、树莓派、NAS、开发测试服务器等设备往往部署在公司的局域网内,没有独立的公网IP,外部无法直接访问。通过内网穿透,可以安全地远程访问这些设备。
2. 核心原理:为什么需要公网IP?
2.1 公网IP vs 内网IP
| 类型 | 特征 | 比喻 |
|---|---|---|
| 公网IP | 全球唯一,可在互联网任意位置访问 | 精确的“门牌号”,快递员可以直接送达 |
| 内网IP(如192.168.x.x) | 仅在局域网内有效,外网无法路由 | 小区内的“业主小名”,外人不知道在哪栋楼 |
2.2 数据包路由的限制
互联网上的路由器只认公网IP。如果目标地址是192.168.x.x,路由器会丢弃数据包,因为找不到这个地址在哪个网络。
结论:要让外网访问内网设备, 必须有一台拥有公网IP的服务器作为“中转站”。
2.3 内网穿透的本质
- 内网设备主动发起连接 → 连接到公网服务器(因为内网设备能上网)。
- 建立持久隧道 → 保持这个连接不断开。
- 公网服务器监听外网请求 → 当外网用户访问服务器指定端口时,服务器通过已建立的隧道将请求转发给内网设备。
- 内网设备回复 → 沿着同一隧道返回数据。
关键点:内网设备不需要公网IP,只需要能主动访问外网(通常公司网络都允许)。
3. 常见内网穿透方案对比
| 方案 | 是否需要自己买服务器 | 实现难度 | 数据安全 | 成本 | 适用场景 |
|---|---|---|---|---|---|
| 自建frp | ✅需要(买云服务器) | 中 | 高(数据仅过你的服务器) | 服务器费用 | 工业设备、长期稳定、多服务 |
| cpolar/ngrok等SaaS | ❌不需要(服务商提供) | 低 | 中(依赖服务商) | 免费或付费套餐 | 个人开发、临时测试 |
| VPN/异地组网(ZeroTier/Tailscale) | 需要信令服务器(可由服务商提供) | 中 | 高(加密隧道) | 免费或付费 | 组建虚拟局域网,访问多个设备 |
| 硬件远程控制(如向日葵控控) | ❌不需要 | 最低 | 高(物理隔离) | 硬件成本高 | 设备无网络或需BIOS级控制 |
3.1 cpolar vs 自建frp 深层区别
| 对比项 | cpolar(SaaS) | 自建frp |
|---|---|---|
| 公网服务器 | cpolar官方提供(共享) | 你自己买的云服务器 |
| 带宽 | 免费版限速(通常几百KB/s) | 取决于你购买的带宽(可自由选择) |
| 端口/域名 | 随机分配,付费才固定 | 固定IP+固定端口 |
| 数据流向 | 经过第三方服务器 | 只经过你自己的服务器 |
| 稳定性 | 依赖服务商服务状态 | 依赖云服务商(大厂通常99.95%可用) |
| 适用场景 | 个人学习、临时分享 | 企业生产环境、长期使用、多服务 |
结论:cpolar这类服务本质是“替你买好了服务器并部署了服务端”,但带宽和隐私受制于人。对于工控等企业场景,自建frp是更可控的选择。
4. 实战:使用frp实现内网穿透(工控机场景)
4.1 架构图
text
[远程用户] --> [云服务器 (frps)] <--> [工控机 (frpc)]
公网IP: 61.xx.xx.xx 内网IP: 192.168.1.100
端口: 7000 (frpc连接)
端口: 7614~7618 (用户访问)
4.2 准备工作
- 购买一台云服务器(阿里云、腾讯云、华为云等),操作系统推荐 Ubuntu/CentOS,确保有公网IP。
- 开放防火墙:
- 云服务器系统防火墙(如 firewalld/iptables)
- 云厂商控制台的“安全组”(最易遗漏!)放行所需端口。
- 下载frp:访问 frp GitHub Releases,根据操作系统和CPU架构分别为服务端(云服务器)和客户端(工控机)下载相同版本。
4.3 服务端配置(云服务器 - frps)
- 解压并进入目录。
- 编辑配置文件
frps.toml(新版)或frps.ini(旧版),以下以新版 TOML 格式为例:
toml
# frps.toml
bindPort = 7000 # frpc 连接端口
auth.method = "token"
auth.token = "your_secure_token_here" # 改为强密码
# Web管理面板(可选)
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "your_admin_password"
- 启动服务端(测试):
bash
./frps -c frps.toml
成功启动后会看到类似 frps started 的日志。
- 关键步骤:在云厂商安全组中放行 TCP 端口
7000和你要暴露给用户的端口(如7614-7618)。
4.4 客户端配置(工控机 - frpc)
- 解压并进入目录。
- 编辑配置文件
frpc.toml(注意:每个代理必须单独用 [[proxies]] 声明,不要漏掉):
toml
# frpc.toml
serverAddr = "你的云服务器公网IP"
serverPort = 7000 # 与服务端 bindPort 一致
auth.method = "token"
auth.token = "your_secure_token_here" # 与服务端 token 一致
# 以下定义多个代理,每个对应一个内网服务
[[proxies]]
name = "api-server"
type = "tcp"
localIP = "127.0.0.1"
localPort = 7676
remotePort = 7614
[[proxies]]
name = "static-web"
type = "tcp"
localIP = "127.0.0.1"
localPort = 7667
remotePort = 7615
[[proxies]]
name = "web-server"
type = "tcp"
localIP = "127.0.0.1"
localPort = 7668
remotePort = 7616
[[proxies]]
name = "print-it"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8000
remotePort = 7617
[[proxies]]
name = "service-web-server"
type = "tcp"
localIP = "127.0.0.1"
localPort = 7688
remotePort = 7618
- 启动客户端(测试):
bash
./frpc -c frpc.toml
看到 start proxy success 表示连接成功。
4.5 远程访问测试
在任意能上网的电脑上:
bash
ssh -p 7614 工控机用户名@云服务器公网IP
输入工控机密码即可登录(假设代理的是 SSH 服务)。其他端口类似。
4.6 配置开机自启(systemd)
创建服务文件 /etc/systemd/system/frpc.service:
ini
[Unit]
Description=frp client
After=network.target
[Service]
Type=simple
ExecStart=/路径/frpc -c /路径/frpc.toml
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
然后执行:
bash
sudo systemctl daemon-reload
sudo systemctl enable frpc.service
sudo systemctl start frpc.service
服务端同理,只需把 frpc 改为 frps。
5. 安全建议
- 修改所有默认密码:云服务器SSH密码、frp的token、Web管理面板密码,都必须使用强密码。
- 开启认证:frp必须配置
auth.token,避免未授权客户端连接。 - 最小化端口暴露:只放行必须的
remotePort,不要全开。 - 云服务器安全组:仅对需要访问的IP段开放端口(如果能固定),或使用VPN叠加。
- 定期更新:frp和操作系统及时打补丁。
- 监控日志:定期查看
frps和frpc日志,发现异常连接及时处理。
7. 总结
- 内网穿透的必要条件:通信链路中至少有一个节点拥有公网IP(通常是云服务器)。
- frp 是自主可控、安全稳定的选择,适合企业生产环境。
- cpolar 等SaaS工具省心但受限于服务商,适合个人轻量使用。
- 核心配置要点:服务端放行端口、客户端正确配置
[[proxies]]、保持token一致。
通过本指南,你应该能独立完成从概念理解到实际部署的全过程。如有问题,可查看 frp 官方文档或查阅日志定位。
版本记录:本文档基于 frp v0.52+ TOML 配置编写,实践前请确认版本兼容性。