内网穿透实战:用 frp 将本地服务安全暴露到公网

在没有公网 IP 的家庭宽带或公司内网里,想把跑在笔记本上的接口、数据库或调试页面临时分享给外部同事,往往卡在”别人访问不到”。内网穿透正是解决这一顽疾的通用方案:它在公网服务器与内网客户端之间建立一条加密隧道,把本地端口映射出去。开源项目 frp(Fast Reverse Proxy)轻量、配置直观,是目前最受欢迎的自建穿透工具之一。下面从架构到落地,完整走一遍。

一、内网穿透解决什么痛点

典型网络里,你的开发机藏在多层 NAT 之后,外部无法直连。内网穿透的思路是:在一台有公网 IP 的服务器上运行服务端(frps),在内网机器上运行客户端(frpc);frpc 主动连上 frps 并保持长连接,外部用户访问 frps 的公网端口时,流量经隧道转发到 frpc 背后的本地服务。整个过程不需要在路由器上做端口映射,也不需要申请固定公网 IP。

二、什么场景需要它

场景痛点frp 方案
远程 SSH 运维家里/机房机器无公网 IP把本地 22 端口映射为 frps 的一个 TCP 端口
本地 Web 联调微信/支付宝回调、OAuth 重定向需要公网可达把本地 8080 映射为 frps 的 HTTP 端口并绑定子域名
远程桌面临时帮家人/同事处理电脑问题把本地 3389(RDP)映射为 frps TCP 端口
演示与协作想把未上线的原型给客户看一眼临时开一条 Web 穿透,用完即关

如果你的目标是在两台设备之间组建稳定的私有网络(而非临时暴露某个端口),那么点对点 VPN(如 WireGuard 异地组网实战)往往是更合适的选择。frp 擅长”把某个端口暴露出去”,VPN 擅长”把两张网卡打通”。

三、frp 的核心概念

  • frps:服务端,部署在有公网 IP 的服务器上,统一接收外部流量。
  • frpc:客户端,跑在内网机器上,主动连 frps 并声明要暴露哪些本地端口。
  • proxy:一条穿透规则,类型支持 tcp / udp / http / https / stcp 等。
  • visitor:用于 stcp 等点对点模式的访问端,避免把端口直接暴露在公网。

四、搭建 frps 服务端

在公网服务器(以 Ubuntu 为例)下载 frp 后,新建 frps.toml。新版 frp 使用 TOML 配置:

# /etc/frp/frps.toml
bindPort = 7000          # frpc 连接 frps 的控制端口
auth.token = "换成一段足够随机的密钥"   # 客户端必须一致

# Web 类穿透使用的虚拟端口
vhostHTTPPort = 80
vhostHTTPSPort = 443

# 可选:后台管理面板
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "再换一段强密码"

用 systemd 托管 frps,保证开机自启、崩溃重启:

# /etc/systemd/system/frps.service
[Unit]
Description=frps
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/frps -c /etc/frp/frps.toml
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

放行防火墙(以 ufw 为例),只开放必要端口:

sudo ufw allow 7000/tcp   # 控制端口
sudo ufw allow 80/tcp     # HTTP 穿透
sudo ufw allow 443/tcp    # HTTPS 穿透
sudo ufw allow 7500/tcp   # 管理面板(建议仅内网或加 IP 限制)
sudo systemctl enable --now frps

五、客户端配置与常见穿透

内网机器上的 frpc.toml 通过 serverAddr 指向公网服务器。下面是三个最常用的场景。

# /etc/frp/frpc.toml
serverAddr = "你的公网服务器IP"
serverPort = 7000
auth.token = "与服务端一致的密钥"

# 1) 远程 SSH:把本地 22 映射为 frps 的 2222
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 2222

# 2) 本地 Web 联调:绑定子域名 web.example.com
[[proxies]]
name = "web"
type = "http"
localPort = 8080
customDomains = ["web.example.com"]

# 3) 远程桌面 RDP
[[proxies]]
name = "rdp"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3389
remotePort = 3389

配置完成后,外部即可用 ssh -p 2222 公网IP 连回内网机器;Web 场景则在 DNS 把 web.example.com 解析到 frps 公网 IP,访问即直达本地 8080。若本地服务本身跑在容器里,可参考 Docker 容器化部署实践 把 frpc 也放进同一网络,省去端口暴露的麻烦。

六、安全加固(必做)

  • 强制 token 鉴权:上面已配置 auth.token,杜绝未授权客户端连入。
  • 启用 TLS:在 frpc 增加 transport.tls.enable = true,防止控制通道被中间人窃听。
  • 最小端口暴露:只为真正需要的 proxy 分配 remotePort,关闭用不到的 Web 面板公网访问。
  • 前端再挡一层:HTTP 类穿透前可加 Nginx 反向代理 做 HTTPS 终止与限流,既加密又防刷。
  • 定期更新:frp 偶有安全修复,保持版本较新。

七、frp 与同类方案怎么选

方案部署成本是否需要自有服务器适用场景
frp低,单二进制需要一台公网服务器自建、可控、可同时穿透多端口
ngrok零,注册即用不需要(用官方隧道)临时演示、快速联调,免费版域名随机
Cloudflare Tunnel中不需要(需 Cloudflare 域名)把站点安全暴露,自带 CDN 与防护
WireGuard中需要服务器组点对点组建私有网络而非单端口暴露

八、排错与最佳实践

  • 连不上:先 telnet 公网IP 7000 确认控制端口可达,再查 frps/frpc 日志(默认 stdout)。
  • token 报错:两端 auth.token 必须完全一致,含大小写。
  • Web 访问 404:确认 customDomains 的 DNS 已解析到 frps,且 vhostHTTPPort 与访问端口一致。
  • 避免长期裸奔:演示用完即删对应 proxy;生产穿透务必叠加 TLS + 反向代理。
  • 自动化触发:把 frpc 启动写进开机任务,结合 GitHub Actions 做配置下发,团队成员一键接入。

九、小结

内网穿透把”没有公网 IP”这个障碍彻底抹平,而 frp 以极简的配置做到了生产可用的稳定。记住一个判断口诀:要”暴露端口”用 frp,要”打通两张网”用 WireGuard。把 token、TLS、反向代理这三道锁上好,你就能既方便又安全地随时连回自己的内网世界。

上一篇 前端国际化 i18n 实战:从 Intl 到多语言架构落地
下一篇 字符编码乱码排查实战:文件、程序与终端的编码一致性
最新评论
Docker 网络模式详解:bridge/host 生产选型 - FSData
Docker 网络模式详解:bridge/host 生产选型 - FSData
8月20日
[…] 注意最后那条:把端口绑定到 127.0.0.1,再由宿主机上的 Nginx 反代进来,比直接 -p 80:80 暴露安全得多,也方便统一做
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
8月20日
[…] Pinia 的工程化用法,可以参考我们之前的实战文章 《Vue3 组合式 API + Pinia:状态管理从入门到实战》,那里覆盖了 Sto
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
8月19日
[…] 状态,点一下就能起停容器,配合我们讲过的 Docker Compose 编排 […]
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
8月19日
[…] 缓存三大坑的本质都是”缓存失效导致请求穿透到数据库”。记住口诀:穿透用布隆、击穿用锁、雪崩用错峰。配合合理的过期策略
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
8月19日
[…] Docker 镜像部署。结合我们之前写的 Docker Compose 一键编排实战,可以在 CI […]