From 6becd11e3915577e5624e8651897a6d7aa821c7f Mon Sep 17 00:00:00 2001 From: Jlypx Date: Mon, 20 Jul 2026 00:10:32 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=20IP=20=E8=BE=B9=E7=BC=98=E5=AE=89=E5=85=A8=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- deploy/EDGE_SECURITY.md | 45 ++++++++++++++++++++++++++++---------- deploy/config.example.yaml | 11 ++++++++++ 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/deploy/EDGE_SECURITY.md b/deploy/EDGE_SECURITY.md index 0c0e78768a..956507c4fb 100644 --- a/deploy/EDGE_SECURITY.md +++ b/deploy/EDGE_SECURITY.md @@ -30,20 +30,41 @@ the application's responsibility. ## Trusted client IPs `security.trust_forwarded_ip_for_api_key_acl` is enabled by default for upgrade -compatibility. On the first upgrade to this mode, a legacy `false` value is -changed to `true` only when `server.trusted_proxies` was not explicitly -configured; explicit proxy policies remain in secure mode. Later administrator -changes are preserved. While enabled, raw `CF-Connecting-IP`, `X-Real-IP`, and -`X-Forwarded-For` values take over client-IP resolution for logs and -security-sensitive paths. Disable the switch to make Gin's -`server.trusted_proxies` chain authoritative. Configure only the exact CIDR/IP -addresses that connect directly to Sub2API; an explicit empty list trusts no -forwarded client IPs while the switch is disabled. +compatibility. While enabled, raw forwarding headers take over client-IP +resolution for logs and security-sensitive paths. Custom headers from +`security.forwarded_client_ip_headers` are checked in configured order before +the built-in `CF-Connecting-IP`, `X-Real-IP`, and `X-Forwarded-For` fallback. +Header names are case-insensitive, normalized when loaded, de-duplicated, and +limited to 16 unique valid HTTP field names. Header values must contain IP +literals; comma-separated values are supported, invalid entries are skipped, +and public addresses are preferred over private fallback addresses. + +The list can be supplied in YAML or with the comma-separated environment +variable `SECURITY_FORWARDED_CLIENT_IP_HEADERS`; an explicitly empty environment +value clears YAML values. It is also editable from the admin security settings +and updates at runtime without a restart. A request snapshots the switch and +header list together, so one request cannot mix old and new settings. Custom +headers are ignored completely when the switch is disabled. In that mode Gin's +`server.trusted_proxies` chain is authoritative: configure only the exact +CIDR/IP addresses that connect directly to Sub2API. An explicit empty list +trusts no forwarded client IPs. + +On the first upgrade to this mode, a legacy `false` value is changed to `true` +only when `server.trusted_proxies` was not explicitly configured; explicit +proxy policies remain in secure mode. New installations persist the configured +custom header list during database initialization. Existing installations +backfill a missing database value from the YAML configuration. A hidden +migration marker prevents later administrator changes from being overwritten. +If settings cannot be read or the persisted custom-header list is malformed, +the process fails closed to trusted-proxy mode with no custom headers. If a +migration write fails, the computed mode remains active for the current process +and startup records a warning. Compatibility takeover accepts forwarded headers without validating the direct -peer. Protect the origin from direct access while it is enabled. A CDN -deployment must firewall the origin so only the CDN or load balancer can reach -it, and the proxy must overwrite forwarded headers. +peer, including any configured custom header. Protect the origin from direct +access while it is enabled. A CDN deployment must firewall the origin so only +the CDN or load balancer can reach it, and that proxy must overwrite every +trusted client-IP header rather than append an untrusted client value. Example for a proxy on the same host: diff --git a/deploy/config.example.yaml b/deploy/config.example.yaml index e84a906d4d..c0fb225ee9 100644 --- a/deploy/config.example.yaml +++ b/deploy/config.example.yaml @@ -106,6 +106,17 @@ security: # 旧版兼容开关。开启时原始转发头会接管 server.trusted_proxies;关闭后严格 # 使用上方配置的可信代理链。示例配置采用高安全模式。 trust_forwarded_ip_for_api_key_acl: false + # Optional client-IP headers for third-party CDNs, checked in list order before + # CF-Connecting-IP, X-Real-IP, and X-Forwarded-For. Valid only while the legacy + # compatibility switch above is true; maximum 16 unique HTTP header names. + # 第三方 CDN 的可选客户端 IP 请求头,按列表顺序优先于内置请求头解析。 + # 仅在上方旧版兼容开关为 true 时生效;最多配置 16 个不重复的合法 HTTP 头名。 + # Environment / 环境变量: SECURITY_FORWARDED_CLIENT_IP_HEADERS=True-Client-IP,X-CDN-Client-IP + forwarded_client_ip_headers: [] + # Example / 示例: + # forwarded_client_ip_headers: + # - "True-Client-IP" + # - "X-CDN-Client-IP" url_allowlist: # Enable URL allowlist validation (disable to skip all URL checks) # 启用 URL 白名单验证(禁用则跳过所有 URL 检查)