1. 问题背景与解决方案概述
当我们在服务器上部署frps(Fast Reverse Proxy Server)服务时,默认需要使用7000-7500端口范围。但实际业务场景中,用户往往希望通过域名直接访问(如https://example.com),而不想记忆复杂的端口号(如https://example.com:7443)。此时若80端口已被其他Nginx服务占用,就需要通过反向代理实现无端口访问。
我最近在客户生产环境就遇到了这个典型场景:主站已占用80/443端口,但需要新增frps服务供移动端接入。经过多种方案对比,最终采用Nginx二级目录反代方案,既不影响现有服务,又实现了业务需求。下面分享具体实现过程和踩坑经验。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 前置条件准备
2.1 环境检查清单
在开始配置前,请确保已具备以下条件:
- 已安装Nginx(版本≥1.18)且运行正常
- 现有Nginx服务已占用80端口(可通过
netstat -tulnp | grep :80验证) - frps服务已部署且运行在非80端口(如默认的7000-7500范围)
- 拥有有效的域名和DNS解析权限
2.2 端口冲突验证方法
通过以下命令检查端口占用情况:
bash复制# 查看80端口占用进程
sudo lsof -i :80
# 查看frps运行端口(通常为7000)
ps aux | grep frps
3. Nginx反向代理配置详解
3.1 核心配置模板
在现有Nginx配置中(通常在/etc/nginx/conf.d/目录下)新增一个server块:
nginx复制server {
listen 80;
server_name frp.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:7000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 以下为WebSocket支持关键配置
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
3.2 关键参数解析
- proxy_pass:将流量转发到本机7000端口(frps默认端口)
- Upgrade头:必须添加以支持WebSocket协议
- 缓冲优化(可选添加):
nginx复制proxy_buffering off; proxy_buffer_size 16k; proxy_busy_buffers_size 24k; proxy_buffers 64 4k;
4. frps服务端适配配置
4.1 frps.ini必要调整
ini复制[common]
bind_port = 7000
vhost_http_port = 7080 # 必须与Nginx转发端口一致
4.2 多域名场景配置
如果需要通过同一Nginx实例代理多个frp服务:
nginx复制server {
listen 80;
server_name frp1.domain.com;
location / { proxy_pass http://127.0.0.1:7001; }
}
server {
listen 80;
server_name frp2.domain.com;
location / { proxy_pass http://127.0.0.1:7002; }
}
5. HTTPS安全加固方案
5.1 Let's Encrypt证书申请
bash复制sudo certbot --nginx -d frp.yourdomain.com
5.2 SSL配置模板
nginx复制server {
listen 443 ssl;
server_name frp.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/frp.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/frp.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:7000;
# 保持前述所有proxy_set_header配置
}
}
# HTTP强制跳转HTTPS
server {
listen 80;
server_name frp.yourdomain.com;
return 301 https://$host$request_uri;
}
6. 性能调优与安全防护
6.1 连接数优化
nginx复制proxy_connect_timeout 75s;
proxy_read_timeout 1800s; # 长连接超时设置
proxy_send_timeout 1800s;
keepalive_timeout 1800s;
6.2 安全防护措施
nginx复制# 禁止非法域名访问
server {
listen 80 default_server;
return 444;
}
# 限制请求频率
limit_req_zone $binary_remote_addr zone=frplimit:10m rate=30r/m;
location / {
limit_req zone=frplimit burst=50;
}
7. 常见问题排查指南
7.1 502 Bad Gateway错误
检查步骤:
- 确认frps服务运行状态:
systemctl status frps - 验证端口连通性:
telnet 127.0.0.1 7000 - 查看Nginx错误日志:
tail -f /var/log/nginx/error.log
7.2 WebSocket连接失败
典型症状:能建立HTTP连接但无法升级WebSocket
解决方案:
- 确保Nginx配置中包含
Upgrade和Connection头 - 检查frpc客户端是否启用
protocol = websocket - 测试WebSocket连通性:
wscat -c ws://frp.yourdomain.com
7.3 性能瓶颈分析
监控命令:
bash复制# 查看Nginx连接状态
ss -ant | grep :80
# 监控frps资源占用
htop -p $(pgrep frps)
8. 高级应用场景扩展
8.1 基于SNI的混合代理
当需要同一IP服务多个域名时:
nginx复制map $ssl_preread_server_name $backend {
frp1.domain.com 127.0.0.1:7001;
frp2.domain.com 127.0.0.1:7002;
}
server {
listen 443;
proxy_pass $backend;
ssl_preread on;
}
8.2 负载均衡配置
nginx复制upstream frp_cluster {
server 127.0.0.1:7000 weight=5;
server 192.168.1.100:7000;
server 192.168.1.101:7000;
}
server {
location / {
proxy_pass http://frp_cluster;
}
}
9. 配置验证与维护建议
9.1 自动化测试脚本
bash复制#!/bin/bash
# 测试HTTP访问
curl -I http://frp.yourdomain.com
# 测试WebSocket
wscat -c ws://frp.yourdomain.com
# 检查SSL证书
openssl s_client -connect frp.yourdomain.com:443 -servername frp.yourdomain.com | openssl x509 -noout -dates
9.2 日志分析技巧
关键日志位置:
- Nginx访问日志:
/var/log/nginx/access.log - frps运行日志:
/var/log/frps.log
常用分析命令:
bash复制# 统计TOP 10访问IP
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head
# 监控异常状态码
tail -f access.log | grep -E ' 50[0-9] '
10. 架构优化思考
在实际部署中发现,当并发量超过5000时,单Nginx实例可能出现性能瓶颈。建议考虑以下优化方案:
-
TCP层代理:改用stream模块实现四层代理
nginx复制stream { server { listen 443; proxy_pass 127.0.0.1:7000; } } -
内核参数调优:
bash复制echo 'net.core.somaxconn = 65535' >> /etc/sysctl.conf echo 'net.ipv4.tcp_max_syn_backlog = 65535' >> /etc/sysctl.conf sysctl -p -
多进程隔离:为frp服务单独部署Nginx worker进程
nginx复制worker_processes auto; events { worker_connections 10000; use epoll; }
