内网穿透:frp 与反向代理
先看清楚场景
远程访问家里的服务,想法很自然:出差时想看 NAS 里的电影,或者在外面给智能家居发指令。但公网 IP 越来越稀缺,大多数家庭宽带拿到的都是运营商内网地址,直接做端口转发行不通。解决这个问题分两条路:一条是组虚拟内网,让外部设备与家里同处一个局域网,比如 ZeroTier 与 Tailscale;另一条是反向代理,让家里主动连到一台公网服务器上,把请求倒着带回来,frp 就是这一类的代表。
两条路定位不同:组网方案适合固定几个人用,私有性强,装了客户端的设备才能访问;反向代理适合服务要给陌生人或临时设备访问的场景,比如把密码管理器、个人博客公开出去。本文只讲反向代理这条线,另一条线见组网一章。所有场景都以自有设备合规使用为前提:访问的内容与流量都合法,穿透链路只用来连自己的家庭服务器。

frp 的服务端与客户端
frp 分为服务端 frps(部署在有公网 IP 的机器上)与客户端 frpc(部署在家里)。配置文件从 0.52 版本起推荐 TOML 格式,老教程里的 ini 写法已经弃用。服务端最小配置就一行端口:
# frps.toml
bindPort = 7000
# 建议加上鉴权,防止陌生客户端连入
auth.method = "token"
auth.token = "改成一长串随机字符串"
客户端对应写法:
# frpc.toml
serverAddr = "你的公网IP"
serverPort = 7000
auth.method = "token"
auth.token = "与服务端一致"
[[proxies]]
name = "nas-web"
type = "tcp"
localIP = "192.168.1.10"
localPort = 5000
remotePort = 7500
这段配置把家里 192.168.1.10 的 5000 端口映射到公网服务器的 7500 端口,外部访问 服务器IP:7500 就等于直接访问家里的 NAS 网页。配置写完先验证:frpc verify -c frpc.toml,提示 ok 再启动。服务端 ./frps -c frps.toml,客户端 ./frpc -c frpc.toml,客户端日志出现 login to server success 即链路打通。
部署细节与常见坑
云服务器上首先要放过行端口。多数云平台的入站规则由控制台安全组管理,系统防火墙关了也没用,必须同时放行 7000 与每个 remotePort。其次是端口占用:服务器上如果已经跑着别的服务占用了 80 或 443,remotePort 就别再映射它们,先 ss -tlnp 确认空闲。第三点是客户端的稳定性:frpc 进程退了链路就断,建议用 systemd 服务管理,让它开机自启、崩溃重启。服务端同理。最后是心跳与重连,默认配置已足够,不要随便改日志级别,线上排查全靠日志。
frp 的部署位置也有讲究。服务端理所当然放公网云服务器,客户端放哪里却有流派:有人把 frpc 装在软路由上,由路由负责代理全家流量;有人单独起一个容器或虚拟机专门跑 frpc,各服务通过它中转。前者的好处是单一入口、管理集中;后者的好处是隔离性好,软路由重启走的是另一套依赖链,怎么选取决于你对单点故障的容忍度。无论哪种做法,都把 frpc 的配置文件纳入版本管理,哪天改坏了能立刻回退。
做长效运行规划时还要给链路留监控。最省事的方式是在公网服务器上对一个固定映射端口做定时探测(比如每两分钟一次),连续两三次失败就在告警群里喊人。配合这台云服务器自身的监控,整条穿透链路的可用性就有了基本盘数据,而不是等家人打电话告诉你网断了才知道。
再讲一个安全要点:frps 的 dashboard(7500 端口的统计页)默认不开,开了也务必加口令并改成非常用端口,否则裸奔的统计页等于把你的网络结构免费展示给扫描器。所有穿透服务的登录口令一律按“字母数字符号混合、长度十六位以上”的标准生成,用密码管理器存好——家庭服务器虽然是自用,但公网上的弱口令每天被成千上万次尝试是常态。

安全加固清单
服务上线后务必做安全加固:token 要足够长足够随机;映射出去的服务该套HTTPS的套HTTPS,密码弱的服务等于公开裸奔;公网服务器的资源有限,frps 的连接数不用额外限制,但你映射的每个服务都暴露在公网扫描之下,非必要不映射行政类端口(比如 SSH 管理端口),实在要映射就改 remotePort 到五位数以上并配合 fail2ban 一类的工具。
| 常见症状 | 原因 | 处理 |
|---|---|---|
| 客户端连不上 | 安全组或防火墙 | 放行 7000 与 remotePort |
| 登录成功但访问超时 | remotePort 被占用 | 换端口或先清理占用 |
| 链路时断时连 | 客户端不稳定 | systemd 重启策略 |
| latency 偏高 | 服务器距离远 | 换就近机房 |
配合反向代理与域名
纯 TCP 映射记 IP 加端口太土,正式用法是配合域名:把 frp 的 http 类型代理与 customDomains 搭配,不同子域名转向家里不同服务。想给每个子域名都套 HTTPS,最成熟的组合是公网服务器跑 Nginx 或 Caddy 做前置反代,后端指向 frp 暴露出的本地端口,由反代统一处理证书申请与续期。Caddy 的配置最省心,两行就能自动申请证书。
# frpc.toml 改用 http 类型
[[proxies]]
name = "photo"
type = "http"
localIP = "192.168.1.10"
localPort = 8080
customDomains = ["photo.example.com"]
换上 https 类型时还能配合 frp 的 HTTPS 卸载选项,把加密留在服务端,家庭链路走加密隧道、解密后转内网,性能与维护性都不错。不过要注意证书一旦放在公网服务器上,就等于让这台服务器成为整条链路的可信节点,服务商的选择自己心里要有杆秤。
链路的健康监控
穿透链路的可用性不能靠体感。核心指标有三个:客户端到服务端的隧道保活状态、最近一周的连接成功率、个别服务的响应延迟。在云服务器上可以用最简单的定时 curl 脚本记录这三个数字,或者挂一个 Uptime 类的页面统一看。发现规律性故障(比如每天晚上固定断几次)先怀疑运营商 QoS 与长连接超时,尝试调整 keepalive 超时参数或开启 frp 的心跳加密与压缩版本兼容。
带宽是这个链路最稀缺的资源。家用云服务器多数是 1 至 3 兆的小水管瓶颈,穿透使用体验设计就围绕它:浏览 NAS 列表与 Thumbnails 缩略图走得动,在线播放蓝光就是折磨。预览与快速查阅走穿透链路、真正的大文件下载走 IPv6 直连或远程回家拷贝,这套组合拳才是小型链接下的正确姿态。监控里把穿透的实际吞吐也画上图,才好判断要不要升级服务器带宽。
家用穿透还有一种省事形态:只给自己人用、不发布任何公开服务。这种情况下 frp 的配置可以化简到极致——只映射一个内部服务的端口、套上 token、客户端 systemd 常驻。无需域名、无需反代、无需证书,五分钟搭好一条私用隧道。它适合“偶尔远程进内网修个东西”的场景,是工具箱里最趁手的螺丝刀。
对外的正式服务则把反向代理那一层做扎实:Caddy 做前置自动证书、frp 做隧道、应用只跑内网端口。三层各管一段,日志分开看,排错时按层定位。这套结构跑了几年都不需要大改,是家庭穿透方案里最稳定的形态。
再补一条容量纪律:穿透服务上云之前先量一下实际需要多少带宽。云服务器的带宽计费方式各有不同(按固定带宽与按流量两种),家用场景通常按流量更便宜——除非你每天都要通过链路看家庭影音。小水管(1 至 3 兆)覆盖浏览、看图、小文件传输完全够用,月费可以压到一杯咖啡的量。先从小规格开始,监控里看半年实际吞吐再决定是否升级,能避免 90% 的超配浪费。
给一条纯运维向的建议:云服务器一期租三年。年付的折扣通常在三到五折之间,单年续费看似便宜,三年下来差价足够再租一年。唯一的风险是服务商跑路,选头部云厂商基本可控。把这条与“钉镜像版本”的纪律对照看:容量上敢投入(确定要长期用),配置上敢保守(怕升级出事),两者并不矛盾。
最后的取舍
穿透方案年年有新花样,但 frp 这类反向代理作为基石型工具的地位一直没变:协议透明、行为可预测、配置文件一目了然、出问题看日志就懂。对家用场景它还有个隐藏优点——全程只转发你自己明确配置的端口,没有黑盒的“智能路由”。确定性在长期运维里比任何花哨功能都珍贵,这是 frp 值得作为家庭远程访问首课的原因。
延伸阅读
- 计算机网络入门:理解反向代理与端口映射的原理,配 frp 事半功倍。
- SSH 远程登录与加固:frpc 与宿主机都用 systemd 管理,SSH 是常用的远程操作底座。
