在自建服务器或家庭网络场景中,常需要让局域网服务能够被公网安全访问。
FRP(Fast Reverse Proxy)是一款流行的内网穿透工具,可以帮助实现这一目标。
当系统采用 HTTPS 与反向代理架构时,正确获取真实访客 IP 需要额外配置。
本文介绍一种基于 FRP + Nginx + Proxy Protocol v2 的通用解决方案。
一、系统结构概览
整个体系由三部分组成:
- FRPS(服务端):部署在公网节点,负责接收内网客户端的连接;
- FRPC(客户端):运行在内网主机,与 FRPS 建立安全隧道;
- 反向代理(如 Nginx):位于内网,用于 TLS 终止与流量分发。
逻辑关系如下:
Internet → FRPS (QUIC/TLS)
↕
FRPC → Reverse Proxy (Proxy Protocol)
→ 内网服务
这种架构可同时实现多服务转发、端口复用与 TLS 加密通信。
二、FRPS 配置(公网端)
FRPS 作为核心入口,建议启用加密、认证和端口白名单。
# 通信端口配置
bindPort = <main_port>
quicBindPort = <main_port>
userConnTimeout = 30
# 启用认证
auth.method = "token"
auth.token = "<随机口令>"
auth.additionalScopes = ["HeartBeats", "NewWorkConns"]
# 限定允许的远端端口(示例)
allowPorts = [
{ single = <port_a> }, { single = <port_b> }, { single = <port_c> }, { single = <port_d> }, { single = <port_e> },
{ single = <port_f> }, { single = <port_g> }, { single = <port_h> }, { single = <port_i> }, { single = <port_j> },
{ single = <port_k> }, { single = <port_l> }, { single = <port_m> }, { single = <port_n> }, { single = <port_o> },
{ single = <port_p> }, { single = <port_q> }, { single = <port_r> }, { single = <port_s> }, { single = <port_t> }
]
# 启用加密
transport.tls.force = true
transport.tls.certFile = "/path/to/fullchain.pem"
transport.tls.keyFile = "/path/to/privkey.pem"
# 管理面板(可选)
webServer.addr = "0.0.0.0"
webServer.port = <dashboard_port>
webServer.user = "<用户名>"
webServer.password = "<密码>"
webServer.tls.certFile = "/path/to/fullchain.pem"
webServer.tls.keyFile = "/path/to/privkey.pem"
要点说明:
auth.token是服务端与客户端的唯一共享密钥;allowPorts建议仅列出确实在使用的端口;- Dashboard 建议启用 HTTPS 并限制访问来源;
- 若采用 QUIC,务必同时放通对应 UDP 端口。
三、FRPC 配置(内网端)
FRPC 运行在内网,负责建立安全连接并转发本地主机服务。
# 连接信息
serverAddr = "<服务器域名>"
serverPort = <main_port>
# 传输层协议
transport.protocol = "quic"
transport.tls.enable = true
# 认证信息
auth.method = "token"
auth.token = "<同上>"
auth.additionalScopes = ["HeartBeats", "NewWorkConns"]
# 管理接口(可选)
webServer.addr = "127.0.0.1"
webServer.port = <admin_port>
webServer.user = "<用户名>"
webServer.password = "<密码>"
# 示例代理项
[[proxies]]
name = "secure_entry"
type = "tcp"
localIP = "<内网地址>"
localPort = <内部服务端口>
remotePort = <对外端口>
# 关键:启用 Proxy Protocol v2,向反向代理传递真实访客 IP
transport.proxyProtocolVersion = "v2"
配置说明:
- 仅需要在对外提供 HTTPS 或 Web 访问的代理项上启用 Proxy Protocol;
- 其他纯 TCP/UDP 服务(如内部通信或文件同步)无需配置该项;
- 管理端口可用于状态查询或热加载,但应限制仅本地访问。
四、Nginx 反向代理配置(内网)
反向代理用于终止 TLS 并将请求转发到后端应用。
要让其识别 Proxy Protocol 头部,需要显式启用相关指令。
server {
listen 443 ssl http2 proxy_protocol;
server_name example.local;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# 信任 FRPC 来源
set_real_ip_from 127.0.0.1;
set_real_ip_from <内网网段>;
real_ip_header proxy_protocol;
real_ip_recursive on;
location / {
proxy_pass http://<backend_host>;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
⚠️ 注意
启用proxy_protocol后,若直接在本机访问该端口(未通过 FRP),连接会因缺少协议头而失败。
若需调试,可额外开放一个仅本地使用的不带proxy_protocol的监听端口。
五、验证与测试
- 启动或重载服务:
systemctl restart frps systemctl restart frpc nginx -t && systemctl reload nginx - 从外部访问对应服务后,检查访问日志:
tail -f /var/log/nginx/access.log如果日志中显示公网 IP 而非内网或 127.0.0.1,即表示真实 IP 透传成功。 - 也可通过 FRPC 管理接口查看连接状态:
curl -u <user>:<password> http://127.0.0.1:<admin_port>/api/status
六、安全建议
- 限制来源:仅允许可信 IP 访问 FRPS 公网端口;
- Token 管理:定期更换认证口令,防止泄露;
- 证书续期:确保 TLS 证书自动更新;
- 最小暴露原则:仅开放必要端口,避免冗余代理;
- Dashboard 保护:设置复杂密码或仅内网访问。
七、总结
通过 FRP 的 Proxy Protocol v2 与反向代理协同,可以在双层加密的前提下实现真实访客 IP 的安全透传。
该方案具备以下优点:
- 安全:全程加密、认证机制明确;
- 可扩展:支持多服务、多协议;
- 通用:适用于自建站点、私有云、家庭 NAS 等多种环境。
合理使用 FRP 与反向代理,不仅能实现安全的远程访问,还能保持日志准确性与访问可追溯性,是个人与小型团队自建服务的可靠方案。