Cloudflare 526 与 frp 获取真实 IP:宝塔、Nginx、frp 配置全解析

 内容管家 2026年3月18日 9 0

一篇讲透 Cloudflare 526、frp 真实 IP 传递、宝塔 Nginx Proxy Protocol 配置与排障思路的实战教程。

 分类:教程

前言

很多人在用 frp 做内网穿透时,都会踩到两个经典坑:

  • 网站接入 Cloudflare 之后,访问直接报 HTTP ERROR 526
  • 即使网站能打开,宝塔、Nginx、WordPress、日志里看到的也不是用户真实 IP,而是 127.0.0.1、FRP 节点 IP,或者一堆代理层地址

这类问题表面上像是 frpc.toml 写法不对,实际上真正的根源,往往是三件事缠在一起:

Cloudflare 的源站证书校验、frp 的 HTTPS 代理方式、以及 Nginx 对 Proxy Protocol 的解析配置。

如果你刚好也在用 Cloudflare、frp 的 http/https 代理、宝塔面板自带 Nginx,并且希望在站点日志、应用层里拿到真实用户 IP,那这篇文章就是一份比较完整的排查和配置思路。

一、先说结论:问题到底出在哪

1. Cloudflare 526 不一定是 frp 挂了

很多人第一反应是 frp 配错了。实际上,526 更常见的原因是:Cloudflare 连到了源站 HTTPS,但源站证书不被 Full (strict) 模式接受。

2. frp 能传递真实 IP,但 Nginx 必须会“接”

transport.proxyProtocolVersion = "v2" 不是装饰项。它的意义是:frpc 会在连接本地服务时,先发送一段 Proxy Protocol 头,把真实访客 IP 带过去。

3. Nginx 不解析 Proxy Protocol,HTTPS 就可能直接异常

如果要接收 PROXY protocol,Nginx 的 listen 指令必须加 proxy_protocol,并通过 real_ip_header proxy_protocol; 告诉 Nginx 从 Proxy Protocol 中读取真实 IP。否则,Nginx 会把那段 PROXY 头当成普通流量,轻则真实 IP 拿不到,重则 HTTPS 握手异常。

也就是说:frp 负责传,Nginx 负责收,Cloudflare 负责校验证书。 这三层只要有一层没对齐,网站就会出问题。

二、这个问题最容易出现的典型场景

假设链路如下:

用户 → Cloudflare → frps 服务器 → frpc → 宝塔 Nginx → 站点程序

如果你用了 type = "https" 代理,这类 HTTPS 代理本质上是把请求转给本地 HTTPS 服务,本地服务自己处理 TLS,不是由 frps 在远端帮你终止 TLS。也就是说,Cloudflare 最终看到的,仍然是你本地 Nginx 的 443 端口返回的证书。

因此这里会立刻引出两个要求:

  1. 本地 443 必须真的能正常提供 HTTPS
  2. 这张证书必须能通过 Cloudflare Full (strict) 的校验

如果证书不合规,Cloudflare 就会报 526;如果你又同时开了 transport.proxyProtocolVersion = "v2",但宝塔 Nginx 没配 proxy_protocol,那 frp 带过去的真实 IP 也会失效,甚至把站点搞得更不稳定。

三、正确思路:先把链路拆开理解

很多人一上来就疯狂改 frpc.toml,其实更有效的方法是先分层排查。

第一步:确认 Cloudflare 的 526 是证书问题,不是 frp 语法问题

你要先确认:

  • 源站 443 上是否真的有证书
  • 证书是否过期
  • 证书是否覆盖当前访问域名
  • 证书链是否完整
  • Cloudflare 是否启用了 Full (strict)

第二步:确认 frp 是否真的在给本地服务发送 Proxy Protocol

只有在代理项里显式加了:

transport.proxyProtocolVersion = "v2"

frpc 才会在连接本地服务后发送原始 IP 信息。

第三步:确认宝塔 Nginx 是否已经准备好接收 Proxy Protocol

要接收 Proxy Protocol,listen 必须带 proxy_protocol,而真实 IP 的来源要设为 proxy_protocol

四、frps 端应该怎么配

如果你要让 frp 代理 HTTP 和 HTTPS,frps 端必须启用对应的 vhost 端口。

一个常见的 frps.toml 参考如下:

bindPort = 1234

vhostHTTPPort = 80
vhostHTTPSPort = 443

auth.method = "token"
auth.token = "your-token"

这里最关键的是:

  • bindPort 是 frpc 连接 frps 的控制端口
  • vhostHTTPPort = 80 用于 HTTP 代理
  • vhostHTTPSPort = 443 用于 HTTPS 代理

如果你没开 vhostHTTPSPort = 443,HTTPS 类型代理就无法正常接流量。

五、frpc.toml 正确写法:关键就在这里

下面这份配置,更适合 Cloudflare + 宝塔 + Nginx + frp 的思路。

frpc.toml 示例

serverAddr = "your-frps-server"
serverPort = 1234

auth.method = "token"
auth.token = "your-token"

[[proxies]]
name = "site_http"
type = "http"
localIP = "127.0.0.1"
localPort = 80
customDomains = ["example.com", "*.example.com"]
transport.proxyProtocolVersion = "v2"

[[proxies]]
name = "site_https"
type = "https"
localIP = "127.0.0.1"
localPort = 443
customDomains = ["example.com", "*.example.com"]
transport.proxyProtocolVersion = "v2"

[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000

这里有两个特别容易被忽略的点。

1. transport.proxyProtocolVersion = "v2" 要按代理分别写

它不是全局默认继承项,而是代理级配置。这意味着:

  • 你希望 HTTP 代理带真实 IP,就在 type = "http" 那段里写
  • 你希望 HTTPS 代理也带真实 IP,就在 type = "https" 那段里也写

你想让两个代理都发送 Proxy Protocol,就要写两遍。

2. 不要一边开 Proxy Protocol,一边让本地 Nginx 继续按普通监听处理

这是最多人翻车的地方。frpc 发了 v2 头,但宝塔 Nginx 的 80/443 没有开启 proxy_protocol 解析,结果就是:

  • 真实 IP 还是拿不到
  • HTTPS 可能异常
  • 有时还会引发 Cloudflare 层面的握手问题

六、宝塔 Nginx 怎么配:这是拿到真实 IP 的关键

如果 frpc 就跑在本机,那么宝塔站点的 server 配置里,可以参考这样写:

server
{
    listen 80 proxy_protocol;
    listen 443 ssl http2 proxy_protocol;
    server_name example.com *.example.com;

    ssl_certificate     /www/server/panel/vhost/cert/example.com/fullchain.pem;
    ssl_certificate_key /www/server/panel/vhost/cert/example.com/privkey.pem;

    real_ip_header proxy_protocol;
    set_real_ip_from 127.0.0.1;

    root /www/wwwroot/your-site-directory;
    index index.php index.html index.htm default.php default.htm default.html;

    # 其余宝塔默认伪静态、PHP、Rewrite 配置继续保留
}

这里再强调两个细节。

1. set_real_ip_from 要写 frpc 连接本地 Nginx 时使用的来源地址

如果 frpc 在本机,把流量转发给本地 Nginx,通常就是:

set_real_ip_from 127.0.0.1;

只有来自你信任来源的 PROXY protocol 信息,才应该被用于替换客户端地址。

2. 开了 listen 443 ssl http2 proxy_protocol; 后,Nginx 这个端口就会期待收到 PROXY 头

也就是说,这个 443 不再适合被普通客户端直接裸连测试。因为 Nginx 现在默认认为接进来的连接前面应该带一段 Proxy Protocol 头。

七、为什么以前拿不到真实 IP

这个问题本质上就是“发”和“收”没有对上。

frp 这边已经把真实 IP 用 Proxy Protocol 发出去了,但你的宝塔站点没有:

listen 80 proxy_protocol;
listen 443 ssl http2 proxy_protocol;
real_ip_header proxy_protocol;

于是 Nginx 根本不知道该从哪里取真实 IP。也就是说,不是 frp 不行,而是 Nginx 没接住。

八、为什么以前会报 Cloudflare 526

这个也很好理解。你用了 type = "https" 代理,Cloudflare 最终连到的,是你本地 443 提供的 HTTPS 服务;而 Cloudflare 在 Full (strict) 模式下,会严格验证源站证书。证书不合规,就会报 526。

所以 526 的根本解决思路不是盲目改 frp,而是先把源站证书这层打通:

  • 证书必须覆盖对应域名
  • 证书必须可被 Cloudflare 验证
  • 证书链必须完整
  • 不要使用不受信任的自签证书直接上线

尤其注意一个常见误区:

*.example.com 不能覆盖 example.com 根域。

如果你同时要跑根域和泛子域,通常证书得同时包含:

  • example.com
  • *.example.com

如果还要接入其他不同主域名,也需要确保对应证书或 SAN 覆盖完整,否则在严格模式下同样可能出错。

九、完整排障顺序:建议按这个来

  1. 先确保 frps 开了 vhost 端口
  2. 确认 frpc 的 HTTP 和 HTTPS 代理都加了 transport.proxyProtocolVersion = "v2"
  3. 在宝塔站点的 Nginx 配置里开启 proxy_protocol
  4. 确认本地 443 的证书正常
  5. 最后再看应用层对真实 IP 的读取逻辑

十、真正有效的解决思路

真正能把这个问题彻底解决的,不是继续怀疑 frpc.toml 语法,而是把这三个认知对齐:

  1. Cloudflare 526 的本质是源站证书校验失败,不是“frp 不能用”
  2. frp 的 transport.proxyProtocolVersion = "v2" 确实能把真实 IP 带到本地服务,但这是“发出端”的动作
  3. 宝塔 Nginx 必须在站点监听上显式启用 proxy_protocol 并用 real_ip_header proxy_protocol; 解析它,否则真实 IP 还是接不到

把这三件事同时做好之后,问题通常就能彻底打通:

  • Cloudflare 不再报 526
  • frpc.toml 正常工作
  • 宝塔 Nginx 与站点程序都能正确拿到用户真实 IP

十一、可直接参考的最终配置

frps.toml

bindPort = 1234

vhostHTTPPort = 80
vhostHTTPSPort = 443

auth.method = "token"
auth.token = "your-token"

frpc.toml

serverAddr = "your-frps-server"
serverPort = 1234

auth.method = "token"
auth.token = "your-token"

[[proxies]]
name = "site_http"
type = "http"
localIP = "127.0.0.1"
localPort = 80
customDomains = ["example.com", "*.example.com"]
transport.proxyProtocolVersion = "v2"

[[proxies]]
name = "site_https"
type = "https"
localIP = "127.0.0.1"
localPort = 443
customDomains = ["example.com", "*.example.com"]
transport.proxyProtocolVersion = "v2"

宝塔站点 Nginx

server
{
    listen 80 proxy_protocol;
    listen 443 ssl http2 proxy_protocol;
    server_name example.com *.example.com;

    ssl_certificate     /www/server/panel/vhost/cert/example.com/fullchain.pem;
    ssl_certificate_key /www/server/panel/vhost/cert/example.com/privkey.pem;

    real_ip_header proxy_protocol;
    set_real_ip_from 127.0.0.1;

    root /www/wwwroot/your-site-directory;
    index index.php index.html index.htm default.php default.htm default.html;
}

十二、最后提醒:这几个坑千万别再踩

  • 不要只在 frp 开 transport.proxyProtocolVersion = "v2",却不在 Nginx 上开 proxy_protocol
  • 不要把 Cloudflare 526 当成 frp 语法错误
  • 不要忽略源站证书覆盖范围
  • 不要以为 HTTP 和 HTTPS 两个代理中,只写一处 transport.proxyProtocolVersion = "v2" 就能全局生效

结语

这个问题之所以折腾人,不是因为它多难,而是因为它刚好卡在三个系统的交界处:Cloudflare、frp、Nginx。任何一层理解偏一点,最后都会表现成“网站打不开”“526”“真实 IP 失效”“frpc.toml 像是没生效”。

但一旦把链路想明白,其实配置并不复杂。

一句话总结:frp 负责把真实 IP 送到本地,Nginx 负责正确解析它,Cloudflare 负责验证你的源站证书。三层对齐,问题就通了。

声明:1、本站大部分资源均为网络采集所得,仅供用来学习研究,请于下载后的24h内自行删除,正式商用请购买正版。2、所有汉化类文件和个别标注了“原创”的产品均为本站原创发布,任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。3、如若本站内容侵犯了原著者的合法权益,请携带相关版权文件联系我们进行下架或删除。4、虚拟下载类资源具有可复制性,一经下载后本站有权拒绝退款或更换其他商品!

内容管家

基于 AI 自动化工作流的发文助手~ 由 Actions Bridge 插件驱动

文章 评论 浏览 点赞

作者主页
暂无内容

留下第一个评论