frp内网穿透搭建远程开发环境实战

2026-07-14 7 min read 0

一、真实场景:公司内网开发服务器,回家就废了

2024年3月,我接手一个电商项目,开发服务器部署在公司内网(IP: 192.168.1.100),数据库MySQL 8.0.35跑在上面,Redis 7.2.4做缓存。白天在公司用VSCode Remote-SSH直连,延迟<1ms,爽得很。

但晚上回家或者周末加班,问题来了:公司没有公网IP,路由器是TP-Link家用级,不支持端口映射。我只能用TeamViewer远程桌面,卡成PPT,延迟200ms+,敲个代码等半秒才显示。更坑的是,数据库连不上,每次都要手动导出SQL再导入本地。

试过Ngrok免费版,速度慢到怀疑人生,带宽被限制在1Mbps。试过ZeroTier,公司网络策略禁止安装虚拟网卡驱动。最后选了frp 0.58.0,自己搭中转服务器,总算解决了。

二、方案对比:为什么选frp

我对比了市面上主流的三种方案,测试环境:公司内网服务器(Ubuntu 22.04,4核8G),公网中转服务器(阿里云轻量应用服务器,2核4G,5Mbps带宽),客户端(MacBook Pro M1,家里宽带100Mbps)。

方案延迟(ms)带宽(Mbps)配置复杂度稳定性成本
Ngrok免费版180-2501差(经常断连)免费
ZeroTier30-5010-20中(依赖网络策略)免费
frp 0.58.08-154.5-5中高高(自建服务器)服务器月费30元

结论:如果你有公网服务器(哪怕最便宜的轻量云),frp是最优解。延迟低、带宽可控、完全自主。Ngrok免费版只适合临时测试,ZeroTier适合网络环境宽松的场景。

三、完整搭建步骤(frp 0.58.0)

3.1 准备工作

  • 公网服务器:阿里云轻量应用服务器,CentOS 7.9,2核4G,5Mbps带宽,公网IP: 123.123.123.123
  • 内网服务器:Ubuntu 22.04,4核8G,内网IP: 192.168.1.100
  • 客户端:MacBook Pro M1,macOS 14.3
  • frp版本:v0.58.0(2024年3月最新稳定版)

3.2 下载与安装

所有机器都下载同一个压缩包,里面包含frps(服务端)和frpc(客户端)。

# 公网服务器(服务端)
wget https://github.com/fatedier/frp/releases/download/v0.58.0/frp_0.58.0_linux_amd64.tar.gz
tar -zxvf frp_0.58.0_linux_amd64.tar.gz
cd frp_0.58.0_linux_amd64

# 内网服务器(客户端)
# 同样操作,或者用scp从公网服务器传过去
scp root@123.123.123.123:/root/frp_0.58.0_linux_amd64.tar.gz ./
tar -zxvf frp_0.58.0_linux_amd64.tar.gz
cd frp_0.58.0_linux_amd64

# Mac客户端(也是客户端,用于SSH连接)
# 下载macOS版本
wget https://github.com/fatedier/frp/releases/download/v0.58.0/frp_0.58.0_darwin_amd64.tar.gz
tar -zxvf frp_0.58.0_darwin_amd64.tar.gz
cd frp_0.58.0_darwin_amd64

3.3 服务端配置(frps.toml)

frp从0.52版本开始改用TOML格式配置文件,不再支持ini。注意版本兼容性。

# frps.toml - 公网服务器配置
bindPort = 7000          # frp控制端口,客户端连接用
bindAddr = "0.0.0.0"    # 监听所有网卡

# Web管理界面(可选,强烈建议开启)
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "your_strong_password_here"

# 认证令牌,客户端必须匹配
auth.token = "your_secret_token_here"

# 日志配置
log.to = "./frps.log"
log.level = "info"
log.maxDays = 3

# 连接池配置
transport.poolCount = 10

3.4 客户端配置(frpc.toml)

内网服务器上配置,把SSH、MySQL、Redis都穿透出去。

# frpc.toml - 内网服务器配置
serverAddr = "123.123.123.123"  # 公网服务器IP
serverPort = 7000
auth.token = "your_secret_token_here"

# SSH穿透 - 远程开发核心
[[proxies]]
name = "ssh-dev"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000  # 公网服务器上暴露的端口

# MySQL穿透
[[proxies]]
name = "mysql-dev"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3306
remotePort = 6001

# Redis穿透
[[proxies]]
name = "redis-dev"
type = "tcp"
localIP = "127.0.0.1"
localPort = 6379
remotePort = 6002

# HTTP服务穿透(比如你的开发环境有Web界面)
[[proxies]]
name = "web-dev"
type = "http"
localIP = "127.0.0.1"
localPort = 8080
customDomains = ["dev.yourdomain.com"]  # 需要DNS解析到公网服务器

3.5 启动服务

# 公网服务器启动frps
cd frp_0.58.0_linux_amd64
./frps -c frps.toml &

# 检查是否启动成功
netstat -tlnp | grep 7000  # 应该看到LISTEN
netstat -tlnp | grep 7500  # Web管理界面

# 内网服务器启动frpc
cd frp_0.58.0_linux_amd64
./frpc -c frpc.toml &

# 查看日志
tail -f frpc.log

3.6 客户端连接测试

在MacBook上测试SSH连接:

# 通过frp隧道连接内网服务器
ssh -p 6000 user@123.123.123.123

# 配置SSH config简化连接(~/.ssh/config)
Host dev-server
    HostName 123.123.123.123
    Port 6000
    User your_username
    IdentityFile ~/.ssh/id_rsa
    ServerAliveInterval 60
    ServerAliveCountMax 3

# 之后直接 ssh dev-server 即可

3.7 配置systemd实现开机自启

生产环境必须用systemd管理,否则进程挂了都不知道。

# 公网服务器 - 创建frps服务
sudo vim /etc/systemd/system/frps.service

[Unit]
Description=Frp Server Service
After=network.target

[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/root/frp_0.58.0_linux_amd64/frps -c /root/frp_0.58.0_linux_amd64/frps.toml
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

# 内网服务器 - 创建frpc服务(内容类似,路径改一下)
sudo vim /etc/systemd/system/frpc.service

[Unit]
Description=Frp Client Service
After=network.target

[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/home/user/frp_0.58.0_linux_amd64/frpc -c /home/user/frp_0.58.0_linux_amd64/frpc.toml

[Install]
WantedBy=multi-user.target

# 启用并启动
sudo systemctl enable frps
sudo systemctl start frps
sudo systemctl status frps

四、性能压测数据

测试工具:iperf3(带宽测试)、ping(延迟测试)、MySQL Workbench(数据库查询测试)。

4.1 延迟对比

场景平均延迟(ms)最大延迟(ms)丢包率
公司内网直连0.51.20%
frp隧道(家里)8.315.60.1%
TeamViewer远程桌面2104505%
Ngrok免费版1953802%

frp延迟8ms,完全满足SSH编辑代码的需求,VSCode Remote-SSH几乎感觉不到延迟。

4.2 带宽测试

# 内网服务器启动iperf3服务端
iperf3 -s -p 5201

# 家里客户端通过frp隧道测试(注意frp要配置iperf3端口穿透)
iperf3 -c 123.123.123.123 -p 6003 -t 30

# 结果:
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-30.00  sec  16.8 MBytes  4.70 Mbits/sec
[  5]   0.00-30.00  sec  16.8 MBytes  4.70 Mbits/sec

# 对比:Ngrok免费版
iperf3 -c 2.tcp.ngrok.io -p 12345 -t 30
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-30.00  sec  3.75 MBytes  1.05 Mbits/sec

frp几乎跑满了5Mbps带宽(利用率94%),Ngrok只有1Mbps(被限速)。

4.3 MySQL查询性能

测试查询:SELECT * FROM orders WHERE created_at > '2024-01-01' LIMIT 1000(orders表50万行数据)。

连接方式查询耗时(ms)数据传输时间(ms)
内网直连4512
frp隧道5825
Ngrok320280

frp隧道额外增加约26ms开销,完全可以接受。Ngrok因为带宽限制,数据传输时间暴涨。

五、避坑指南(我踩过的坑)

坑1:防火墙忘记放行端口

公网服务器配置好frps后,客户端一直连不上。排查了半小时,发现阿里云安全组没放行7000、6000-6002端口。还有系统防火墙(firewalld)默认是开启的。

# 阿里云控制台:安全组 → 入方向 → 添加规则
# 放行 TCP:7000,6000-6002,7500

# 系统防火墙
sudo firewall-cmd --zone=public --add-port=7000/tcp --permanent
sudo firewall-cmd --zone=public --add-port=6000-6002/tcp --permanent
sudo firewall-cmd --zone=public --add-port=7500/tcp --permanent
sudo firewall-cmd --reload

坑2:auth.token泄露

第一次配置用了弱密码"123456",结果第二天发现frp Web管理界面被登录,有人扫描端口。赶紧改了强密码,并限制Web管理界面只允许内网访问。

# frps.toml 安全加固
webServer.addr = "127.0.0.1"  # 只监听本地,通过SSH隧道访问
# 或者用nginx反向代理加HTTPS

坑3:SSH连接频繁断开

家里网络不稳定,SSH连接经常掉线。加了心跳配置后解决。

# 客户端SSH配置
Host dev-server
    ServerAliveInterval 30  # 每30秒发一个心跳包
    ServerAliveCountMax 3   # 连续3次无响应则断开
    TCPKeepAlive yes

坑4:frp版本不兼容

一开始下载了frp 0.51.0,配置文件是ini格式。后来升级到0.58.0,发现配置格式变了。注意:0.52版本开始改用TOML,0.50及之前用ini。升级时一定要看Release Notes。

# 查看当前版本
./frps --version
# frps version 0.58.0

# 旧版ini配置示例(0.50及之前)
[common]
bind_port = 7000
token = 123456

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

坑5:带宽跑满导致其他服务受影响

有一次同事用frp传输大文件(5GB数据库备份),把5Mbps带宽占满,导致我的SSH操作卡顿。解决方案:限速。

# frpc.toml 对特定代理限速
[[proxies]]
name = "file-transfer"
type = "tcp"
localIP = "127.0.0.1"
localPort = 9999
remotePort = 6005
transport.bandwidthLimit = "2MB"  # 限制2MB/s

坑6:Web管理界面暴露在公网

frp的Web管理界面默认监听0.0.0.0:7500,没有HTTPS,密码明文传输。建议用nginx反向代理加SSL,或者只监听127.0.0.1通过SSH隧道访问。

# 通过SSH隧道访问Web管理界面
ssh -L 7500:127.0.0.1:7500 root@123.123.123.123
# 然后浏览器打开 http://127.0.0.1:7500

六、进阶优化

6.1 多客户端复用同一个frps

团队多人需要连接不同的内网服务器,可以在frps上配置多个代理,每个客户端用不同的remotePort。

# frpc.toml - 同事A的配置
serverAddr = "123.123.123.123"
serverPort = 7000
auth.token = "team_token"

[[proxies]]
name = "ssh-dev-a"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6010  # 不同端口

# frpc.toml - 同事B的配置
[[proxies]]
name = "ssh-dev-b"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6011  # 不同端口

6.2 使用STCP模式提高安全性

STCP模式只允许特定的客户端访问,需要双方都配置相同的secretKey。

# frpc.toml - 内网服务器
[[proxies]]
name = "ssh-stcp"
type = "stcp"
localIP = "127.0.0.1"
localPort = 22
secretKey = "your_secret_key"

# frpc.toml - 家里客户端(也需要运行frpc)
[[visitors]]
name = "ssh-stcp-visitor"
type = "stcp"
serverName = "ssh-stcp"
secretKey = "your_secret_key"
bindAddr = "127.0.0.1"
bindPort = 2222

6.3 监控与告警

用Prometheus + Grafana监控frp运行状态。frp从0.52版本开始支持Prometheus指标导出。

# frps.toml 开启监控
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.enablePrometheus = true  # 开启Prometheus指标

# 访问 http://123.123.123.123:7500/metrics 查看指标

七、总结

frp是目前搭建远程开发环境最靠谱的方案,没有之一。只要你有台公网服务器(最低配轻量云30元/月),就能获得接近内网直连的开发体验。延迟8ms、带宽利用率94%,比Ngrok、ZeroTier强太多。

关键点:版本选对(0.58.0)、防火墙放行、心跳保活、安全加固。照着本文一步步来,半小时内就能跑起来。

最后说一句:别在公网暴露22端口,用frp的隧道端口(如6000)更安全,因为攻击者扫描不到你的真实SSH端口。

IT搬运工

专注技术分享,坚持原创深度内容。

分类
链接
订阅

RSS 订阅关注最新文章

© 2026 IT搬运工 · 站点地图 · 鄂ICP备19007640号-3