不需设置trustIPs, 使用traefik在 Cloudflare 后安全获取客户端真实 IP
-
目标
通过 Cloudflare 添加自定义 header 和 token,在 Traefik 中启用 header 转发并验证 token,最后在后端安全获取客户端真实 IP。
步骤
1. 在 Cloudflare 中设置自定义 Header 和 Token
- 登录 Cloudflare 仪表盘,选择你的域名。
- 导航到 Rules(规则) > Transform Rules(转换规则) > Modify Request Header(修改请求头)。
- 创建一个新规则:
- 规则名称:例如
Add-Auth-Token
- 匹配条件:选择所有传入请求(
All incoming requests
),或根据需要设置特定路径。 - 操作:选择
Add Header
(添加头部)。 - Header 名称:例如
X-Auth-Token
。 - Header 值:输入一个安全的 token,例如
your-secret-token-123
(建议使用复杂且唯一的字符串)。
- 规则名称:例如
- 保存并部署规则。
- 所有通过 Cloudflare 的请求都会带上
X-Auth-Token: your-secret-token-123
。
- 所有通过 Cloudflare 的请求都会带上
2. 在 Traefik 中启用 Header 转发
Traefik 默认会转发所有 header,我们只需要确保它能正确处理 Cloudflare 的真实 IP header(如
CF-Connecting-IP
)。- 编辑 Traefik 的配置文件(
traefik.yml
):entryPoints: web: address: ":80" forwardedHeaders: insecure: true # 允许转发所有 header,包括 CF-Connecting-IP
insecure: true
表示 Traefik 会信任并转发上游(如 Cloudflare)发送的 header,无需显式指定trustedIPs
。
3. 在站点配置中匹配 Header 和 Token
在 Traefik 的动态配置中,添加中间件以验证
X-Auth-Token
,确保只有合法请求被转发到后端。- 创建路由规则(例如在动态配置文件中):
routers: my-site: rule: "Host(`example.com`) && Header(`X-Auth-Token`, `your-secret-token-123`)" service: my-service middlewares: - auth-token services: my-service: loadBalancer: servers: - url: "http://backend:8080"
4. 在后端程序中安全获取真实 IP
在后端代码中,进一步验证
X-Auth-Token
,确保只有来自 Cloudflare 的合法请求的 IP 被信任。示例(使用 Python Flask):
from flask import Flask, request app = Flask(__name__) VALID_TOKEN = "your-secret-token-123" @app.route('/') def get_client_ip(): auth_token = request.headers.get("X-Auth-Token") if auth_token != VALID_TOKEN: return "Unauthorized: Invalid token", 403 # 信任 Cloudflare 的 CF-Connecting-IP real_ip = request.headers.get("CF-Connecting-IP", request.remote_addr) return f"Client Real IP: {real_ip}" if __name__ == "__main__": app.run(host="0.0.0.0", port=8080)
这种方法的优点
- 无需维护
trustedIPs
列表:- 使用
trustedIPs
需要手动列出 Cloudflare 的 IP 范围(如173.245.48.0/20
等),而 Cloudflare 的 IP 列表可能会更新。每次更新都需要手动调整配置,非常麻烦且容易出错。 - 本方法通过 token 验证请求来源,完全避免了依赖 IP 列表的维护问题。
- 使用
- 更高的灵活性:
- Token 可以随时在 Cloudflare 仪表盘中更改,无需修改服务器端配置文件,操作更简单。
- 相比硬编码 IP 范围,token 的动态性更适合快速调整安全策略。
- 增强安全性:
- 即使攻击者伪造了 Cloudflare 的 IP,也无法通过 token 验证,确保只有合法请求被信任。
- 避免了因 IP 列表过时而导致的安全漏洞。
- 简化配置:
- 不需要频繁同步 Cloudflare 的 IP 列表到 Traefik,减少了配置复杂度和维护成本。
注意事项
- 安全性:
X-Auth-Token
是核心验证依据,建议定期更新并通过环境变量管理。- 如果使用
forwardedHeaders.insecure: true
,确保后端严格验证 token。
- 测试:
- 使用
curl
测试:curl -H "X-Auth-Token: your-secret-token-123" http://example.com
- 确认返回的是客户端真实 IP。
- 使用
总结
通过 Cloudflare 添加
X-Auth-Token
,在 Traefik 中启用 header 转发并验证 token,后端检查 token 后获取真实 IP,这种方法既安全又高效。相比使用trustedIPs
的传统方式,它避免了 IP 列表维护的麻烦,提供了更高的灵活性和安全性。