Cloudflare 域名反向代理配置:Nginx、Caddy 与 NPM 实践
在搭建个人网站、媒体服务或其他 Web 服务时,有时需要通过自己的服务器反向代理一个已经启用 Cloudflare 代理的 HTTPS 域名。
本文记录如何使用 Nginx、Caddy 和 Nginx Proxy Manager(NPM)实现这一需求,并重点说明 HTTPS 上游连接中的 Host 请求头、TLS SNI 以及常见故障的处理方法。
一、适用场景与工作原理
本文所说的「套了 CF」,是指目标域名已接入 Cloudflare,并启用了代理功能(DNS 记录显示为橙色云朵)。
假设有以下两个域名:
| 项目 | 示例域名 | 作用 |
|---|---|---|
| 代理入口 | proxy.example.net | 用户访问的域名 |
| 上游地址 | origin.example.com | 实际被反向代理的 HTTPS 域名 |
以上域名均为示例,请替换为自己的实际地址。
访问流程如下:
客户端
│
▼
proxy.example.net
│
▼
自己的反向代理服务器
│
│ HTTPS 请求
▼
origin.example.com
│
▼
Cloudflare 网络
│
▼
目标网站源站反向代理服务器负责接收客户端请求,再将请求转发给上游域名,并将上游响应返回给客户端。
这里需要注意几个概念:
- 反向代理入口域名:客户端访问的域名。
- 上游域名:反向代理服务器实际连接的目标域名。
- Host 请求头:HTTP 层用于标识目标主机的请求头。
- TLS SNI:TLS 握手时客户端发送的服务器名称,用于上游选择对应的证书和站点。
当上游使用 HTTPS 时,TLS SNI 和 HTTP Host 都可能影响连接是否成功。如果二者与上游站点的配置不匹配,就可能出现证书错误、访问到错误站点或 HTTP 403 等问题。
二、Nginx 配置
1. 基础反向代理配置
假设上游域名为 origin.example.com,可以在对应的 server 配置块中加入以下内容:
location / {
# 将请求转发至上游 HTTPS 域名
proxy_pass https://origin.example.com;
# 使用上游域名作为 HTTP Host
proxy_set_header Host origin.example.com;
# 传递客户端地址及原始访问信息
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 $scheme;
# 启用上游 TLS SNI
proxy_ssl_server_name on;
proxy_ssl_name origin.example.com;
}配置说明:
proxy_pass:指定上游 HTTPS 地址。proxy_set_header Host:将上游需要的主机名传递给目标站点。proxy_ssl_server_name on:启用上游 TLS SNI。proxy_ssl_name:明确指定 TLS 握手时使用的服务器名称。
如果上游使用标准 HTTPS 端口 443,可以省略端口号;如果上游使用其他端口,则应在 proxy_pass 中明确指定。
2. 检查并重载 Nginx
修改配置后,先检查语法:
nginx -t确认检查通过后再重载:
systemctl reload nginx如果配置文件存在语法错误,不要直接重启服务,应先修复问题。
3. 关于客户端真实 IP
上面的配置通过 X-Real-IP 和 X-Forwarded-For 传递客户端地址信息,但它们并不意味着上游一定能够获得客户端的真实公网 IP。
如果请求经过了其他 CDN 或代理层,$remote_addr 可能是前一层代理服务器的地址。只有在正确配置可信代理及真实 IP 解析规则后,才能可靠地获取客户端地址。
此外,X-Forwarded-For 可能包含多级代理的地址。上游应用应根据实际代理链和可信代理配置解析,而不应无条件信任客户端自行提交的请求头。
三、Caddy 配置
Caddy 的配置相对简洁。对于 HTTPS 上游,可以在 Caddyfile 中写入:
proxy.example.net {
reverse_proxy https://origin.example.com {
header_up Host {upstream_hostport}
}
}其中:
proxy.example.net是客户端访问的入口域名。https://origin.example.com是上游 HTTPS 地址。header_up Host {upstream_hostport}将上游主机地址设置为 HTTPHost。
对于 Caddy v2.11.0 及更新版本,HTTPS 上游的 Host 处理已经有相应的默认行为,通常不必再手动覆盖。保留上述写法可以明确表达配置意图,但如果希望保留原始请求的 Host,则需要根据目标站点的要求另行配置。
保存配置后,可以检查并重新加载 Caddy:
caddy validate --config /etc/caddy/Caddyfile
systemctl reload caddy请根据实际安装方式确认 Caddyfile 的路径。如果使用 Docker 部署,应在对应容器和挂载配置中执行检查及重载操作。
官方文档:Caddy reverse_proxy
四、Nginx Proxy Manager(NPM)配置
如果使用 Nginx Proxy Manager,通常可以先通过网页管理界面创建 Proxy Host,再在 Advanced 中添加必要的上游 HTTPS 配置。
1. 创建 Proxy Host
进入 NPM 管理界面,添加对应的 Proxy Host:
- Domain Names:填写代理入口域名,例如
proxy.example.net。 - Scheme:选择
https。 - Forward Hostname / IP:填写
origin.example.com。 - Forward Port:填写
443。 - 根据需要配置 SSL 证书、强制 HTTPS 等选项。
请确保 NPM 所在服务器可以解析并访问上游域名。
2. 配置 Advanced
如果上游要求明确的 TLS SNI,可以在 Advanced 中添加:
proxy_ssl_server_name on;
proxy_ssl_name origin.example.com;如果上游还要求 HTTP Host 与上游域名一致,可以根据当前 NPM 版本生成的 Nginx 配置,确认 Host 请求头的实际取值。必要时设置:
proxy_set_header Host origin.example.com;注意: NPM 会自动生成 location、proxy_pass 和请求头等配置。Advanced 内容会被插入生成的配置中,因此不要直接照搬一个完整的 location / { ... } 块,以免与 NPM 自动生成的 location 重复或发生嵌套错误。
不同版本的 NPM 生成配置可能有所不同。若修改后仍然出现 502 或访问到错误站点,可以检查最终生成的 Nginx 配置,确认 proxy_pass、Host 和 TLS SNI 的实际值。
官方文档:Nginx Proxy Manager Advanced Configuration
五、常见问题排查
1. 出现 502 Bad Gateway
可能原因:
- 上游域名无法解析。
- 上游 HTTPS 端口无法访问。
- 代理服务器无法连接 Cloudflare 网络。
- 上游 TLS 握手失败。
- Nginx 或 Caddy 配置错误。
可以在反向代理服务器上测试上游连接:
curl -I https://origin.example.com如果需要指定连接地址但保留正确的域名与 TLS SNI,可以使用:
curl -Iv \
--resolve origin.example.com:443:上游IP地址 \
https://origin.example.com/将 上游IP地址 替换为实际测试地址。注意,直接指定 IP 只适用于你确实需要测试某个特定连接地址的情况;如果上游域名使用 Cloudflare 代理,通常应优先测试正常的域名解析和连接链路。
2. 出现 403 Forbidden
403 不一定是反向代理配置错误。可能原因包括:
- 上游站点设置了访问限制。
- 目标站点要求特定的
Host。 - Cloudflare 安全规则拦截了请求。
- 上游站点限制了来源 IP 或访问方式。
建议先确认站点是否允许此类代理访问,再检查请求头和上游响应。不要通过伪造身份、绕过访问控制或规避目标站点的安全限制来解决问题。
3. 出现证书或 TLS 错误
如果上游使用 HTTPS,应确认:
- 上游域名解析正常。
proxy_ssl_server_name已启用。proxy_ssl_name与上游证书对应的主机名匹配。- 上游证书链有效且未过期。
不要为了消除错误而直接关闭 TLS 证书验证。正确做法是修复域名、SNI 或证书配置,确保上游连接仍然经过有效的 TLS 身份验证。
4. 页面可以打开,但部分资源加载失败
有些网站会在 HTML、CSS、JavaScript 或 API 请求中写入原始域名,也可能使用 WebSocket、重定向、绝对 URL 或 Cookie 域属性。
如果首页能够打开,但登录、图片、视频或其他功能异常,需要进一步检查:
- 浏览器开发者工具中的请求失败情况。
- 上游返回的
Location重定向地址。 - Cookie 的
Domain、Path和Secure属性。 - WebSocket 是否需要单独配置。
- 应用是否要求使用原始域名访问。
这类问题通常不是单纯增加 proxy_pass 或调整 SNI 就能完全解决的,需要根据目标应用的实际行为逐项排查。
六、安全与使用注意事项
- 确认拥有代理权限。 使用反向代理前,应确认目标站点允许相应访问方式,并遵守站点条款。
- 不要将反向代理当作绕过安全策略的工具。 Cloudflare 的访问控制、源站限制和安全规则仍可能生效。
- 保持 TLS 验证。 不要使用关闭证书验证的方式掩盖证书或 SNI 配置错误。
- 合理配置真实 IP。 仅信任明确配置的代理来源,不要无条件信任客户端传入的转发头。
- 注意上游服务的兼容性。 如果应用依赖原始域名、Cookie、WebSocket 或重定向,需要单独验证。
七、总结
通过 Nginx、Caddy 或 Nginx Proxy Manager,都可以将请求转发到启用了 Cloudflare 代理的 HTTPS 域名。
无论使用哪种工具,核心都是正确配置上游地址、HTTP Host 和 TLS SNI,并确保代理服务器能够正常连接上游。
如果只需要简单的 HTTPS 反向代理,可以优先选择自己熟悉的工具;如果使用 NPM,则建议先通过管理界面完成基础配置,再根据实际生成的 Nginx 配置补充必要参数。
完结,撒花。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭