在自建服务器或家庭网络场景中,常需要让局域网服务能够被公网安全访问。
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 的监听端口。


五、验证与测试

  1. 启动或重载服务: systemctl restart frps systemctl restart frpc nginx -t && systemctl reload nginx
  2. 从外部访问对应服务后,检查访问日志: tail -f /var/log/nginx/access.log 如果日志中显示公网 IP 而非内网或 127.0.0.1,即表示真实 IP 透传成功。
  3. 也可通过 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 与反向代理,不仅能实现安全的远程访问,还能保持日志准确性与访问可追溯性,是个人与小型团队自建服务的可靠方案。

Leave a Reply

Your email address will not be published. Required fields are marked *