1. 为什么需要内网穿透?
在开始讲解frp的具体部署之前,我们先要理解内网穿透的核心价值。想象一下这样的场景:你家里有一台NAS设备,存储了大量家庭照片和视频;或者你在办公室搭建了一个开发测试环境,需要在外出时也能访问。这些设备通常位于路由器后面,没有公网IP地址,外部网络无法直接访问它们。
传统解决方案包括:
- 向运营商申请公网IP(越来越难获得)
- 使用第三方商业穿透服务(如ngrok,但通常有流量限制)
- 端口映射(需要路由器支持且存在安全风险)
frp(Fast Reverse Proxy)作为开源解决方案,完美解决了这些痛点。它允许你通过一台具有公网IP的服务器(我们称为frps服务端)作为跳板,将内网服务暴露到公网。与同类工具相比,frp的优势在于:
- 完全开源可控
- 支持TCP/UDP/HTTP/HTTPS等多种协议
- 配置灵活,性能优异
- 社区活跃,文档完善
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与基础概念
2.1 硬件需求分解
部署frp需要至少两台机器:
-
服务端(frps):必须具有公网IP的服务器(如阿里云ECS)
- 最低配置:1核CPU/1GB内存(轻量级应用足够)
- 推荐配置:2核CPU/2GB内存(应对更高并发)
- 带宽建议:至少5Mbps(视业务流量而定)
-
客户端(frpc):需要穿透的内网设备
- 可以是树莓派、NAS、办公电脑等任何设备
- 对配置无特殊要求,能运行对应系统的frp客户端即可
2.2 网络拓扑示意图
code复制[外网设备] ←互联网→ [frps服务端(公网IP)] ←穿透隧道→ [frpc客户端(内网)] → [内网服务]
2.3 版本选择建议
访问frp的GitHub发布页(https://github.com/fatedier/frp/releases),选择适合的版本:
- Linux服务器:选择
frp_*_linux_amd64.tar.gz - Windows客户端:选择
frp_*_windows_amd64.zip - ARM设备(如树莓派):选择
frp_*_linux_arm64.tar.gz
提示:服务端和客户端的版本最好保持一致,避免兼容性问题
3. 服务端部署实战
3.1 基础安装步骤
以阿里云CentOS 7为例:
bash复制# 下载最新版本(请替换为实际版本号)
wget https://github.com/fatedier/frp/releases/download/v0.51.3/frp_0.51.3_linux_amd64.tar.gz
# 解压
tar -zxvf frp_0.51.3_linux_amd64.tar.gz
cd frp_0.51.3_linux_amd64/
# 查看文件结构
ls -l
关键文件说明:
frps:服务端可执行程序frps.ini:服务端配置文件frpc:客户端可执行程序(服务端不需要)frpc.ini:客户端配置示例(服务端不需要)
3.2 最小化配置详解
编辑frps.ini:
ini复制[common]
bind_port = 7000 # 客户端连接端口
token = your_secure_token_here # 认证令牌,防止未授权访问
dashboard_port = 7500 # 控制台端口
dashboard_user = admin
dashboard_pwd = admin@123
log_file = ./frps.log
log_level = info
log_max_days = 3
3.3 高级安全配置
生产环境建议添加以下配置:
ini复制[common]
...
# 限制允许连接的客户端IP(可选)
allow_ports = 2000-3000,4000-5000 # 允许代理的端口范围
# TLS增强安全
tls_only = true
3.4 系统服务配置
创建systemd服务文件/etc/systemd/system/frps.service:
ini复制[Unit]
Description=Frp Server Service
After=network.target
[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/usr/local/frp/frps -c /usr/local/frp/frps.ini
[Install]
WantedBy=multi-user.target
启用服务:
bash复制sudo systemctl daemon-reload
sudo systemctl enable frps
sudo systemctl start frps
3.5 防火墙配置
bash复制# 放行必要端口
sudo firewall-cmd --permanent --add-port=7000/tcp # 控制端口
sudo firewall-cmd --permanent --add-port=7500/tcp # 仪表盘
sudo firewall-cmd --reload
4. 客户端配置实战
4.1 Windows客户端配置示例
创建frpc.ini:
ini复制[common]
server_addr = your_server_ip # 替换为你的服务器IP
server_port = 7000
token = your_secure_token_here # 与服务端一致
[ssh] # 示例:暴露内网SSH
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000 # 通过服务器6000端口访问
[web] # 示例:暴露内网Web服务
type = http
local_port = 80
custom_domains = your.domain.com # 需要解析到服务器IP的域名
4.2 Linux客户端后台运行
使用nohup保持运行:
bash复制nohup ./frpc -c ./frpc.ini > frpc.log 2>&1 &
或配置为systemd服务(类似服务端配置)。
4.3 常见服务配置模板
远程桌面(RDP)
ini复制[rdp]
type = tcp
local_ip = 192.168.1.100 # 内网机器IP
local_port = 3389
remote_port = 7001
HTTP/HTTPS服务
ini复制[web]
type = http
local_port = 8080
custom_domains = demo.yourdomain.com
# HTTPS需要额外配置
[https]
type = https
local_port = 443
custom_domains = secure.yourdomain.com
文件共享(SMB)
ini复制[smb]
type = tcp
local_ip = 192.168.1.50
local_port = 445
remote_port = 7002
5. 域名与HTTPS高级配置
5.1 域名解析设置
-
在DNS服务商处添加A记录:
- 主机记录:
frp - 记录值:你的服务器IP
- TTL:建议600秒
- 主机记录:
-
配置frps支持域名访问:
ini复制[common]
...
vhost_http_port = 80
vhost_https_port = 443
subdomain_host = yourdomain.com
5.2 Let's Encrypt证书配置
ini复制[web]
type = https
custom_domains = secure.yourdomain.com
plugin = https2http
plugin_local_addr = 127.0.0.1:8080
plugin_crt_path = /path/to/cert.pem
plugin_key_path = /path/to/key.pem
plugin_host_header_rewrite = 127.0.0.1
plugin_header_X-From-Where = frp
5.3 Nginx反向代理配置
更专业的做法是使用Nginx处理HTTPS:
nginx复制server {
listen 443 ssl;
server_name frp.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
6. 监控与维护
6.1 仪表盘使用
访问http://your_server_ip:7500,输入配置的用户名密码,可以看到:
- 所有活跃的代理连接
- 流量统计图表
- 客户端版本信息
6.2 日志分析技巧
常见日志信息解读:
login to server success:客户端连接成功new proxy [ssh] success:代理规则生效port already used:端口冲突错误authentication failed:token不匹配
6.3 性能调优建议
- 连接池配置(减少连接建立开销):
ini复制[common]
...
pool_count = 10 # 每个代理的预建连接数
- 带宽限制(防止滥用):
ini复制[web]
...
bandwidth_limit = 10MB # 单个代理带宽限制
- 心跳检测配置:
ini复制[common]
...
heartbeat_timeout = 90
7. 安全加固方案
7.1 防火墙最佳实践
- 仅开放必要的端口
- 使用fail2ban防止暴力破解:
bash复制# 安装fail2ban
sudo yum install fail2ban
# 配置frp规则
sudo nano /etc/fail2ban/jail.d/frp.conf
添加内容:
ini复制[frp]
enabled = true
filter = frp
port = 7000
logpath = /var/log/frps.log
maxretry = 3
findtime = 3600
bantime = 86400
7.2 访问控制列表
ini复制[common]
...
allow_ports = 2000-3000,4000,5000 # 只允许这些远程端口
privilege_allow_ports = 3000-4000 # 特权模式允许的端口
7.3 定期维护检查清单
-
每月检查:
- 更新到最新版本
- 轮换认证token
- 审查访问日志
-
每季度检查:
- 更新SSL证书
- 评估带宽使用情况
- 检查防火墙规则
8. 常见问题排错指南
8.1 连接失败排查步骤
-
检查服务端:
bash复制
netstat -tulnp | grep frp systemctl status frps -
检查客户端日志:
bash复制tail -f frpc.log -
测试端口连通性:
bash复制
telnet your_server_ip 7000
8.2 典型错误解决方案
问题1:无法通过域名访问
- 检查DNS解析是否生效
- 确认frps配置了
vhost_http_port - 检查Nginx/Apache配置
问题2:连接频繁断开
- 调整
heartbeat_timeout - 检查网络稳定性
- 考虑使用
tcp_mux = true
问题3:带宽跑满
- 设置
bandwidth_limit - 使用
traffic_plugin进行流量统计
8.3 性能问题诊断
使用iftop监控实时流量:
bash复制sudo iftop -P -N -n -i eth0
关键指标观察:
- 单个连接占用过高带宽
- 异常连接数激增
- 不正常的重传包
9. 进阶应用场景
9.1 多级穿透架构
对于复杂网络环境:
code复制[公网服务器] ←→ [二级内网服务器] ←→ [最终目标设备]
配置示例:
ini复制# 二级服务器配置
[common]
role = server
bind_port = 7000
[range:master]
type = tcp
local_ip = 192.168.1.100
local_port = 6000-7000
remote_port = 6000-7000
9.2 负载均衡配置
ini复制[web]
type = http
local_ip = 192.168.1.101,192.168.1.102,192.168.1.103
local_port = 80
custom_domains = lb.yourdomain.com
load_balance = roundrobin
9.3 与Docker集成
使用Docker运行frps:
bash复制docker run -d --name frps \
-p 7000:7000 \
-p 7500:7500 \
-v /path/to/frps.ini:/etc/frp/frps.ini \
snowdreamtech/frps
10. 实际部署经验分享
在为客户部署frp解决方案的这些年,有几个关键经验值得分享:
-
端口规划:建议建立端口分配表,避免冲突。例如:
- 6000-6999:开发测试环境
- 7000-7999:生产环境
- 8000-8999:临时用途
-
配置版本控制:所有frpc.ini和frps.ini文件应该纳入git管理,记录每次变更。
-
灾备方案:准备备用服务器和自动切换脚本,核心业务建议部署双frps节点。
-
客户端管理:开发简单的Web界面批量管理frpc配置,特别是当有上百个客户端时。
-
监控集成:将frp指标接入Prometheus+Grafana,实现可视化监控。
最后一个小技巧:对于需要频繁修改配置的场景,可以使用include指令拆分配置:
ini复制[common]
...
include = conf.d/*.ini
这样每个服务可以单独一个配置文件,便于管理。
