frp 内网穿透实战:从原理配置到远程办公与 Web 发布
家里一台旧电脑装了 NAS 系统,人在公司却想访问里面的照片;客户现场的设备出了 bug,远程连不上只能买张高铁票;开发好的 Web 服务在本地跑得好好的,想给外地同事临时看一眼演示……这些场景有一个共同的敌人——内网。
上一篇黑漂技术佬带大家玩转了 ZeroTier(P2P 组网路线),今天换个思路,聊聊内网穿透界最著名的"老大哥"——frp。它走的是"服务器中转转发"路线,原理更朴素、适用面更广,是无数运维和开发者的心头好。本文从零开始,用当前最新稳定版(v0.71.x)带你把它从原理到实战彻底跑通,远程桌面、Web 发布、点对点模式一次讲清楚。
一、先搞懂:什么是内网穿透
1.1 问题的根源:你根本没有"公网门牌号"
在互联网世界里,一台设备要被别人主动访问,需要有一个公网 IP。但现实是:
- IPv4 地址早就枯竭了,运营商分给家庭宽带的往往是内网 IP(你拨号拿到的其实是 100.64.x.x 这种运营商大内网地址);
- 即便有公网 IP,很多家庭/企业路由器默认还挡着一层防火墙,外网照样进不来;
- 就算你做了端口映射,遇到没有公网 IP 的宽带,一切白搭。
所以就有了这么个尴尬局面:你的设备能"出去"(主动访问外网),但外网"进不来"(无法主动访问你)。
1.2 什么是内网穿透
内网穿透(也叫 NAT 穿透)解决的就是上面这个问题。最朴素的思路是:
找一台有公网 IP 的服务器当"中间人",内网设备主动和它建立一条长连接;外网用户访问时,先访问这台服务器,服务器再把数据沿着这条长连接"转发"给内网设备。
一句话:内网设备够不着公网,那就让公网服务器帮你"递话"。frp 干的就是这个活。
1.3 一张图看懂 frp 的转发模型
① frpc 主动连上 frps(内网→公网,能出去) ┌──────────────┐ 长连接 ┌──────────────┐ │ 内网机器 │ ──────────▶ │ 公网 VPS │ │ (frpc 客户端) │ ◀────────── │ (frps 服务端) │ │ 跑着 RDP/Web │ 数据转发 │ 开放 7001 等 │ └──────────────┘ └──────┬───────┘ │ ② 外网用户访问 VPS 的端口 ▼ ┌──────────────┐ │ 外网用户/设备 │ │ (手机/电脑/Kali) │ └──────────────┘注意关键点:所有业务数据都要经过 VPS 中转。这和 ZeroTier 的"打洞直连"是两条完全不同的技术路线,各有优劣,后面细说。
二、frp 是什么:内网穿透界的"瑞士军刀"
2.1 一句话简介
frp(Fast Reverse Proxy)是一个开源、高性能的内网穿透 + 反向代理工具,由 Go 语言编写,作者 fatedier。它的江湖地位有多高?GitHub 上10 万 + star,几乎是同类工具里知名度最高的那个。
它的核心组成只有两个程序:
| 程序 | 全称 | 部署位置 | 职责 |
|---|---|---|---|
frps | frp Server | 有公网 IP 的服务器(VPS/云主机) | 监听端口、接收 frpc 连接、转发数据、提供 Dashboard |
frpc | frp Client | 内网里要被访问的机器 | 主动连接 frps,把本地服务"挂"到公网 |
2.2 它能干什么
- 把内网机器的SSH(22)、远程桌面(3389)、文件共享(445)暴露到公网,出差在外也能远程办公;
- 把内网的HTTP/HTTPS Web 服务发布到公网,支持域名绑定、虚拟主机(多个域名共用一个公网端口);
- 支持TCP、UDP、HTTP、HTTPS等协议,游戏联机、视频流、设备报文转发都能做;
- 进阶玩法支持STCP / XTCP(点对点加密模式,frp 服务器只做"介绍人",数据两端直连)。
2.3 为什么选 frp(而不是 ngrok、花生壳……)
市面上的内网穿透工具一抓一大把,frp 的核心优势在于:
| 维度 | frp(自建) | 花生壳/cpolar/ngrok(SaaS) | ZeroTier/Tailscale(P2P 组网) |
|---|---|---|---|
| 数据路径 | 自己的 VPS 中转 | 第三方服务器中转 | 优先 P2P 直连 |
| 数据掌控 | 完全自主 | 经过第三方,敏感数据有顾虑 | 自建 Planet 才完全自主 |
| 免费额度 | 一台 VPS 全搞定 | 免费版限速限流量 | 官方免费 25 台/网 |
| 上手难度 | 中等(要会 Linux) | 低(注册即用) | 低 |
| 典型场景 | 长期稳定发布服务、企业远程办公 | 临时演示、个人应急 | 多设备长期互联互访 |
选型口诀:想"把内网服务发布给公网陌生人/客户访问"→ frp;想"自己多台设备互相访问"→ ZeroTier 更省流量更快。两者不是竞争关系,很多老哥家里两个都装——ZeroTier 管设备互联,frp 管对外发布。
三、环境准备:你需要什么
动手之前先盘一盘家底:
| 角色 | 要求 | 说明 |
|---|---|---|
| 公网 VPS | 有公网 IP,Linux 系统(本文以 Ubuntu 为例),能装 Docker 更好但不是必须 | frp 非常轻量,1 核 512M 的入门机都绰绰有余 |
| 内网机器 | 要被访问的设备:Windows/Linux 皆可 | 放家里/公司的 NAS、台式机、服务器都行 |
| 测试设备 | 任意能上网的设备(手机、另一台电脑) | 用于验证穿透是否成功 |
关键认知:frp 是转发型工具,VPS 的带宽就是你的"水管粗细"。VPS 带宽 1Mbps,穿透后远程桌面就会卡成幻灯片;想要流畅的远程桌面/看视频,VPS 带宽至少 3-5Mbps 起步。瓶颈在 VPS,不在内网。
顺带一提:如果你要穿透的是HTTP/HTTPS 服务并绑定域名,国内云服务器上 80/443 端口需要域名备案。嫌备案麻烦,就把 frp 的 HTTP 端口设成非 80(比如 8060),照样能访问,本文就这么干。
四、服务端搭建:把"中转站"架起来
4.1 下载 frp 并确认架构
frp 是 Go 写的,单文件、免安装,下载解压就能跑。先 SSH 登录 VPS,查看 CPU 架构:
uname-m# 输出 x86_64 → 选 amd64 版本# 输出 aarch64 → 选 arm64 版本(ARM 服务器常见)然后去 frp 的 GitHub Releases 页面下载对应版本。以 2026 年 8 月发布的v0.71.0为例(版本号以官方最新为准),Linux x86_64 的包名是:
frp_0.71.0_linux_amd64.tar.gz# 假设已经把压缩包下载/上传到服务器,开始解压tar-zxvffrp_0.71.0_linux_amd64.tar.gz# 改个短名字,方便后续操作mvfrp_0.71.0_linux_amd64 frpcdfrpls-l解压后你会看到一组文件,重点认准这四个:
| 文件 | 作用 |
|---|---|
frps | 服务端程序(s = server) |
frps.toml | 服务端配置文件(新版默认 TOML 格式) |
frpc | 客户端程序(c = client) |
frpc.toml | 客户端配置文件 |
⚠️版本认知更新(重要):老教程里配置文件名都是
frps.ini/frpc.ini,那是v0.52.0 之前的格式。从 v0.52.0 起 frp 改用TOML(也支持 YAML/JSON),INI 已被官方标记弃用、将在未来版本移除。新项目请直接用 .toml,网上那些 .ini 教程当历史参考就好,别照着配。
4.2 编写服务端配置 frps.toml
# 项目源码:frps.toml(服务端配置) # 客户端与服务端通信的主端口 bindPort = 7000 # 鉴权:token 方式,客户端必须带相同 token 才能连上来 auth.method = "token" auth.token = "换成你自己的强口令" # 管理面板(Dashboard),浏览器查看运行状态与流量 webServer.addr = "0.0.0.0" webServer.port = 7500 webServer.user = "admin" webServer.password = "也换掉这个默认密码" # 反向代理 HTTP 服务的统一入口端口(走域名访问时用) vhostHTTPPort = 8060逐行解释:
bindPort:frps 的主监听端口,客户端连接用,默认 7000;auth.token:连接口令。客户端和服务端 token 不一致,直接拒连——务必设置并记牢,这是 frp 的第一道安全闸;webServer.*:管理面板。启动后浏览器访问http://VPS公网IP:7500就能看到所有代理的运行状态、流量统计;vhostHTTPPort:HTTP 虚拟主机入口。多个域名共用这个端口转发到不同内网服务,后面 Web 发布会用到;暂时用不到可以先注释掉。
4.3 启动服务端
# 前台启动测试(先确认能正常跑起来)./frps-c./frps.toml看到类似下面的日志就是成功了:
frps uses config file: frps.toml frps tcp listen on 0.0.0.0:7000 frps started successfully启动后先别急着下一步,回到云厂商控制台,在"安全组/防火墙"里放行这几个端口:
7000(主连接)、7500(Dashboard)、7001/7002(等会儿给代理用的公网端口,按实际开)。忘记放行端口是 frp 排错榜第一名。
4.4 用 systemd 守护,告别 nohup
老教程喜欢nohup ./frps &挂后台——能用,但一重启服务器就没了,进程死了也没人管。生产环境推荐用systemd 托管,开机自启 + 崩溃自动拉起:
# 把 frp 移到标准目录(可选,路径清爽)sudomvfrp /opt/frp# 创建 systemd 服务文件sudovim/etc/systemd/system/frps.service写入以下内容(示意,路径按你的实际部署改):
[Unit] Description=frp Server After=network.target [Service] Type=simple ExecStart=/opt/frp/frps -c /opt/frp/frps.toml Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target启用并启动:
sudosystemctl daemon-reloadsudosystemctlenable--nowfrpssudosystemctl status frps# 看到 active (running) 即成功此时浏览器访问http://VPS公网IP:7500,用配置里的账号密码登录,就能看到 frp Dashboard 面板了——以后所有代理的连接状态、流量曲线一目了然。
五、客户端配置:把内网服务"挂"出去
5.1 场景一:远程桌面(RDP)——最刚需的用法
frp 的客户端是那台要被远程访问的内网机器。以一台内网 Windows 机器为例(要远程访问它),下载Windows amd64版本的 frp,解压后编辑frpc.toml:
# 项目源码:frpc.toml(客户端配置) # 公网 VPS 的信息(和 frps.toml 对应) serverAddr = "你的VPS公网IP" serverPort = 7000 # 鉴权 token,必须与 frps.toml 里一致 auth.method = "token" auth.token = "换成你自己的强口令" # 第一条代理:远程桌面 [[proxies]] name = "rdp" # 规则名,自己起,好认就行 type = "tcp" # 协议类型 localIP = "127.0.0.1" # 本机服务地址 localPort = 3389 # 本机 RDP 端口 remotePort = 7001 # 公网 VPS 上对外开放的端口 # 第二条代理:文件共享(SMB) [[proxies]] name = "smb" type = "tcp" localIP = "127.0.0.1" localPort = 445 # Windows 文件共享 remotePort = 7002启动客户端(关键提醒:不能双击 frpc.exe!):frpc 是命令行程序,双击没有任何反应,必须在 cmd 或 PowerShell 里运行:
# 在解压目录下执行.\frpc.exe-c.\frpc.toml看到以下日志即连接成功:
login to server success proxy added: [rdp smb] start proxy success5.2 验证远程桌面
方法一:Windows 自带"远程桌面连接"(mstsc)
- 计算机栏填:
VPS公网IP:7001 - 输入内网 Windows 的账号密码 → 进入桌面
方法二:Linux/Kali 下用 rdesktop
rdesktop VPS公网IP:7001排错提示:连不上先自查三件事——① VPS 防火墙有没有放行 7001;② 内网 Windows 是否已开启"允许远程桌面"(系统属性 → 远程);③ 在内网先测试
mstsc /v:127.0.0.1能通再谈穿透。很多人第一步就栽在没开系统自带的远程桌面功能上。
5.3 场景二:把内网 Web 服务发布到公网
假设你的内网 Linux 机器上跑着一个 Web 应用(端口 8080),想给外网同事看。客户端加一条 HTTP 代理:
# frpc.toml 中追加 [[proxies]] name = "web" type = "http" # 注意类型是 http localIP = "127.0.0.1" localPort = 8080 # 内网 Web 服务端口 customDomains = ["web.example.com"] # 换成你的域名服务端需要已经配置了vhostHTTPPort = 8060(4.2 节已加)。然后:
- 去域名服务商把
web.example.com解析(A 记录)到你的 VPS 公网 IP; - 重启 frpc 让新配置生效;
- 外网直接访问
http://web.example.com:8060就能打开你内网的 Web 服务。
原理:frps 的 8060 端口收到 HTTP 请求后,根据请求里的Host 域名判断该转发给哪台 frpc——这就是"虚拟主机"能力,多个域名可以共用一个 8060 端口,分别转到不同内网机器,非常省公网端口。
同理,
type = "https"+customDomains可以发布 HTTPS 服务(frps 侧开vhostHTTPSPort);UDP 服务把type改成udp即可(比如穿透游戏联机、设备 UDP 报文)。
六、进阶修炼:从"能跑"到"跑得专业"
6.1 ini → toml 迁移对照(老玩家必看)
如果你以前用的是 .ini,升级新版时对照这张表改,几分钟搞定:
| 语义 | 旧版 frps.ini | 新版 frps.toml |
|---|---|---|
| 主端口 | bind_port = 7000 | bindPort = 7000 |
| 口令 | token = 12345678 | auth.method = "token"auth.token = "12345678" |
| 面板端口 | dashboard_port = 7500 | webServer.port = 7500 |
| 面板账号 | dashboard_user = admin | webServer.user = "admin" |
| 面板密码 | dashboard_pwd = admin | webServer.password = "admin" |
| HTTP 入口 | vhost_http_port = 8060 | vhostHTTPPort = 8060 |
| 代理定义 | [rdp]+ 散落字段 | [[proxies]]数组 + 驼峰字段 |
| 语义 | 旧版 frpc.ini | 新版 frpc.toml |
|---|---|---|
| 服务器地址 | server_addr = x.x.x.x | serverAddr = "x.x.x.x" |
| 服务器端口 | server_port = 7000 | serverPort = 7000 |
| 本地端口 | local_port = 3389 | localPort = 3389 |
| 远程端口 | remote_port = 7001 | remotePort = 7001 |
| 自定义域名 | custom_domains = xxx | customDomains = ["xxx"] |
TOML 版还支持YAML / JSON和环境变量模板渲染,配置多了还能用
includes拆分成多个文件(类似 Nginx 的 conf.d),管理几百条代理也不乱。
6.2 STCP / XTCP:不想让流量过服务器的"私密通道"
TCP 模式所有流量都走 VPS,中转带宽吃紧、且 VPS 能看到你的明文数据。frp 还提供两种进阶模式:
- STCP(Secret TCP):frps 只负责牵线,两端 frpc 之间建立加密直连,且访问方必须持有相同的
secretKey才能连——适合"只有自己人要访问"的服务,比如加密 SSH; - XTCP(P2P TCP):在 STCP 基础上做UDP 打洞,打洞成功则完全 P2P 直连(不占用 VPS 带宽),思路和 ZeroTier 一致。缺点是对 NAT 类型有要求,打洞失败就退化成 STCP。
STCP 服务端配置与普通 TCP 几乎一样(代理类型写stcp,多一个secretKey);访问方不是直接连 VPS 端口,而是再跑一个 frpc 配[[visitors]]段,把远程服务映射到本地端口,然后访问127.0.0.1:本地端口。逻辑稍绕,但对带宽敏感、注重隐私的场景非常值。
6.3 给 frpc 也上个 systemd(Windows 用计划任务)
内网机器一重启 frpc 就没了?Linux 端照 4.4 节写个frpc.service即可。Windows 端最省事的方案是"任务计划程序":新建任务 → 触发器选"计算机启动时" → 操作填frpc.exe -c frpc.toml(起始目录选解压目录)。
七、安全与运维:别把家门钥匙挂门口
frp 本质是把内网服务暴露到公网,用得好是远程办公利器,用不好就是引狼入室。安全清单请收好:
- token 必须改:默认/弱口令等于裸奔,任何知道你 VPS IP 的人都能连上你的 frps;
- Dashboard 不要暴露公网:
webServer.addr改成127.0.0.1,需要看面板时用 SSH 隧道访问,或至少换强密码; - 只开放必要的 remotePort:用新版
allowPorts字段限制客户端能申请的端口范围,防止 frpc 被攻破后乱开端口; - 敏感服务优先 STCP:SSH、数据库这类高价值服务别用裸 TCP 挂公网,套一层 secretKey 直连模式;
- 及时升级:frp 这类 Go 单二进制工具升级极简单(换文件重启即可),历史上也曝出过安全公告(如 HTTP vhost 路由鉴权绕过、畸形请求导致拒绝服务等),追平最新稳定版是性价比最高的安全投入;
- 关注日志:Dashboard 和
journalctl -u frps都能看到谁在连、连了什么端口,异常连接早发现早处理。
八、常见问题速查表
| 现象 | 大概率原因 | 解决办法 |
|---|---|---|
frpc 报login to server failed | token 不一致 / 7000 端口没放行 | 核对 token;放行安全组端口 |
| frpc 登录成功但外网连不上 | 代理的 remotePort 没放行 | VPS 防火墙放行对应端口 |
| 远程桌面连不上 | 内网 Windows 没开远程桌面 | 系统属性开启;先用 127.0.0.1 自测 |
| 能连上但非常卡 | VPS 带宽不足 / 走了中继 | 升带宽;或改用 STCP/XTCP 直连 |
| HTTP 域名访问 404 | 域名没解析到 VPS / 没走 8060 | 配 A 记录;访问带端口 |
| 改完配置不生效 | 没重启 frpc / frps | systemctl restart 对应服务 |
| 服务器重启后 frp 没了 | 没用 systemd/计划任务托管 | 按 4.4/6.3 配置自启 |
九、写在最后:frp 在真实业务里的样子
黑漂技术佬身边最常见的 frp 用法,其实都挺朴素但刚需:
- 远程办公:居家连公司电脑,RDP/SSH 全走 frp,体验和坐在工位前差别不大;
- 客户现场设备运维:无人零售柜的工控机、农业大棚的边缘网关,内网跑一个 frpc,人在总部就能 SSH 上去看日志、改配置,省下的差旅费够买好几台 VPS;
- 临时给客户演示:本地开发的服务用 frp 一键发布,把地址甩给客户,比录屏演示有说服力得多;
- 家里 NAS / 相册 / 博客:一台低配 VPS + frp,把家里的服务一个个挂出去,全年稳定在线。
frp 的上手曲线很平缓:一台 VPS、两个文件、三行配置,半小时内就能跑通第一个穿透。真正拉开差距的是对原理的理解和对安全的敬畏——这两点,今天这篇都给你补上了。
去试试吧,把第一个服务穿出去的那一刻,你会觉得"远程"这个词从此有了新的含义。
附:知识地图
frp 内网穿透 ├─ 概念:内网穿透 / 转发模型(VPS 中转) ├─ frp 简介:frps(服务端) + frpc(客户端),Go 单文件 ├─ 选型:frp vs ngrok/花生壳 vs ZeroTier/Tailscale ├─ 环境:公网 VPS(带宽=瓶颈)+ 内网机器 + 测试机 ├─ 服务端 │ ├─ 下载解压(v0.71.x,注意架构) │ ├─ frps.toml:bindPort / auth.token / webServer / vhostHTTPPort │ ├─ systemd 托管(替代 nohup) │ └─ Dashboard :7500 看流量 ├─ 客户端 │ ├─ frpc.toml:serverAddr + [[proxies]] │ ├─ TCP 场景:RDP(3389→7001)、SMB(445→7002) │ ├─ HTTP 场景:customDomains + vhostHTTPPort 8060 │ └─ 启动:cmd 运行,禁止双击 ├─ 进阶 │ ├─ ini → toml 迁移对照表 │ ├─ STCP/XTCP:加密直连、P2P 打洞 │ └─ Windows 计划任务 / Linux systemd 自启 ├─ 安全:强 token / 面板内网化 / allowPorts / 及时升级 └─ 排错:登录失败 / 端口未放行 / RDP 未开 / 带宽卡顿