ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

frpc 客户端安装使用全指南:多平台常驻、配置与排错

frpc 客户端安装使用全指南:多平台常驻、配置与排错 手上有一台放在家里或公司内网的机器上面跑着 NAS 管理页、代码仓库、数据库或者一个刚写完还没上线的 Web 服务它只能在内网里被访问。这时候绝大多数人都会选择 frp 这套内网穿透方案在公网服务器上跑 frps在内网机器上跑 frpc。服务端那一步往往照着教程走一遍就通了真正让人卡住的反倒是看起来最简单的 frpc 客户端——下载、改配置、启动只有三步但版本换代带来的配置格式变化、不同平台的常驻方式、以及连不上时该怎么定位才是决定你能不能把它用顺手的关键。这篇内容就围绕frp 客户端 frpc 的安装与使用展开从它到底在整个链路里扮演什么角色到 Linux、Windows、macOS含 M 系列芯片、Docker 四种环境下的落地方式再到frpc.toml每个字段该怎么填、隧道类型怎么选、连不上时按什么顺序排查最后聊怎么把它做成一个长期跑着不用操心的服务。不管你是刚接触内网穿透的新手还是已经用了一两年但只会复制配置的老用户下面这些细节应该都能省下你不少试错时间。1. 先把 frpc 在整个链路里的位置摆正1.1 连接方向永远是客户端先拨出去这是理解 frp 的第一件事也是后面所有排错的底层前提。frps 部署在那台有公网 IP 的服务器上它负责监听一个控制端口默认 7000等待客户端来报到frpc 跑在内网机器上它启动之后会主动向 frps 发起一条长连接把这条连接保持住当作控制通道之后再按配置把本地服务的流量从这条通道里塞过去。正因为方向是内网往外拨所以你的内网机器不需要公网 IP路由器也不用做任何端口映射甚至机器在多层 NAT 后面都无所谓——只要它能访问到公网服务器的 7000 端口这条隧道就能建立起来。很多人第一次接触时想不明白外面怎么访问进来本质就是没意识到隧道是客户端先出去铺好的外面的访问其实是沿着这条已经铺好的管道反向走。提示判断一个内网穿透工具能不能用最快的方法就是看连接方向。客户端主动外连的方案frp 属于这类基本不挑网络环境但也意味着客户端进程一旦挂掉隧道立刻就断。1.2 哪些场景值得上 frpc结合我自己和身边朋友的实际用法frpc 出现频率最高的场景大概是这几类。第一类是远程运维家里的机器比如把家里的 NAS、软路由、下载机通过 SSH 或 Web 面板挂到外面随时能上去看一眼。第二类是内网测试环境临时对外前后端联调时把本地跑起来的服务映射出去让对方直接访问省去反复打包部署。第三类是设备侧数据回传一些部署在客户内网的采集程序、工控网关需要把状态上报到中心服务器用 frpc 做反向连接比让客户开防火墙简单得多。第四类是远程开发机把公司或机房的开发机端口映射出来用本地 IDE 的远程开发功能直接连。这几类的共同点是被访问的服务本身就在内网、只是偶尔需要外部触达、对延迟和带宽的要求不算极端。这也恰好是 frpc 的舒适区。1.3 什么时候不该硬上 frpc有一种情况是很多人踩过坑之后才明白的不要把 frpc 当成正式对外站点的主链路。如果某个服务需要长期对外提供访问、有备案和证书要求、访问量还不小那正确做法是直接把它部署在有公网 IP 的环境里或者走正规的负载与网关方案。把生产流量长期压在一台 frpc 客户端上一旦客户端所在的网络抖动、运营商侧有波动或者机器重启后服务没自启损失的是真实用户。另外纯大流量场景比如持续的视频流转发也不太适合因为 frp 的转发是经过服务端中转的带宽会受公网服务器出口限制。这类需求更适合寻找能走点对点直连的方案frp 里的 xtcp 类型就是为这个准备的后面会单独讲。2. 动手改配置之前先把这四项信息拿到手并验证2.1 serverAddr、serverPort、token 三件套frpc 的配置里最核心的就是这三项它们必须和 frps 那侧完全对上serverAddr公网服务器的 IP 或域名是你内网机器能访问到的地址不是服务端的内网 IP。serverPort控制端口frps 默认 7000。如果服务端改过这里跟着改。token认证口令两边必须一字不差。大小写、前后空格、有没有复制到换行符都会直接导致连接被拒。这三项里最容易出问题的是 token。我见过不止一次是从聊天窗口复制 token 时把末尾的换行也带进去了结果日志里一直报认证失败人却在那边反复检查网络。所以拿到 token 之后建议先粘贴到配置文件里再用编辑器的显示不可见字符功能扫一眼确认没有多余空白。2.2 顺带确认服务端给你的端口范围隧道建起来之后每一个映射出去的服务都要占用服务端的一个公网端口remotePort。服务端一般会用allowPorts限制一个范围防止客户端随便占用端口。所以在你规划 remotePort 之前先问清楚服务端留给你的是哪一段比如 20000 到 21000。如果你配了一个超出范围的 remotePort客户端连得上、隧道也注册了但日志里会明确提示端口不允许很多人看到连接成功就以为万事大吉结果外面访问不通问题就出在这里。2.3 用一条命令做连通性预检在写配置之前先在内网机器上确认它真的能碰到服务端的控制端口。Linux 和 macOS 上nc -vz your.server.com 7000Windows 上如果没装 nc用 PowerShell 的这条Test-NetConnection your.server.com -Port 7000只要能返回连接成功说明网络链路没问题后面如果 frpc 起不来方向就锁定在配置本身而不是网络。这一步花十秒钟能帮你省掉后面半小时的无效排查。3. 四个平台上把 frpc 装成一个常驻服务3.1 Linux二进制加 systemd 是最省心的组合frp 的发布包是纯二进制不需要编译直接去项目的 Releases 页面按架构下载对应压缩包即可。判断架构用uname -mx86_64 对应linux_amd64ARM 服务器对应linux_arm64。下载后解压把frpc和frpc.toml放到一个固定目录我个人习惯是/usr/local/frp/然后给它单独建个配置目录也行关键是位置固定不然以后 systemd 找不到文件。接着写 systemd 单元文件/etc/systemd/system/frpc.service[Unit] Descriptionfrp client Afternetwork.target [Service] Typesimple Usernobody Restarton-failure RestartSec5s ExecStart/usr/local/frp/frpc -c /usr/local/frp/frpc.toml LimitNOFILE1048576 [Install] WantedBymulti-user.target这里有几个细节值得说。Restarton-failure加上RestartSec5s是保证它掉线后能自动拉起来的关键不然机器重启或者网络闪断一次你就得手动上去启动。LimitNOFILE调大是因为隧道数量多的时候文件描述符容易成为瓶颈。Usernobody是降权frpc 本身不需要 root 权限除非你要映射的本地服务端口低于 1024。启用并启动sudo systemctl daemon-reload sudo systemctl enable --now frpc sudo systemctl status frpcenable和--now一起用既设置开机自启又立刻启动少敲一条命令。3.2 Windows别丢进启动项注册成服务Windows 上最省事的做法是把它注册成系统服务。frp 本身不带服务封装通常借助winsw或者nssm这类工具把frpc.exe包成服务。以 nssm 为例下载后执行nssm install frpc C:\frp\frpc.exe -c C:\frp\frpc.toml nssm set frpc AppStdout C:\frp\frpc.log nssm set frpc AppStderr C:\frp\frpc_err.log nssm start frpc这么做的价值在于服务模式下它能在没有用户登录的情况下运行也能设置崩溃后自动重启。很多人图省事把 frpc 丢到启动文件夹结果一锁屏、一切换用户进程就没了隧道断得莫名其妙。还有一个 Windows 上特别容易忽略的点被杀软拦。frpc 做的行为是持续外连一个固定端口并保持长连接某些安全软件会把它判定为异常外联行为直接阻断。如果你确认配置没错日志里却连尝试连接都没有先去安全软件里看一眼拦截记录。3.3 macOSM 系列芯片要认准 arm64 包从 M1 开始到现在的 M4Apple 芯片的 Mac 已经是主流下载时务必选darwin_arm64的包选成darwin_amd64也能靠 Rosetta 跑起来但启动时会多一层转译日志和实际行为偶尔会出现不一致排查起来很烦。下载后同样解压到固定位置比如/usr/local/frp/。macOS 上有个必踩的坑从浏览器下载的二进制会带上隔离属性直接执行会提示已损坏或来源不明。解决办法是解除隔离sudo xattr -d com.apple.quarantine /usr/local/frp/frpc sudo chmod x /usr/local/frp/frpc如果要常驻用 launchd 而不是 cron。在~/Library/LaunchAgents/下建一个com.user.frpc.plist配置ProgramArguments指向 frpc 和配置文件路径KeepAlive设为 true再用launchctl load加载。KeepAlive相当于 systemd 的自动重启是保证长期在线的关键项。另外别忘了 macOS 的登录项与扩展和完全磁盘访问权限某些情况下需要给 frpc 授权否则它读取配置目录会被系统拦下。3.4 Docker网络模式选错就等于白配容器方式跑 frpc 最干净但有一个高频坑必须提前讲默认的 bridge 网络下容器里的127.0.0.1指向的是容器自身而不是宿主机。如果你的隧道要映射的是宿主机上跑的服务配置里写127.0.0.1就会转发不到东西。两种解决方案一是用--network host直接共享宿主机网络栈最简单直接二是保持 bridge 模式把 localIP 改成宿主机的局域网 IP比如 192.168.1.10。前者更省心docker run -d --name frpc \ --network host \ --restart unless-stopped \ -v /opt/frp/frpc.toml:/etc/frp/frpc.toml \ snowdreamtech/frpc:latest--restart unless-stopped是容器版的自动重启策略配合前面的 systemd 思路是一回事。日志用docker logs -f frpc看别去翻文件。平台常驻方案自动重启关键项最容易踩的坑LinuxsystemdRestarton-failure配置文件路径写成相对路径Windowsnssm/winsw服务恢复策略被杀软静默拦截macOSlaunchdKeepAlive隔离属性导致无法执行Dockerrestart 策略unless-stopped网络模式选错导致转发失败4. frpc.toml 逐字段拆开讲4.1 从 ini 到 toml先搞清你手上的版本用哪种格式frp 在 0.52 版本前后做了一次配置格式的切换老版本用frpc.ini的 ini 格式新版本统一改成frpc.toml。这是一个非常容易混淆的地方因为你搜索到的教程十有八九是旧格式照抄到新版本上直接报解析错误。老版 ini 长这样[common] server_addr your.server.com server_port 7000 token your_token [ssh] type tcp local_ip 127.0.0.1 local_port 22 remote_port 6000新版 toml 长这样serverAddr your.server.com serverPort 7000 auth.method token auth.token your_token [[proxies]] name ssh type tcp localIP 127.0.0.1 localPort 22 remotePort 6000最直观的差别是[common]段没了公共配置直接提到顶层每一条隧道不再是独立的中括号段而是用[[proxies]]这个数组表来承载。判断方法很简单跑一次frpc --version看版本号或者直接看解压包里给的是frpc.ini还是frpc.toml。注意新版 frp 仍然能读 ini但它只做兼容处理一些新特性在 ini 里没法表达。既然是新装就别再用旧格式了。4.2 隧道类型怎么选从 tcp 到 xtcptype这个字段决定了隧道的工作方式选错类型是配置看起来对但访问不通的头号原因。下面这张表是我自己整理过的常用对照类型适用场景是否需要服务端额外端口特点tcpSSH、数据库、自定义协议需要 remotePort最通用什么都能转发udp游戏联机、部分监控协议需要 remotePort无连接协议专用http多站点按域名分流通常不需要依赖 vhostHTTPPort 和自定义域名https需要证书的 Web 服务通常不需要依赖 vhostHTTPSPortstcp只想给指定人访问的服务不需要访问方也要跑 frpc 做 visitorxtcp大流量、追求直连不需要尝试点对点穿透失败会回退大部分人的第一个隧道都是 tcp比如把内网的 SSH 映射出去[[proxies]] name home-ssh type tcp localIP 127.0.0.1 localPort 22 remotePort 6000配好之后从外面ssh -p 6000 your.server.com就能连到内网那台机器。这里有个安全上的提醒不要把 SSH 直接暴露在所有 IP 上后面第 7 节会讲怎么做限制。如果是要映射 Web 服务并且服务端已经配好了vhostHTTPPort用 http 类型会更优雅因为它靠域名区分不同隧道不需要为每个服务单独占一个端口[[proxies]] name web-demo type http localPort 8080 customDomains [demo.your.domain.com]stcp 是很多人没注意到但非常实用的一类。它的逻辑是服务只对同样跑着 frpc 的访问方开放公网上没有暴露任何端口。服务提供方这样配[[proxies]] name secret-rdp type stcp secretKey a-long-random-string localIP 127.0.0.1 localPort 3389访问方那边则加一段 visitors[[visitors]] name secret-rdp-visitor type stcp serverName secret-rdp secretKey a-long-random-string bindAddr 127.0.0.1 bindPort 13389然后访问方本地连127.0.0.1:13389就等价于连到了对方的 3389。整个过程公网服务端不开放任何端口安全面小得多这也是我推荐用它替代直接 tcp 暴露远程桌面的原因。4.3 加密、压缩、限速这三项到底开不开每个隧道下面都可以挂这几个开关[[proxies]] name db type tcp localIP 127.0.0.1 localPort 3306 remotePort 6033 transport.useEncryption true transport.useCompression trueuseEncryption会把客户端到服务端之间的流量加密。如果服务端也开了 TLStransport.tls.force true那隧道本身已经在加密通道里跑再叠加这一层收益有限反而多耗一点 CPU。但如果你对服务端不是完全信任或者服务端没开 TLS建议打开。useCompression适合传文本、JSON、HTML 这类可压缩内容能明显省带宽但如果转的是已经压缩过的数据图片、视频、压缩包开了反而多一次无用的 CPU 开销。至于限速frp 支持在隧道级别配置带宽上限适合在共享服务器上跑、不希望某条隧道吃满出口的场景配置方式是transport.bandwidthLimit加单位。我一般不主动开除非确实观察到某条隧道把出口占满了。4.4 一个进程同时挂多条隧道没有必要为每个服务单独起一个 frpc 进程。[[proxies]]是数组允许多段并存同一个 frpc 可以同时映射 SSH、Web、数据库serverAddr your.server.com serverPort 7000 auth.method token auth.token your_token [[proxies]] name home-ssh type tcp localIP 127.0.0.1 localPort 22 remotePort 6000 [[proxies]] name nas-panel type tcp localIP 127.0.0.1 localPort 5000 remotePort 6001 [[proxies]] name dev-web type http localPort 8080 customDomains [dev.your.domain.com]这样启动一次、维护一份配置、看一处日志比开好几个进程清爽得多。唯一要注意的是name必须全局唯一重复了服务端会拒绝注册。5. 连不上时的排查链路按这个顺序走5.1 第一件事永远是看日志而不是猜frpc 的日志信息量其实很足只是默认级别不够细。启动时加参数./frpc -c ./frpc.toml --log_level debug --log_file ./frpc.log或者直接在配置里写log.to ./frpc.log log.level debug log.maxDays 7拿到日志之后按报错内容分层定位连不上服务端是网络层连上了但认证失败是 token 层认证成功但隧道注册失败是端口或配置层注册成功但访问不通是本地服务层。把这几层分清楚排查方向立刻明朗。5.2 token 与 TLS 握手失败的典型表现如果日志里出现authentication failed或类似的提示基本就是 token 不匹配按前面说的检查前后空格和大小写。如果出现 TLS 相关的握手错误通常是服务端开了transport.tls.force而客户端的证书配置没跟上或者系统时间偏差太大导致证书校验失败。后者特别隐蔽——机器时间如果错了几分钟TLS 校验就可能不过而人压根想不到去检查时间。5.3 端口占用和本地服务没起来隧道注册成功但外部访问不通先确认三件事本地服务是不是真的在跑ss -lntp | grep 端口remotePort 是不是被服务端上别的进程占了服务端防火墙有没有放行那个端口段。这三条里最容易忽略的是第三条很多人只确认了控制端口 7000 是通的就以为映射端口自动也通其实完全是两回事。5.4 被 allowPorts 挡住的情况如果日志里出现类似port not allowed的提示就是服务端限制了可映射端口范围。这时候要么找服务端管理员申请扩大范围要么把自己的 remotePort 调进允许区间。这个坑的特点是前面所有步骤看起来都成功了只有实际访问时不通所以一定要养成看完整日志的习惯别只看前面几行。6. 日常运维热加载、多实例和巡检6.1 改完配置不用重启进程frp 提供了一条热加载命令改了frpc.toml之后执行./frpc reload -c ./frpc.toml它会重新读取配置、动态增删隧道已有的隧道连接不会全断。前提是配置里开了管理接口webServer.addr 127.0.0.1 webServer.port 7400 webServer.user admin webServer.password a-strong-password这个接口同时也是一个 Web 面板浏览器访问http://127.0.0.1:7400能看到当前所有隧道的状态。特别提醒一句这个管理端口千万别监听到 0.0.0.0 上还配弱密码它不是业务端口暴露出去等于把配置控制权送人。6.2 真的需要多个 frpc 时怎么做隔离有些场景确实需要多个进程比如同一台机器上有多个用户各自管理自己的隧道或者要把不同环境的隧道分开。这时候建议按目录隔离/opt/frp/team-a/frpc /opt/frp/team-a/frpc.toml /opt/frp/team-b/frpc /opt/frp/team-b/frpc.toml每个实例一个 systemd 单元单元名带后缀区分管理端口也错开7400、7401……。这样任何一个实例出问题都互不影响日志也不会混在一起。6.3 用管理接口做个简单巡检管理接口提供了状态查询接口可以写个几行的脚本定时拉一次检查隧道是不是都在线。一旦发现某条隧道掉了直接告警。这比自己时不时手动上去systemctl status看一眼靠谱得多尤其是隧道数量上了十几条之后肉眼检查根本不现实。7. 把暴露面压到最小几条安全基线7.1 token 要够长够随机TLS 尽量强制token 是整个方案的第一道门别用123456这种。生成一条真正的随机串openssl rand -hex 32服务端和客户端都换上同一个值。同时如果条件允许在服务端开启 TLS 强制让控制通道本身加密避免 token 和隧道数据在传输中被旁观。7.2 能用 stcp 就别用裸 tcp 暴露远程桌面前面提过stcp 不对外开放任何端口只有持有相同 secretKey 的访问方能连。远程桌面、管理后台这类敏感服务强烈建议优先用 stcp实在不方便再退回 tcp并且配合服务端防火墙做来源 IP 限制。7.3 只映射真正需要的端口一个很常见的坏习惯是把内网机器的整段端口都映射出去图省事。正确做法是一条隧道对应一个具体服务把不需要的关掉。每多一个暴露的端口就多一份被扫描和被尝试的风险。7.4 客户端配置文件权限收紧frpc 的配置里存着 token这个文件的权限应该收紧到只有对应服务账号能读sudo chmod 600 /usr/local/frp/frpc.toml sudo chown nobody:nobody /usr/local/frp/frpc.toml配合 systemd 里的降权运行即使机器上有其他低权限用户也读不到你的认证信息。我自己这几年用下来最大的体会是frpc 真正麻烦的地方从来不是怎么装而是怎么把它当一个长期在线的服务来对待。配置写对一次很容易难的是半年后机器重启、网络抖动、版本升级时它还能自己恢复。所以我现在的习惯是任何一台机器上装完 frpc第一件事就是把 systemd 的自动重启配好、日志落盘、管理接口只监听本地这三样做完基本就不用再管它了。另外配置目录固定、文件名固定、注释写清楚每条隧道是给谁用的等过几个月回头看时你会感谢当时的自己。
返回列表