frps使用tcp协议通信到frpc + Nginx真实IP获取三种部署模式指南

社区话题 Linux/macOS 与自动化运维 frps使用tcp协议通信到frpc + Nginx真实IP获取三种部署模式指南

标签: ,

正在查看 1 条回复
  • 作者
    帖子
    • #1379

      追光
      管理员

      以下是完全分离的两种部署模式说明,每种模式独立成章,互不交叉,便于你按需选择和部署。

      frp 三种 Web 穿透架构的性能与处理能力对比(精简技术版)

      📌 模式一:不使用 PROXY 协议
      适用于绝大多数 HTTP/HTTPS 网站穿透场景,配置简单、安全、稳定。

      🧩 架构拓扑

      Client → [Nginx @ frps] → TCP + PROXY v2 → [frpc] → [Local Nginx]

      客户端
      ↓ (HTTP/HTTPS)
      公网服务器 Nginx(监听 80/443)
      ↓ (反向代理到本地 TCP 端口 如8080/8443)
      frpc(监听 remotePort,如 8080/8443 转发到本地tcp的80/443)
      ↓ (TCP 转发)
      本地 Nginx(监听 本地tcp的 80/443)

      ✅ frp 仅做 透明 TCP 转发,不插入任何协议头。
      ✅ 真实 IP 通过 HTTP Header(如 X-Real-IP)传递。

      1. frpc 配置(本地)

      toml

      
      #################http配置####################
      [[proxies]]
      name = "AMH-web"
      type = "tcp"
      localIP = "127.0.0.1"
      localPort = 80
      remotePort = 8080

      #################使用Nginx反代到此端口需要关闭v2#######
      #transport.proxyProtocolVersion = “v2”

      #transport.useEncryption = true
      #transport.useCompression = true

      #################https配置####################
      [[proxies]]
      name = “AMH-webs”
      type = “tcp”
      localIP = “127.0.0.1”
      localPort = 443
      remotePort = 8443

      #################使用Nginx反代到此端口需要关闭v2#######
      #transport.proxyProtocolVersion = “v2”

       

      ⚠️ 重要:不要启用 PROXY 协议
      transport.proxyProtocolVersion = “v2” ← 必须注释或删除

      2. 公网服务器 Nginx 配置

      nginx
      HTTP 反向代理

      server {
      listen 80;
      servername your.domain.com;

      location / {
      proxypass http://127.0.0.1:8080;
      proxysetheader Host $host;
      proxysetheader X-Real-IP $remoteaddr;
      proxysetheader X-Forwarded-For $proxyaddxforwardedfor;
      proxysetheader X-Forwarded-Proto $scheme;
      }
      }

      HTTPS 反向代理(SSL 终止在公网 Nginx)

      
      server {
      listen 443 ssl;
      servername your.domain.com;

      sslcertificate /path/to/fullchain.pem;
      sslcertificatekey /path/to/privkey.pem;

      location / {
      proxypass http://127.0.0.1:8443; 注意 https/http都可以,https需要在本地也要部署一次证书
      proxysslverify off; 若本地使用自签名证书
      proxysetheader Host $host;
      proxysetheader X-Real-IP $remoteaddr;
      proxysetheader X-Forwarded-For $proxyaddxforwardedfor;
      proxysetheader X-Forwarded-Proto $scheme;
      }
      }

      3. 本地 Nginx 配置(无需修改)

      nginx
      保持默认即可,无需 proxyprotocol

      server {
      listen 80;
      servername localhost;

      正常网站配置…
      }

      server {
      listen 443 ssl;
      servername localhost;

      sslcertificate /local/path/cert.pem;
      sslcertificatekey /local/path/key.pem;

      正常网站配置…
      }

      💡 在 PHP、Node.js 或日志中,通过 $SERVER[\’HTTPXREALIP\’] 或等效字段获取真实 IP。

      ✅ 优点

      既使用了nginx高性能的转发能力又实用了 frps上底层的原生tcp通讯
      兼顾性能与可用性,比较灵活。
      配置简单,兼容性好
      不依赖 frp 的 PROXY 协议支持
      安全:无 IP 伪造风险
      适用于 WordPress、PHP、静态站等所有 HTTP 应用


      📌 模式二:使用 PROXY 协议 v2(高级模式)
      适用于需要保留原始 TCP 连接、TLS 直通或本地 Nginx 必须获得 $remoteaddr 为真实 IP 的场景。

      🧩 架构拓扑

      Client → [frps] → TCP → [frpc] → [Local Nginx @ 127.0.0.1:80/443]

      客户端
      ↓ (TCP + PROXY v2 header)
      公网服务器 frps模块,不设置vhost )
      ↓ (转发带 PROXY 头的 TCP 流)
      frpc(remotePort 80/443)开启v2协议
      ↓ (转发到本地,保持 PROXY 头)
      本地 Nginx(listen … proxyprotocol)

      ✅ frpc 向本地 Nginx 转发 带 PROXY 协议头的原始连接
      ✅ 本地 Nginx 直接通过 $remoteaddr 获取真实 IP

      1. frpc 配置(本地)

      toml

      
      #################http配置####################
      [[proxies]]
      name = "AMH-web"
      type = "tcp"
      localIP = "127.0.0.1"
      localPort = 80
      remotePort = 8080

      #################不使用Nginx反代需要开启v2#######
      transport.proxyProtocolVersion = “v2”

      #transport.useEncryption = true
      #transport.useCompression = true

      #################https配置####################
      [[proxies]]
      name = “AMH-webs”
      type = “tcp”
      localIP = “127.0.0.1”
      localPort = 443
      remotePort = 8443

      #################不使用Nginx反代需要开启v2#######
      transport.proxyProtocolVersion = “v2”

      ✅ 显式启用 PROXY 协议 v2
      transport.proxyProtocolVersion = “v2”

      ⚠️ 确保 frp 版本 ≥ v0.50(支持 proxyProtocolVersion)

      3. 本地 Nginx 配置(必须启用 proxyprotocol)

      nginx http模式配置获取真实ip

      
      listen 80 proxy_protocol; #listen end
      set_real_ip_from 0.0.0.0/0;
      real_ip_header proxy_protocol;
      

      nginx https模式在V2协议下获取真实ip配置

      
      listen 443 ssl proxy_protocol;#listen end
      set_real_ip_from 0.0.0.0/0;
      real_ip_header proxy_protocol;
      

      ⚠️ 尽量使用真实ip setrealipfrom 0.0.0.0/0 这会允许任意 IP 伪造。

      ✅ 优点
      公网服务器与本地服务器之间建立的是纯TCP连接,相当于物理底层的直接通讯。
      frps–frpc 直接使用tcp拥有极致的吞吐量和网络传输性能,满足系统级的通讯链路要求
      本地 Nginx 的 $remoteaddr 就是真实客户端 IP
      支持 TLS 直通(无需在公网解密)
      适用于 WordPress、PHP、静态站等所有 HTTP 应用,以及广泛的tcp应用连接,udp应用连接。

      按需选择其一部署即可,两者不可混用。

      模式2 可以直接在本地像使用云服务器一样的的使用,申请ssl证书,部署多个网站均完全一样,且性能最高。

    • #1384

      追光
      管理员

      模式三:frp vhost 模式 + 无 PROXY 协议(推荐用于多站共享 80/443)

      适用于:
      • 公网服务器无 80/443 端口权限(如 NAT VPS、家用宽带)
      • 需要穿透多个域名到不同本地服务
      • 不要求本地 Nginx 的 remote_addr 为真实客户端 IP(可通过 Header 获取)
      • 完全关闭 PROXY 协议,配置更简单、更安全

      架构拓扑说明

      客户端
      ↓ (HTTP/HTTPS 请求,带 Host: your.domain.com)
      frps(监听 vhost_http_port / vhost_https_port,如 8080/8443)
      ↓ (基于 Host 头路由,TCP 转发,无 PROXY 协议)
      frpc(匹配 proxy name)
      ↓ (转发到 127.0.0.1:本地端口)
      本地 Nginx(标准监听 80/443)

      说明:
      • frps 替代 Nginx 作为反代,可以直接解析 Host 并路由到后端多台服务器
      • 全程不使用 PROXY 协议,transport.proxyProtocolVersion 必须关闭
      • 客户端真实 IP 通过 X-Real-IP 或 X-Forwarded-For Header 传递(由 frps 自动添加)

      一、frps 配置(公网服务器)

      启用 vhost HTTP / HTTPS 支持

      
      # HTTP/HTTPS 虚拟主机端口
      vhostHTTPPort =  80
      vhostHTTPSPort = 443
      custom404Page = "/home/usrdata/NetworkServer/frps/404.html"
      

      可选:绑定自定义域名(用于 HTTPS SNI)

      subdomain_host = yourdomain.com

      启动后,frps 会监听:

      • 0.0.0.0:8080 用于 HTTP
      • 0.0.0.0:8443 用于 HTTPS

      将域名 DNS 指向公网服务器 IP,然后通过
      http://your.domain.com

      如果vhost使用的是非 80 443端口,则可以额外使用 Nginx反向代理将域名转发到自定义的 vhost端口,那只是优化手段,不属于本模式的核心部分。

      二、frpc 配置(本地)

      
      #################http配置####################
      [[proxies]]
      name = "AMH-lnmp"
      #type = "http"
      type = "tcp"
      localIP = "127.0.0.1"
      localPort = 80
      remotePort = 8080
      #customDomains = ["*.x.newvfx.com", "x.newvfx.com"]
      
      #transport.useEncryption = true
      #transport.useCompression = true
      
      #################https配置####################
      [[proxies]]
      name = "AMH-lnmp-https"
      #type = "https"
      type = "tcp"
      localIP = "127.0.0.1"
      localPort = 443
      remotePort = 4443
      #customDomains = ["*.x.newvfx.com", "x.newvfx.com"]
      

      关键点:
      不启用 proxyProtocolVersion
      以下配置必须删除或注释:
      transport.proxyProtocolVersion = “v2”

      可选项(不影响本模式):
      transport.useEncryption = true
      transport.useCompression = true

      说明:
      • type 必须是 http 或 https,这是 vhost 模式的标志
      • customDomains 必须与客户端请求的 Host 头完全一致

      三、本地 Nginx 配置(标准配置,无需任何特殊修改)

      
      server {
      listen 80;
      server_name site1.example.com;
      
      location / {
      root /var/www/site1;
      index index.html;
      }
      
      }
      
      server {
      listen 443 ssl;
      server_name site2.example.com;
      
      ssl_certificate /path/to/site2.pem;
      ssl_certificate_key /path/to/site2.key;
      

      其余网站正常配置

      }

      说明:
      • 不需要 proxy_protocol
      • 不需要修改 remote_addr 的获取方式

      四、真实客户端 IP 的获取方式

      在 vhost 模式下,frps 会自动添加标准 Header:
      • X-Real-IP: 客户端真实 IP
      • X-Forwarded-For: 客户端真实 IP

      在nginx全局设置的http模块加入以下设置即可获取真实ip

      
      # ✅ 反代的真实客户端 IP
          set_real_ip_from 0.0.0.0/0;
          real_ip_header X-Forwarded-For;
          real_ip_recursive on;
      

      Nginx 日志示例:

      log_format main ‘$http_x_real_ip - $remote_addr - $request’;

      PHP 示例:

      $real_ip = $_SERVER[‘HTTP_X_REAL_IP’] ?? $_SERVER[‘REMOTE_ADDR’];

      安全说明:
      frps 是从 TCP 连接中获取客户端 IP 后写入 Header,客户端无法自行伪造,因为连接只来自 frps 公网服务器。

      五、如何让用户访问标准 80 / 443 端口

      由于 frps 实际监听的是 8080 / 8443,可以使用以下方式之一:

      方案 A:DNS + 显式端口访问
      • 用户访问 http://site1.example.com:8080
      • 适合测试环境或可接受非标准端口的场景

      方案 B:公网 Nginx 做端口转发(推荐)

      server {
      listen 80;
      server_name site1.example.com;
      location / {
      proxy_pass http://127.0.0.1:8080;
      proxy_set_header Host $host;
      }
      }

      说明:
      • frps 仍然工作在 vhost 模式
      • Nginx 仅做端口映射,不改变本模式本质

      方案 C:使用 CDN(例如 Cloudflare)
      • CDN 回源到 your.ip:8080
      • 用户访问标准 80 / 443
      • CDN 会通过 CF-Connecting-IP 等 Header 传递真实 IP
      • frps 注入的 X-Real-IP 会变为 CDN 节点 IP

      六、优点总结
      • 不占用公网 80 / 443 端口,适合端口受限环境
      • 支持多域名路由,一个 frpc 可穿透多个网站
      • 配置简单,不依赖 PROXY 协议
      • frps 自动注入真实 IP Header,安全可靠
      • 兼容 Let’s Encrypt,本地直接申请证书

      七、注意事项
      1. 不要混用 type = tcp 与 type = http / https,vhost 模式必须使用 http / https。
      2. customDomains 必须能够解析到 frps 的公网 IP(或通过 hosts 文件测试)。
      3. HTTPS 穿透时,证书必须部署在本地 Nginx,frps 不负责 SSL。
      4. 不要启用 proxyProtocolVersion,否则连接会失败,vhost 模式不支持 PROXY 协议。

      模式三是 Web 穿透场景中最推荐的 frp 部署方式,在功能、安全性和易用性之间取得了良好平衡。

正在查看 1 条回复
  • 在下方一键注册,登录后就可以回复啦。