
1. 一个老运维眼里的内网穿透frp到底解决了什么干了多年运维和开发内网穿透这件事基本是绕不开的坎。开发阶段要在本地调试第三方回调接口临时要给客户演示一个部署在公司内网的Demo系统居家办公要连回办公室的测试服务器——这些场景背后都指向同一个需求让公网能够访问到处于内网环境里的服务。frpFast Reverse Proxy是我用下来最顺手的一套开源反向代理方案。它的核心思路特别朴素内网机器主动向外网一台有公网IP的服务器建立长连接公网服务器收到外部请求后通过这条已经打通的隧道转发给内网机器。相当于内网服务自己在公网服务器上挂了个号外部流量顺着这个号就能找到它。这篇内容不打算写成frp的官方文档翻译而是基于我实际部署过的多个项目把免费版frp从原理、部署、配置到踩坑经验完整串一遍。无论你是刚接触内网穿透的入门玩家还是已经在生产环境里跑frp但希望优化得更稳的开发者这篇都能提供一些可直接照抄的实践经验。需要提前说明的是frp的合法用途非常明确远程办公、开发调试、设备管理、临时演示都属于典型场景。在合规前提下使用工具才能真正发挥它的价值。下面进入正题。2. frp的工作机制拆解客户端主动出网服务端被动转发2.1 为什么反向代理能穿透内网传统的端口映射思路是让公网流量直接进入内网但大多数家庭宽带和办公网络根本没有公网IP运营商还经常封禁入站端口。frp反其道而行之——让内网机器主动向公网服务器发起连接。这个设计的关键在于一般的防火墙只拦截未经请求的入站包但不拦截内网主动发起的出站连接。frp客户端frpc在公网服务器frps上建立长连接后这条通道实际上是从内到外的公网流量到达frps后通过这个已经建立的隧道原路转进内网从而绕开了 NAT 和防火墙的入站限制。我用一个生活化的类比来解释公网服务器像一个前台接待内网服务是办公室里的人。办公室没有对外的大门但办公的人可以主动打电话到前台说我在这里。外部访客来了前台通过电话线把访客的需求转达给办公室里的人再把答复传回来。frp就是这个电话线和前台登记系统。2.2 两个核心组件的分工frp由两部分组成frps部署在具有公网IP的服务器上负责监听端口、接收客户端注册、转发流量。frpc部署在内网目标机器上主动连接frps并注册自己提供的服务。frpc注册时会告知frps我在内网提供了某某服务端口是多少frps则把这个信息映射到自己公网侧的某个端口。外部用户访问服务器IP:映射端口流量就通过frps中转到达内网服务。这里有个容易被忽略的点frps本身并不存储业务数据它只是一个流量搬运工。所以frps服务器的带宽直接决定了穿透后服务的访问速度。如果只是调试HTTP接口1M带宽的小水管也够用如果要传大文件或者跑桌面远程控制建议至少5M以上。2.3 免费版frp与商业版思路的差异现在市面上其实有不少免费内网穿透服务很多都是基于frp二次开发的商业平台。这些平台帮你托管了frps服务器你只需要装他们的客户端即可。好处是零门槛坏处是免费额度通常有限制——带宽限制、连接数限制、域名随机分配、不稳定等。自己搭建frps则意味着完全掌控不限制隧道数量、可以使用自己的域名、可以配置TLS加密、可以做流量限制和鉴权。一台便宜的云服务器加上frp就能搭建出媲美商业产品的穿透服务。这也是我为什么坚持推荐自己部署的原因——配置一次长期受益。3. 部署frps前必须想清楚的几个选型问题3.1 服务器怎么挑frps对服务器性能要求极低主要瓶颈在带宽和流量。以最低配的1核1G云主机为例跑frps完全足够OSS和网络带宽才是关键指标。选择机房时可以优先考虑离你实际使用地域近的节点延迟会低不少。如果预算有限有几点提示按量付费的带宽计费模式比固定带宽更适合frps因为穿透流量的使用往往集中在工作时间段。服务器操作系统建议选Debian或Ubuntufrp官方对Linux的支持最完善systemd服务管理也方便。如果服务器在国内需要确保已完成ICP备案才能绑定自己的域名否则建议用IP加端口的方式访问或者选择海外节点搭配自己的域名。3.2 公网IP与端口的规划frps默认监听7000端口用于frpc注册连接这个端口可以自定义但建议别用常见端口如22、80、443避免被扫描器盯上。我习惯把frps的bindPort设为7000以外的数值比如17000。对外提供服务时HTTP类型的代理默认监听80端口HTTPS默认443但云服务器安全组里需要显式放行这些端口。为了避免冲突我通常会让frps的vhostHTTPPort使用8080vhostHTTPSPort使用8443然后在Nginx里做一层反向代理和域名转发。这样做的额外好处是可以在Nginx层统一配置WAF规则、访问日志和限流策略。3.3 认证与安全的前置配置frp从0.34版本开始全面支持Token认证。frpc和frps之间必须配置相同的token否则连接会被拒绝。Token的强度建议用类似生成密码的方式生成一段随机字符串不要用什么123456这种。更高阶的做法是配置TLS# frps.toml bindPort 17000 auth.method token auth.token 你的强密码token transport.tls.force true对应frpc侧# frpc.toml serverAddr 你的服务器IP serverPort 17000 auth.method token auth.token 你的强密码token transport.tls.enable true这样frpc到frps之间的通信会走TLS加密避免流量在公网传输时被中间人截获。值得说明的是frp在更新到0.52版本之后配置文件格式全面转向TOML旧版INI格式虽然仍兼容但新项目建议直接采用TOML官方文档也更侧重这个方向。4. frps frpc从零配置全记录一套可直接复用的模板4.1 下载与安装frp的发布包可以从GitHub的Release页面获取。以Linux x86_64环境为例# 下载指定版本这里以0.61.0为例 wget https://github.com/fatedier/frp/releases/download/v0.61.0/frp_0.61.0_linux_amd64.tar.gz # 解压 tar -zxvf frp_0.61.0_linux_amd64.tar.gz # 进入目录 cd frp_0.61.0_linux_amd64目录下会看到frps、frpc二进制文件以及对应的TOML示例配置。把frps复制到系统路径sudo cp frps /usr/local/bin/frpc则按需部署如果内网机器是Linux同样处理如果是Windows直接下载windows_amd64的对应包。4.2 配置frps创建/etc/frp/frps.tomlbindPort 17000 auth.method token auth.token 这里填你的强密码 # 启用面板 webServer.addr 127.0.0.1 webServer.port 7500 webServer.user admin webServer.password 这里填面板密码 # HTTP虚拟端口 vhostHTTPPort 8080 vhostHTTPSPort 8443 transport.tls.force true log.to /var/log/frps.log log.level info log.maxDays 7注意webServer.addr我设置为127.0.0.1这样面板只能本机访问。如果需要远程查看面板建议通过SSH隧道访问而不是直接把7500端口暴露到公网。面板主要用于查看连接状态和流量统计实际调试场景中价值很大。4.3 配置frpc内网机器上的frpc.toml示例serverAddr 你的服务器IP serverPort 17000 auth.method token auth.token 这里填强密码 transport.tls.enable true [[proxies]] name ssh-local type tcp localIP 127.0.0.1 localPort 22 remotePort 6022 [[proxies]] name web-demo type http localIP 127.0.0.1 localPort 3000 customDomains [demo.example.com]上面这段配置做了两件事把内网的22端口映射到服务器公网的6022端口用于SSH远程登录。把一个本地3000端口的Web服务通过HTTP类型代理暴露并绑定域名demo.example.com。HTTP类型代理需要域名解析到服务器IP并且必须通过域名访问不能直接用IP加端口访问。如果你只有一个域名但需要暴露多个服务可以用不同的子域名来实现。4.4 使用systemd托管手动启动frps的方式只适合测试生产环境建议用systemd管理。创建/etc/systemd/system/frps.service[Unit] Descriptionfrps Afternetwork.target [Service] Typesimple ExecStart/usr/local/bin/frps -c /etc/frp/frps.toml Restarton-failure RestartSec5 [Install] WantedBymulti-user.targetfrpc的服务配置同理替换路径即可。然后sudo systemctl daemon-reload sudo systemctl enable frps sudo systemctl start frps学会看日志排查问题很关键sudo journalctl -u frps -f sudo tail -f /var/log/frps.log5. 免费方案怎么选自建frp与传统方案对比市面上提到免费内网穿透大体有这几条路线自建frps、使用第三方免费穿透服务、使用其他开源隧道工具。我把实际体验整理成一张对比表方案成本稳定性可定制性适用场景自建frps需要一台云服务器完全取决于自己服务器极高长期稳定使用、多隧道、生产环境第三方免费穿透平台零成本但有额度和带宽限制免费额度受平台控制一般临时测试、快速验证其他开源隧道工具如ngrok自托管同样需要服务器依赖自身部署较高特定场景下的替代选择我个人的观点是如果你手头已经有一台云服务器自建frps是毫无悬念的首选。它不产生额外费用一个frps可以挂无数个frpc且所有流量都在自己的掌控范围内。而第三方免费平台虽然零成本但免费用户往往需要忍受随机域名、限速、连接数限制以及不定期的服务不稳定。当然如果连服务器都没有只是想临时暴露一个本地端口给对方看一眼第三方平台反而更省事。这类平台普遍支持一条命令启动隧道五分钟内解决问题。但从把数据握在自己手里这个角度讲自建frp的长期价值明显更高。6. 高频踩坑实录这些毛病我都在生产环境里踩过6.1 frpc连接被拒绝日志提示EOF这是最常见的问题原因通常是frpc与frps的版本不匹配。frp的作者在版本更新时会调整协议老版本frpc连接新版本frps时经常会在握手阶段出现EOF错误。排查顺序确认两端版本号一致frps -v和frpc -v确认frps的bindPort没有被防火墙拦截用telnet 服务器IP 17000测试确认token一致包括首尾空格版本统一是frp部署的第一铁律。我曾在一次升级中只更新了服务端忘了同步客户端结果一堆设备全部断连排查了半小时才发现是版本问题。6.2 HTTP代理访问返回404HTTP类型代理配置了customDomains域名也解析了但访问就是404。这时候检查两点访问是否带了端口如果vhostHTTPPort设的是8080那么访问地址应该是http://demo.example.com:8080除非在Nginx做了反向代理否则不带端口访问默认80端口自然404。域名解析是否正确通过dig demo.example.com确认解析到了服务器IP。6.3 穿透的TCP服务频繁断连如果映射的是数据库这类长连接服务经常出现建立连接后一段时间就断开的现象。原因多半是frpc和frps之间的心跳参数没调好。相关配置项# frps.toml transport.heartbeatTimeout 90 # frpc.toml transport.heartbeatInterval 30frpc默认每隔30秒发送心跳包frps如果90秒没收到心跳就判定连接断开。如果内网网络质量较差可以适当调大heartbeatTimeout或者增加TCP的keepalive设置。这类参数需要结合实际的网络情况做适配没有放之四海而皆准的值。6.4 使用STCP类型实现点对点通信frp的STCP类型经常被忽略但它非常适合服务不想暴露在公网只想让特定客户端访问的场景。举个例子我在内网有一台Redis服务器公网的开发机需要连它做数据管理又不希望Redis端口直接映射到公网被所有人扫到。用STCP类型就可以实现frpc配置内网Redis机器[[proxies]] name redis-secret type stcp secretKey 你的密钥 localIP 127.0.0.1 localPort 6379需要访问的客户端frpc配置[[proxies]] name redis-secret-visitor type stcp role visitor serverName redis-secret secretKey 你的密钥 bindAddr 127.0.0.1 bindPort 16379这样只有在frps上注册了相同secretKey的visitor才能建立到Redis的隧道外部完全无法感知Redis的存在。Redis客户端直接连本机的16379端口即可。这种模式在安全要求较高的场景中很有价值。我把生产环境中部署在公网的数据库映射全部改成了STCP安全性提升了一个档次。6.5 面板显示在线但流量不增长面板上的连接数和流量数据是通过frps统计的。如果内网服务本身没有请求进来流量自然不增长。排查时优先确认访问的端口、域名是否正确再确认frpc所在机器能否正常访问内网服务本身。我记得有一次用户反馈穿透后打不开系统结果排查发现frpc所在的机器上服务根本没有启动。frp就像一个电话总机它负责接通线路但对方办公室没人接电话问题当然不在总机。7. 如何把frp做得更顺手进阶优化与安全加固7.1 用Nginx统一入口管理多个HTTP服务当穿透的HTTP服务变多直接在frps上开放多个vhost端口并不优雅。更推荐的做法是frps只开放一个HTTP端口然后在Nginx里按域名转发到frps的对应vhost端口server { listen 80; server_name demo.example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }这样外部访问的是标准的80端口URL里不用带一串自定义端口也更符合用户习惯。HTTPS证书也可以在Nginx层统一配置配合certbot自动续期比在frps里配置TLS证书要省心得多。7.2 frpc的配置热加载frpc支持在不重启进程的情况下重新加载配置。修改frpc.toml后执行frpc reload -c /etc/frp/frpc.toml也可以用frpc verify -c /etc/frp/frpc.toml先校验配置语法是否正确。这两个命令配合起来改配置基本不会引入事故。我习惯每次修改配置前先verify确认无语法错误再reload。frps侧修改配置则需要重启服务因为frps的监听端口、认证信息等属于全局配置不像frpc的代理项可以热更新。7.3 安全加固的几个实操建议云服务器安全组只放行必要端口frps的bindPort、vhost端口、面板端口都要最小化暴露。frps面板端口不要映射到公网必须访问时用SSH隧道ssh -L 7500:127.0.0.1:7500 用户服务器IPToken定期更换建议写在自动化脚本里按月或按季度轮换。如果穿透的是Web服务务必在Nginx层加访问认证或IP白名单避免服务意外暴露后被扫描器盯上。日志定期清理frps的maxDays参数设置为7到30天即可。7.4 XTCP模式P2P直连的进阶玩法frp的XTCP模式比STCP更进一步它尝试在两个frpc之间建立P2P直连frps只负责打洞和协调不中转业务流量。这样能够有效减轻frps的带宽压力适合视频流、大文件传输等场景。XTCP的配置思路与STCP类似但需要额外指定transport.protocol xtcp。打洞的成功率取决于双方的NAT类型全锥形NAT环境下成功率较高对称NAT环境下往往退化到走frps中转。我在实际测试中大约七成环境能成功建立P2P连接剩下的三成由frps自动兜底。8. 写在最后的实操体会frp这套工具的妙处在于简单的东西做到极致。它没有花哨的功能但反向代理的机制设计得非常精巧以至于多年过去它依然是内网穿透领域应用最广泛的开源方案之一。如果要给刚接触frp的朋友一条实践路径我建议是先用最低成本的配置跑通一个SSH隧道感受一下整个链路的建立过程然后逐步添加HTTP代理、配置TLS、使用STCP保护敏感服务。每一步都尽量理解背后的原理而不是直接复制配置了事。我踩过的最大的坑是盲目追求功能全面在配置里堆了一大堆用不上的参数结果出了问题反而不知道从哪排查。后来学乖了配置保持最小化每增加一个参数都弄清楚它的作用。frp的文档质量很高建议遇到不确定的参数时优先查阅官方文档对应版本的内容而不是直接在网络上搜索过时的配置片段。最后分享一个实际经验frp这个工具用得越久越能体会稳定压倒一切。与其频繁折腾新功能不如把基础配置做扎实、监控做好让它在后台默默工作。当你在异地的电脑上顺利连回办公室的服务器时那种一切都按预期运转的感觉就是运维工作最踏实的回报。