frp 应该算是我日常折腾服务器时用得最频繁的内网穿透工具没有之一。它的用途非常直接一台机器在内网里没有公网地址外部网络访问不到那就用另一台有公网地址的服务器做中转把内网端口“映射”出去让外部网络能通过公网服务器访问到内网服务。frp 配置看着不复杂核心就两个配置文件一个跑在有公网地址的服务器上一个跑在内网机器上但真正花时间的地方几乎都在常见错误排查上——token 对不上、端口被占用、安全组没放行、systemd 起不来、日志里反复出现 EOF 或 connection refused。这篇文章我把 frp 配置和 frp 常见错误放在一起梳理一遍既能当新手快速上手的文档也能当排查问题时的参考手册。1. 先把 frp 的原理和应用场景讲清楚1.1 frp 到底解决的是一个什么问题frp 解决的本质上是一个“内网可达性”的问题。假设你在办公室有一台开发机家里还有一台 NAS它们只有内网地址外面的人从公网直接访问不到而你恰好有一台带公网地址的云服务器这时候 frp 就能在两者之间搭一条专用的转发通道。外人访问公网服务器的某个端口时数据会被原样送到你家或者办公室的内网机器上看起来就像这台内网机器直接暴露在了公网上。说白了frp 就是把“公网服务器”当成一个接待前台所有从外部进来的请求先到达前台前台再根据登记信息把请求转给真正干活的“内网服务”。这个过程对内网服务是完全透明的它不会感知到访问流量绕了这么一圈。理解了这个模型后面配置和排错就顺了。你会发现很多常见错误其实都是“前台”和“内网服务”之间信息不一致导致的比如登记地址写错、口令对不上、端口被别的服务抢占了。1.2 frps 与 frpc 的角色分工frp 有两个核心角色名字比较像但职责完全不同。frps 是服务端跑在有公网地址的那台机器上。它负责监听一个固定端口接受来自客户端的注册请求也接受来自外部网络的访问请求然后按配置把流量转到对应的内网目标。frpc 是客户端跑在你需要被访问的内网机器上。它主动去连接 frps把自己本地的某个端口“登记”到服务端登记完成后只要服务端的对应端口收到访问流量就会被转到 frpc 这边的本地服务。这里最关键的一点是连接永远是内网机器主动发起的。即便内网机器没有公网地址、处在 NAT 后面只要它能正常访问外网就能通过 frpc 把通道建立起来然后实现外部网络对内部服务的访问。这也是 frp 这类工具适用面广的原因不需要在路由器上做端口映射也不需要内网机器真的拥有公网 IP。1.3 哪些场景适合用 frp从应用场景看frp 适合做的工作不外乎这几类远程 SSH 登录内网服务器比如在家里连公司内网的开发机。把本地正在开发的 Web 接口暴露出去给前端、测试同学联调用。在外访问家里的 NAS、路由器管理页面或个人网盘。通过 stcp 这类方式做点对点加密通信只在两端建立临时访问关系不把服务直接暴露到公网。需要提醒的是frp 更适合临时的、小型的、个人或小团队的使用场景。如果你要做高可用或者入口要扛大规模流量建议还是考虑更成熟的负载均衡体系。frp 的定位始终是轻量通道工具不是流量分发系统超出了它的边界反而容易把自己坑进去。2. 开始配置前需要准备哪些基础条件2.1 一台有公网地址的服务器怎么确认frp 服务端必须有一台能被外网直接访问的机器最常见的就是云服务器。你首先要确认这台服务器的公网地址是真实、可用的。可以通过ip addr看网卡地址也可以执行curl ifconfig.me查看出口 IP然后跟云厂商控制台显示的公网 IP 做对比。如果两者不一致说明机器可能处在云平台内部 NAT 后面访问还是要看控制台那个公网地址。另外提前在纸上记一下后面会用到的端口frps 接收 frpc 连接的端口我习惯用 7000、控制面板端口比如 7500、要映射出去的 remotePort比如 16022。这样配置时不至于一团乱麻。2.2 下载安装包与选择合适架构frp 的发布包放在 GitHub Releases 页面文件命名一般是frp_版本号_系统_架构.tar.gz。Linux x86 服务器下载linux_amd64的包。树莓派或 ARM 开发板下载linux_arm64或linux_arm。mac 本地下调试下载darwin_amd64或darwin_arm64。下载前先用uname -m确认架构x86_64 对应 amd64aarch64 对应 arm64别不看架构就直接解压跑否则很可能遇到Exec format error这种启动失败。2.3 frp 目录结构和配置文件初识解压之后你会看到 frps、frpc、以及带.toml后缀的配置模板文件。这里要特别提醒一点frp 在较新的版本里已经统一使用 TOML 配置格式默认读取frps.toml和frpc.toml。网上很多老教程还在用frps.ini、frpc.ini那些内容看看思路就好直接抄配置在新版本上很可能会解析失败。我习惯把二进制和配置都放到固定目录方便后面用 systemd 管理mkdir -p /opt/frp tar -xzf frp_0.61.1_linux_amd64.tar.gz -C /opt/frp --strip-components1 cd /opt/frp ls -l正常情况下能看到frps、frpc和对应的.toml文件。目录路径后面写 systemd service 时要保持一致不要一会儿用/root/frp一会儿用/opt/frp。3. 服务端 frps 配置实操3.1 最小可运行配置先编辑服务端配置/opt/frp/frps.toml写一个最小可用版本bindPort 7000 auth.method token auth.token 改成你自己的复杂随机字符串bindPort是 frp 服务端用来接收 frpc 连接的端口可以按需要调整但后面客户端必须保持一致。auth.token是两端握手的口令建议用随机生成的长字符串不要用123456这种一眼能猜出来的弱口令。这个配置其实已经能跑起来但实际使用中我会直接把控制面板一起打开方便观察连接状态。3.2 控制面板与端口规划控制面板是 frp 自带的 Web 状态页能看到当前有哪些客户端在线、哪些通道正在工作。配置长这样bindPort 7000 auth.method token auth.token 改成你自己的复杂随机字符串 webServer.addr 0.0.0.0 webServer.port 7500 webServer.user admin webServer.password 请改成强密码控制面板端口没有特殊要求只要不和 bindPort 冲突即可。需要注意的是面板带登录口令默认账号密码一定要改尤其是当webServer.addr配成0.0.0.0的时候外部网络也能访问到面板。我自己实际使用时会把这个端口加来源 IP 限制只允许办公网络 IP 访问不给公网裸奔的机会。3.3 用 systemd 把 frps 做成常驻服务直接用./frps -c frps.toml前台启动只适合调试。真正要长时间跑我建议放到 systemd 里管理这样服务器重启后能自动拉起进程意外退出也会按策略重启。创建一个 systemd 服务文件cat /etc/systemd/system/frps.service EOF [Unit] Descriptionfrp server Afternetwork.target [Service] Typesimple ExecStart/opt/frp/frps -c /opt/frp/frps.toml Restarton-failure RestartSec5s [Install] WantedBymulti-user.target EOF然后执行systemctl daemon-reload systemctl enable --now frps systemctl status frps看到active (running)就说明服务端已经起来了。后面改配置后记得执行systemctl restart frps。4. 客户端 frpc 配置实操4.1 最常用的 TCP 端口映射配置假设我想在内网机器上把本机的 22 端口映射到公网服务器的 16022 端口frpc.toml可以这样写serverAddr 你的服务器公网IP serverPort 7000 auth.method token auth.token 和 frps.toml 保持一致 [[proxies]] name ssh type tcp localIP 127.0.0.1 localPort 22 remotePort 16022字段解释一下serverAddr和serverPortfrps 的地址和连接端口端口必须和frps.toml的bindPort一致。[[proxies]]定义一个转发条目name可以自己取但不能和同一客户端下其他条目重名。type转发类型TCP 转发就写tcp。localIP和localPort内网实际服务的地址和端口。如果服务就在本机写127.0.0.1没问题如果 frpc 要转发同一局域网里另一台机器的服务这里要写那台机器的内网 IP。remotePortfrps 对外提供服务要使用的端口这个端口要保证在公网服务器上没有被其他服务占用。启动客户端./frpc -c frpc.toml启动后在任意一台有公网访问能力的机器上执行ssh user服务器公网IP -p 16022就能登录到内网机器。注意remotePort不能用服务器上已占用的端口否则绑定时会直接失败。如果服务器是云厂商的16022 这个端口还必须在安全组里放行否则外部流量到不了 frps。4.2 其他常用转发类型UDP、HTTP、STCPUDP 转发和 TCP 差别不大把type改成udp其余逻辑一样。适合做 DNS 调试、NTP 同步这类场景的外网访问。HTTP 转发则更适合有域名的情况。frps 上需要开启vhostHTTPPortfrpc 里配置type http和customDomains [app.example.com]服务端收到 HTTP 请求后会按照域名把流量转发到对应的内网服务。这样做的好处是不需要为每个 Web 服务分配独立端口一个 HTTP 端口加不同域名就能承载多个内网站点。STCP 不一样它不直接暴露对外端口而是通过 frps 做信令交换由两个 frpc 之间建立点对点加密通道。适合想对外安全提供服务又不想让端口直接暴露在公网上的场景配置上也多一层 visitor 概念。我第一次用 frp 的时候直接先从最简单的 TCP 转发开始跑通之后再尝试 HTTP、STCP。建议你也按这个顺序来不然一堆配置项堆在一起出问题时根本不知道从哪里排查起。4.3 客户端日志与启动验证frpc 前台启动后正常情况下日志里会出现类似start proxy success的字样并打印出当前映射的地址信息。如果看到login to server failed那就是和第 6 章的常见错误对上了。客户端同样推荐用 systemd 管理避免重启服务器之后 frpc 没有自动拉起来。配置文件路径和启动命令换成 frpc 对应版本即可。5. 配置完成后的联调与网络放行5.1 从零开始的启动顺序frp 的启动顺序其实没有强依赖frpc 先启动也能等 frps 恢复后自动连上但我习惯先确保 frps 服务端起来并监听端口再启动 frpc这样日志比较干净方便定位问题。真正需要重点检查的反而是配置一致性服务端bindPort和客户端serverPort是否一致两边 token 是否完全一致remotePort是否冲突。顺序对了但配置对不上一样连不通。5.2 验证内外网是否真正打通验证分三步走在服务器上执行ss -lntp | grep 16022确认 frps 已经在监听对应端口。打开 frps 控制面板在浏览器访问http://服务器公网IP:7500登录后看到客户端在线、通道状态正常。在另一台外部机器上执行telnet 服务器公网IP 16022或者直接用业务命令验证比如 SSH 端口就直接ssh -p 16022 user服务器公网IP。如果服务器本机访问端口是通的但外部不通那问题八成出在网络放行这一环。5.3 防火墙与云平台安全组注意事项服务器自带的防火墙比如 firewalld 或 ufw和云平台的安全组是两个独立环节任何一个挡着都会失败。常见现象是frpc 日志显示连接成功控制面板也显示在线但外部访问超时。这种情况十有八九是安全组或服务器防火墙没放行 remotePort。排查时可以先用curl -v或者telnet从外部访问再看是超时还是拒绝超时大概率是安全组丢包拒绝则可能是端口没监听。开放防火墙端口示例firewall-cmd --permanent --add-port7000/tcp firewall-cmd --permanent --add-port7500/tcp firewall-cmd --permanent --add-port16022/tcp firewall-cmd --reload如果用的是 ufwufw allow 7000/tcp ufw allow 7500/tcp ufw allow 16022/tcp云平台安全组的操作不在命令行里每家的控制台位置不同但思路一样找到安全组规则添加入方向的对应端口放行规则。我经常看到有人改了 frp 配置半天最后发现只是安全组漏了一条规则特别浪费时间。6. frp 常见错误排查实战6.1 配置文件解析错误导致启动失败现象启动 frps 或 frpc 时直接报invalid config或者load config error。排查思路先确认配置文件后缀是.toml新版本已经不推荐使用旧的.ini后缀。再看字段名是否按 TOML 规范写比如serverAddr是驼峰写法不是旧版的server_addr。检查是否有中文引号、中文冒号混在配置文件里。这个问题常见于在 Windows 编辑器中复制内容再粘贴到 Linux 的场景。较新版本提供了配置校验命令强烈建议启动前先跑一遍./frpc verify -c frpc.toml服务端对应使用./frps verify -c frps.toml。校验能通过再谈其他排错。6.2 token 认证失败与 401 报错现象客户端日志出现login to server failed: 401或者auth error。原因几乎都是两端 token 不一致。先对比frpc.toml和frps.toml的 token 是否完全一样注意不要有空格、不要用中文引号。如果服务端开了auth.method token而客户端没有写这个字段也可能导致认证异常。我遇到过最气人的情况是token 复制的时候从日志里多复制了一个换行符进去肉眼完全看不出来但两边就是握不上。所以建议token 写成无空格、无换行的纯字符串。6.3 bind 端口被占用的问题现象frps 启动时日志出现port already used或者服务起不来。排查时先在服务器上执行ss -lntp | grep 7000如果看到其他进程占了 7000 端口要么换端口要么把占用进程处理掉。另一种常见情况是配置了多个代理但把多个remotePort配成了一样的值导致后定义的代理无法绑定。日志里通常会有类似proxy name duplicated或者端口绑定的报错看到后挨个检查每个转发条目的remotePort即可。6.4 客户端已经连上但外部始终访问不了这是实际使用中频率最高的一个问题。分三步排查在服务器本机执行telnet 127.0.0.1 16022或curl 127.0.0.1:16022看端口是否在监听。如果本机都连不通说明 frps 没有成功监听或者转发通道没有注册成功。如果本机能通但外部机器不行去检查安全组和服务器防火墙。如果外部能连到端口但连接后马上就断去看后端内网服务的localIP和localPort填得对不对内网服务本身有没有在监听。还有一种隐蔽情况服务器公网 IP 写错了。尤其是云服务器有内网 IP 和公网 IP 两个地址frpc 的serverAddr必须填公网 IP填了内网 IP 只会导致外部通道永远建立不起来。6.5 EOF、timeout、connection refused 分别代表什么日志里出现这些关键字含义完全不同EOF连接被对方正常或异常关闭。常见于 token 不正确服务端主动断掉握手也可能是服务端重启导致旧连接没被清理客户端重连后恢复。timeout网络不通或端口被丢包。重点检查安全组、防火墙、frps 的bindPort是否监听。connection refused端口没有监听。常见于remotePort被占用或者 frps 还没有起来。看到这些关键词不用慌先把它对应到具体嫌疑点再逐项排除。6.6 常见错误速查表把上面这些问题整理成一张表格遇到问题先对着表格查能省不少时间现象可能原因优先排查动作启动报 invalid configTOML 格式或字段名写错执行frpc verify -c frpc.toml日志出现 401token 不一致对比两端 token 是否完全一致bind 端口失败端口被其他服务占用执行ss -lntp查看端口占用客户端在线但外部不能访问安全组或防火墙未放行检查云平台安全组和本机防火墙连接后立刻断开 / EOFtoken 错误或服务端拒绝查看 frps 端日志timeout网络不通或端口被丢包检查公网 IP、防火墙、安全组connection refused端口未监听确认 frps 是否正常运行端口是否被占6.7 几个容易被忽略的低级错误最后再单独列出几个我见过很多次的低级错误用中文双引号写配置文件导致 TOML 解析失败。手动复制 token 时把日志里的省略号或者换行符一起复制进去。frpc 连接公网服务器时IP 填成了云服务器内网 IP。修改配置文件后忘记重启 frp 服务还在用旧配置跑。这些错误排查起来不难但容易在忙乱中反复踩。我的习惯是每次改完配置先执行一遍verify再重启服务最后看日志确认状态。7. 一些提升使用体验的小细节7.1 版本选择与升级思路不要盲目追最新版也不要用太老的版本。frp 迭代速度很快部分版本之间协议或配置格式有调整升级前一定先备份现有配置再替换二进制文件升级后在本地环境先跑通再更新线上。版本太老的问题主要是新特性没有协议兼容也可能出问题版本太新的问题则是社区资料还不充分遇到问题能搜到的案例少。一般我会选择最近半年内发布的功能相对完整的版本。7.2 日志策略与磁盘占用frp 如果通过 systemd 管理日志默认会进入 journald。长时间运行后日志量不可小觑尤其是有大量连接请求和控制面板刷新的情况。可以用下面的命令查看服务日志journalctl -u frps -n 50 --no-pager journalctl -u frpc -f如果担心日志占用过多磁盘可以在 frps 的 systemd service 里加日志清理相关配置或者定期用journalctl --vacuum-size200M限制日志体积。简单场景下我通常只保留最新的一部分日志重点是能看到最近几次启动和报错信息。7.3 关于 token 和安全习惯frp 的 token 本质上是两端握手时的口令务必用高强度随机字符串不要把 token 提交到代码仓库、不要写在公开笔记里。控制面板的账号密码也一定要改默认值不要用默认的admin。如果服务器只给固定来源使用尽量在防火墙层面限制来源 IP。从个人习惯来说我会把服务端 systemd 服务、防火墙放行命令、配置文件模板整理成一套固定流程换新机器的时候直接复用。frpc 每新增一个转发通道都会在配置里加注释说明这个通道是给哪个服务用的、对应内网端口是什么。这样配置多了之后不会混乱排查问题的时候也知道每一个条目当初为什么加。最后再分享一个小技巧遇到 frp 连不上、访问异常这类问题先别急着改配置先把 frps 和 frpc 两端的日志同时打开对比看是在握手阶段就断了还是握手成功后转发阶段才出问题。这样做能直接砍掉一大半排查路径比盲试配置高效得多。