从零搭建FRP内网穿透:配置详解与实战指南 📅 2026/8/15 5:50:40 1. 项目概述为什么我们需要自己动手配置内网穿透如果你手头有一台放在家里的NAS或者在公司内网开发了一个Web服务想临时给客户演示又或者想远程访问办公室的电脑那你大概率会遇到一个头疼的问题这些设备和服务都在内网里没有公网IP从外部网络根本找不到它们。这就是内网穿透要解决的核心痛点。简单来说它就像给你的内网服务装了一个“专属快递员”frpc并在一台有公网地址的“中转站”frps那里挂了号。外部用户访问“中转站”的特定地址“中转站”就会把请求准确无误地“转运”到你的内网服务上。市面上内网穿透工具很多为什么偏偏是frp我用了这么多年核心就三点开源免费、配置灵活、性能稳定。它用Go语言编写单文件部署对服务器资源消耗极小。更重要的是它的配置逻辑清晰一个frps.ini定义中转站规则一个frpc.ini定义内网服务如何暴露这种“服务端-客户端”的经典架构让无论是简单的端口映射还是复杂的TCP/UDP/HTTP/HTTPS隧道都能通过修改配置文件轻松实现。相比于一些提供免费但限速、限流量的公共服务自建frp意味着完全的控制权、更高的带宽和绝对的隐私安全。接下来我就以一个典型的、拥有公网IP的云服务器作为服务端家庭内网的树莓派作为客户端的场景带你从零开始手把手拆解frps.ini和frpc.ini的每一个配置项并分享我趟过的坑和积累的技巧。2. 核心概念与架构拆解理解frp的工作流在动手编辑配置文件之前我们必须先彻底理解frp的架构和核心组件。这能让你在后续配置时清楚地知道每一行配置在全局中扮演什么角色出了问题该从哪里排查。2.1 核心组件frps与frpc的角色定位frp的架构非常清晰就是经典的C/S客户端-服务器模型frps (FRP Server)服务端。你必须将它部署在一台拥有公网IP地址的服务器上例如阿里云、腾讯云、AWS的云主机或者你家有公网IP且设置了端口转发的路由器后的某台机器。它的核心职责是“监听和转发”。它对外开放一个或多个端口如7000等待frpc来连接建立控制通道同时根据配置对外提供用户访问的端口如80, 443, 6000等将到达这些端口的用户流量通过已建立的控制通道转发给对应的frpc客户端。frpc (FRP Client)客户端。部署在你需要暴露的内网设备上比如你的办公电脑、家里的NAS、树莓派等。它的核心职责是“注册和等待”。它会主动连接到指定的frps服务器地址和端口认证身份并告知服务器“我这里有这些服务比如SSH、Web网站请帮我转发流量。”连接建立后它就开始等待frps转发过来的数据。注意很多人混淆了“访问方向”。用户永远不直接连接frpc。用户的访问路径是用户浏览器/客户端 -frps的公网IP:端口- frps - (通过内部隧道) - frpc - 内网目标服务。理解这一点对后续的防火墙配置至关重要。2.2 核心工作流程与协议支持一次完整的访问流程如下启动与注册在内网启动frpc它读取frpc.ini主动向frps.ini中定义的公网地址和端口发起连接并进行身份认证token验证。建立控制通道连接成功后frps和frpc之间会建立一个持久的控制连接。这个连接主要用于传输控制信息、保持心跳和传递新的代理请求。用户访问触发当外部用户尝试访问frps的某个特定端口例如访问your-server-ip:8080时frps会接收到这个请求。动态创建数据通道frps通过控制通道通知frpc“有用户要访问你注册的A服务了。”随后frps和frpc之间会为这次请求临时建立一个独立的数据通道对于TCP代理可能是一个新的TCP连接对于HTTP则复用连接处理HTTP请求。这个设计避免了所有流量都挤在一条连接里提升了并发性能。流量转发用户流量通过这个临时数据通道从frps完整地转发到frpc再由frpc转发给内网中真正的服务如本机的127.0.0.1:80。frp支持丰富的协议这决定了你该如何配置TCP最基础、最通用的转发。将frps的一个TCP端口透明地映射到内网服务的一个TCP端口。适用于SSH、远程桌面、数据库、游戏服务等任何基于TCP的协议。UDP用于转发UDP数据包。适用于DNS查询、视频流、某些游戏等。HTTP/HTTPS七层代理。frps可以识别HTTP协议根据域名subdomain或URL路径locations将请求转发给不同的内网Web服务。这对于在一台服务器上通过不同子域名暴露多个内网Web服务特别有用。HTTPS代理还能处理TLS解密https2http或透传https2https。STCP (Secret TCP)和SUDP一种更安全的P2P穿透模式。它要求访问端也运行一个特殊的frpc称为visitor并且双方都需要知道同一个“访问密钥”sk。流量不经过frps转发而是尝试在客户端和访问端之间直接建立连接仅在无法直连时才由frps中转。适用于需要更高安全性的内部服务访问避免了在frps上暴露端口。3. 服务端配置详解搭建稳固的中转站 (frps.ini)我们把frps搭建在一台公网云服务器上假设系统为Ubuntu 22.04。这是所有流量的入口其配置的稳定性和安全性是第一位的。3.1 基础安装与环境准备首先我们需要从frp的GitHub Releases页面下载对应系统架构的二进制文件。以amd64架构为例# 进入一个临时目录例如 /tmp cd /tmp # 下载最新版本的frp (请替换为实际版本号例如 v0.52.3) wget https://github.com/fatedier/frp/releases/download/v0.52.3/frp_0.52.3_linux_amd64.tar.gz # 解压 tar -zxvf frp_0.52.3_linux_amd64.tar.gz # 进入解压后的目录 cd frp_0.52.3_linux_amd64 # 查看文件我们会看到 frps frps.ini frpc frpc.ini ls -l我们需要的是frps服务端程序和frps.ini服务端配置文件。将其复制到合适的系统目录例如/usr/local/frp/# 创建目录 sudo mkdir -p /usr/local/frp # 复制服务端程序和配置文件 sudo cp frps /usr/local/frp/ sudo cp frps.ini /usr/local/frp/ # 进入该目录 cd /usr/local/frp3.2 frps.ini 核心配置项逐行精讲现在我们来编辑frps.ini。一个功能完备且安全的最小化配置如下[common] bind_addr 0.0.0.0 bind_port 7000 kcp_bind_port 7000 # 认证配置强烈建议设置这是安全的第一道防线 authentication_method token token your_strong_password_here # 仪表盘配置用于监控frps状态 dashboard_addr 0.0.0.0 dashboard_port 7500 dashboard_user admin dashboard_pwd another_strong_password # 日志配置 log_file ./frps.log log_level info log_max_days 3 # 连接限制与超时设置 max_pool_count 50 tcp_mux true我们来逐一拆解每个配置项的含义和配置理由[common]这是必须的节头所有通用配置都写在这里面。bind_addr与bind_portbind_addr 0.0.0.0表示监听所有网络接口这是标准做法。bind_port 7000是frpc连接frps的控制端口这是frp架构的“管理通道”必须开放。kcp_bind_portKCP是一种快速、可靠的ARQ协议在弱网络环境下高延迟、丢包比TCP体验更好。如果你需要通过移动网络访问或者网络质量不佳让frpc使用KCP协议连接在frpc.ini中设置protocol kcp会提升流畅度。这里设置和bind_port一样的端口frps可以同时处理TCP和KCP连接。authentication_method与token这是重中之重如果不设置token任何知道你的服务器IP和7000端口的人都可以连接上来占用你的资源甚至转发恶意流量。token是一个共享密钥frpc连接时必须提供相同的token才能认证通过。请务必使用高强度、无规律的密码。dashboard_*系列配置Web仪表盘功能。开启后你可以通过浏览器访问http://你的服务器IP:7500输入用户名密码查看所有frpc的连接状态、代理列表、流量统计等信息。对于运维和调试非常有用。同样仪表盘的密码也要设得复杂些。日志配置建议开启日志方便排查问题。log_level可以是trace,debug,info,warn,error。生产环境用info即可。log_max_days设置日志保留天数避免磁盘被占满。max_pool_count每个代理预创建的最大连接池数量。对于短连接服务如HTTP可以适当调低如5-10对于长连接如SSH保持默认或调高有助于快速响应。需要根据客户端数量和业务类型调整。tcp_mux是否启用TCP多路复用。默认为true强烈建议开启。它允许在frps和frpc之间的单个TCP连接上承载多个用户的并发请求极大地减少了连接数提升了性能和资源利用率。3.3 高级安全与性能调优配置基础配置能跑起来但要用于生产环境还需要考虑更多[common] # ... 上述基础配置 ... # 限制单个客户端可创建的代理数量防止某个客户端过度占用资源 max_ports_per_client 10 # 自定义二级域名后缀仅对HTTP/HTTPS类型代理有效 # 例如设置为 subdomain_host example.com客户端配置 subdomain web # 那么用户访问 web.example.com 就会被转发到该客户端。 # subdomain_host your_domain.com # TLS仅用于frps和frpc之间的控制通道加密与暴露的HTTP/HTTPS服务无关 # tls_enable true # 特权模式配置允许frpc配置某些敏感参数 # privilege_mode true # privilege_token another_privilege_token # privilege_allow_ports 2000-3000,3001,3003-3010max_ports_per_client一个重要的资源限制配置。假设你的token不慎泄露一个恶意客户端连上来后疯狂创建几百个代理端口会瞬间耗光你的服务器端口资源。设置此参数可以限制单个客户端能创建的代理数量。subdomain_host这是实现“基于域名的HTTP反向代理”的关键。你需要拥有一个域名例如example.com并将其DNS的A记录指向你的frps服务器IP。这样当客户端配置subdomain nas时用户访问nas.example.comDNS解析到你的服务器frps接收到HTTP请求根据Host头识别出是nas子域名然后转发给对应的frpc。非常优雅的解决方案。tls_enable为frps和frpc之间的控制通道启用TLS加密。这可以防止控制信息被窃听。注意这和你通过frp暴露的HTTPS网站type https是两回事。对于安全性要求极高的场景建议开启。特权模式默认情况下frpc不能配置某些可能影响服务器安全的参数如远程连接的本地IPlocal_ip 默认为127.0.0.1、特权端口1024等。开启特权模式并配置privilege_token和privilege_allow_ports后拥有特权token的客户端可以突破这些限制。非必要不开启如果开启务必使用独立的强token并严格限制允许的端口范围。3.4 系统服务化与防火墙配置手动运行./frps -c ./frps.ini不是长久之计。我们需要配置systemd服务让frps开机自启、自动重启。创建服务文件/etc/systemd/system/frps.service[Unit] DescriptionFrp Server Service Afternetwork.target [Service] Typesimple Usernobody Restarton-failure RestartSec5s ExecStart/usr/local/frp/frps -c /usr/local/frp/frps.ini ExecReload/usr/local/frp/frps reload -c /usr/local/frp/frps.ini LimitNOFILE1048576 [Install] WantedBymulti-user.target配置解析与实操心得Usernobody使用低权限用户运行服务是基本的安全准则。即使服务被攻破攻击者获得的权限也有限。Restarton-failure服务异常退出时自动重启增强稳定性。LimitNOFILE提高进程可打开的文件描述符数量上限。frp作为网络代理会持有大量socket连接默认的1024可能不够用特别是在高并发场景下。1048576是一个比较宽松的设置。ExecReload定义了重载配置的命令。当你修改了frps.ini后可以执行sudo systemctl reload frps来平滑重载配置而无需重启服务中断现有连接。接下来是防火墙这是最容易出问题的地方。假设你使用ufwUbuntu或firewalldCentOS必须放行相关端口# 对于 ufw sudo ufw allow 7000/tcp # frpc控制连接端口 sudo ufw allow 7500/tcp # 仪表盘端口如果开启 # 假设你还要通过frp暴露一个Web服务在8080端口 sudo ufw allow 8080/tcp sudo ufw reload # 对于 firewalld (CentOS/RHEL) sudo firewall-cmd --permanent --add-port7000/tcp sudo firewall-cmd --permanent --add-port7500/tcp sudo firewall-cmd --permanent --add-port8080/tcp sudo firewall-cmd --reload重要提示云服务器厂商如阿里云、腾讯云、AWS的安全组规则是另一道独立的防火墙也必须配置放行上述端口。很多人配置了系统防火墙却忘了安全组导致始终无法连接。4. 客户端配置实战暴露你的内网服务 (frpc.ini)服务端配置好后我们转到内网客户端。假设我们想暴露两个服务1内网NAS的Web管理界面HTTP2通过SSH远程登录这台内网机器。4.1 基础代理配置TCP与HTTP客户端的frpc.ini配置围绕一个个[proxy_name]的节展开每个节代表一个要暴露的服务。[common] server_addr your_server_public_ip server_port 7000 token your_strong_password_here # 必须与frps.ini中的token一致 # 示例1暴露SSH服务 (TCP代理) [ssh] type tcp local_ip 127.0.0.1 local_port 22 remote_port 6000 # 示例2暴露NAS的Web界面 (HTTP代理) [web-nas] type http local_ip 192.168.1.100 # NAS的内网IP local_port 5000 custom_domains nas.your-domain.com # 或使用 subdomain # 心跳与连接保持 heartbeat_interval 30 heartbeat_timeout 90[common]节这里配置连接服务端的参数。server_addr填你的云服务器公网IP或域名。server_port和token必须与frps中的设置严格一致。[ssh]代理type tcp声明这是一个TCP隧道。local_ip和local_port指定内网中真正提供服务的地址和端口。127.0.0.1:22表示本机的SSH服务。remote_port 6000这是用户在公网访问时使用的端口。用户需要连接your_server_public_ip:6000。你必须在frps服务器的防火墙上开放6000端口。配置好后你就可以用ssh -p 6000 usernameyour_server_public_ip来连接内网机器了。[web-nas]代理type http声明这是一个HTTP隧道。frps会解析HTTP协议。local_ip和local_port这里指向了内网中NAS的IP和Web端口例如群晖的5000端口。custom_domains这是关键。你需要将域名nas.your-domain.com的DNS A记录解析到你的frps服务器IP。当用户访问这个域名时frps会根据HTTP请求头中的Host字段匹配到这个代理规则然后转发流量。你也可以使用subdomain nas但前提是frps.ini中配置了subdomain_host your-domain.com。心跳参数heartbeat_interval和heartbeat_timeout用于保持控制连接活跃。在网络不稳定的环境中适当调小间隔如10秒和调大超时时间可以防止因短暂网络波动导致的频繁重连。4.2 高级代理类型与配置技巧除了基础的TCP和HTTPfrp还提供了更多场景的解决方案。HTTPS代理如果你内网的服务本身就是HTTPS的或者你想让frps直接处理TLS证书可以使用HTTPS代理。[https-web] type https local_ip 192.168.1.101 local_port 443 custom_domains secure.your-domain.com # 可选如果frps上配置了TLS证书可以启用 # plugin https2httpstype https代理HTTPS流量。此时流量在用户-frps和frps-frpc之间都是加密的frps不会解密内容只是透传TLS数据包。这要求用户访问的是https://secure.your-domain.com。plugin https2https这是一个高级插件用于在frps上终止TLS使用frps的证书然后以HTTPS或HTTP协议与frpc通信。这需要你在frps端配置证书适用于统一管理证书的场景。STCP (安全TCP) 代理这是一种点对点的模式不在frps上暴露公网端口更安全。# 在需要被访问的内网机器服务端上配置 [secret-ssh] type stcp sk my_secret_key_123 # 访问密钥双方需一致 local_ip 127.0.0.1 local_port 22 # 在想要发起访问的机器访问端上配置 [secret-ssh-visitor] type stcp role visitor server_name secret-ssh # 要访问的代理名 sk my_secret_key_123 # 必须与上面一致 bind_addr 127.0.0.1 bind_port 6001在服务端配置一个type stcp的代理并设置一个共享密钥sk。在访问端配置一个role visitor的代理指定要访问的server_name和相同的sk。访问端启动后会监听本地的bind_port如6001。此时在访问端机器上执行ssh -p 6001 user127.0.0.1流量会通过frp的STCP机制尝试与内网服务端直连或通过frps中转最终到达内网机器的22端口。整个过程frps的防火墙无需开放6000这样的远程端口提升了安全性。负载均衡与健康检查对于需要高可用的服务可以在多个内网服务器上部署相同的frpc代理并配置相同的代理名。frps会自动将流量负载均衡到这些客户端上。此外可以配置health_check_type和health_check_timeout_s等参数让frps自动剔除不健康的后端。4.3 客户端部署与管理与服务器类似客户端也需要稳定运行。在Linux上同样建议配置为systemd服务。Windows上可以配置为服务或用nssm工具封装。Linux客户端服务文件示例 (/etc/systemd/system/frpc.service)[Unit] DescriptionFrp Client Service Afternetwork.target [Service] Typesimple Usernobody Restarton-failure RestartSec5s ExecStart/usr/local/frp/frpc -c /usr/local/frp/frpc.ini ExecReload/usr/local/frp/frpc reload -c /usr/local/frp/frpc.ini LimitNOFILE1048576 [Install] WantedBymulti-user.target一个关键的实操心得对于客户端尤其是笔记本电脑等可能频繁变更网络的设备建议在[common]节中加入以下配置[common] # ... 其他配置 ... login_fail_exit falselogin_fail_exit false会让frpc在连接frps失败时例如网络断开不断尝试重连而不是直接退出。这对于移动环境非常有用。5. 故障排查与性能优化实录即使配置看起来正确在实际部署中也难免遇到问题。这里记录几个最常见的问题和我的排查思路。5.1 连接类问题排查清单问题现象可能原因排查步骤frpc启动报错:connection refused1. frps未启动。2. 服务器防火墙/安全组未开放bind_port默认7000。3.server_addr填写错误。1. 登录服务器systemctl status frps查看状态sudo netstat -tlnp | grep :7000检查端口监听。2. 检查服务器ufw/firewalld和云平台安全组规则。3. 在客户端用telnet server_ip 7000或nc -zv server_ip 7000测试端口连通性。frpc连接超时或卡住1. 网络路由问题。2. 服务器或客户端存在出站/入站限制。1. 在客户端尝试ping服务器IP检查是否有丢包和高延迟。2. 检查客户端防火墙是否允许frpc出站连接。3. 尝试在frpc.ini中设置protocol kcp使用KCP协议可能改善弱网连接。能连接但无法访问暴露的服务1.remote_port或 HTTP域名未在服务器防火墙/安全组开放。2. frpc配置的local_ip或local_port错误内网服务未启动。3. 对于HTTP/HTTPS代理域名DNS解析未生效或未配置。1.再次确认服务器防火墙和安全组这是最高频的错误开放你配置的remote_port如6000, 8080或HTTP端口80,443。2. 在frpc所在机器用curl http://local_ip:local_port或telnet local_ip local_port测试内网服务本身是否正常。3. 使用nslookup your-domain.com检查域名是否已正确解析到服务器IP。仪表盘无法访问1.dashboard_port未在防火墙开放。2. 配置的dashboard_addr是127.0.0.1只允许本地访问。1. 确保服务器防火墙和安全组开放了dashboard_port如7500。2. 确认dashboard_addr 0.0.0.0。5.2 性能与稳定性调优经验连接池与多路复用确保tcp_mux true默认开启。对于大量短连接HTTP服务可以适当降低pool_count在代理配置中设置如pool_count 5以减少服务器资源占用。对于SSH、远程桌面等长连接保持默认或增加pool_count有助于快速建立新连接。心跳与超时在跨国或高延迟网络中默认的心跳间隔30秒和超时90秒可能太短导致频繁重连。可以适当调整[common] heartbeat_interval 60 heartbeat_timeout 180 # 控制连接的总超时 dial_server_timeout 10 dial_server_keepalive 7200日志排查遇到问题时第一时间查看日志。在frpc.ini和frps.ini中设置log_level debug可以获取最详细的运行信息帮助定位问题。生产环境排查后记得改回info级别。资源限制在frps服务器上使用ulimit -n查看文件描述符限制。如果代理连接数很多超过1024需要在systemd服务文件或系统层面提高这个限制否则会出现“too many open files”错误。带宽监控frps仪表盘提供了基本的流量统计。对于更详细的监控可以考虑配合Prometheus和Grafana如果frps版本支持metrics或者使用服务器自带的工具如iftop,nethogs监控网卡流量避免服务器带宽被未知流量占满。5.3 安全加固要点强Token认证这不再赘述是必须项。最小化端口暴露只开放必要的端口。例如如果只用HTTP/HTTPS代理可以只开80/443和7000端口关闭无用的remote_port。使用特权模式白名单如果必须使用特权模式务必用privilege_allow_ports严格限定允许的端口范围避免客户端滥用。定期更新关注frp项目的GitHub Releases定期更新到稳定版本修复潜在的安全漏洞。隔离运行使用nobody或新建的专用低权限用户运行frps/frpc进程。HTTPS与TLS对于Web服务尽量使用type https或配置域名SSL证书。对于控制通道可以考虑开启tls_enable。配置frp内网穿透从简单的端口映射到复杂的基于域名的Web服务暴露其核心在于理解“流量走向”和“配置对应关系”。每一次配置其实都是在清晰地告诉frps“当有流量以某种方式某个端口或域名来到你这里时请通过那条我建立好的隧道原封不动地送到我内网的这个地址上。” 理清这个逻辑再结合详细的日志和循序渐进的排查绝大多数问题都能迎刃而解。这套自建的内网穿透方案在稳定运行了几年后其可控性和性价比依然是任何第三方免费服务无法比拟的。