設定 OpenClaw Trusted Proxy 驗證:整合反向代理伺服器
你是否曾經為了管理一堆 API token 而感到頭痛?或者在設定 reverse proxy 後,發現 WebSocket 連線一直跳出 1008 錯誤?這些通常是開發者在處理身分驗證時最常遇到的痛點。
如果你已經有了一套成熟的身分驗證基礎設施,那麼將驗證工作交給專業的代理伺服器處理,通常是更聰明且更安全的做法。
Trusted Proxy Auth
Section titled “Trusted Proxy Auth”⚠️ 安全性敏感功能。 此模式會將身分驗證完全委託給你的 reverse proxy。配置錯誤可能會導致你的 Gateway 暴露在未經授權的存取風險中。在啟用前請仔細閱讀本頁面。
在以下情況下,請使用 trusted-proxy 驗證模式:
- 你在 identity-aware proxy(如 Pomerium, Caddy + OAuth, nginx + oauth2-proxy, Traefik + forward auth)後方執行 OpenClaw
- 你的代理伺服器處理所有身分驗證,並透過 header 傳遞使用者身分
- 你處於 Kubernetes 或容器環境中,代理伺服器是通往 Gateway 的唯一路徑
- 因為瀏覽器無法在 WebSocket payload 中傳遞 token,導致你遇到 WebSocket
1008 unauthorized錯誤
何時不該使用
Section titled “何時不該使用”- 如果你的代理伺服器不驗證使用者(僅作為 TLS 終端或負載平衡器)
- 如果有任何路徑可以繞過代理伺服器直接存取 Gateway(例如防火牆漏洞、內部網路存取)
- 如果你不確定代理伺服器是否能正確清除或覆寫轉發的 header
- 如果你只需要個人單一使用者存取(考慮使用 Tailscale Serve + loopback,設定更簡單)
- 你的 reverse proxy 驗證使用者(OAuth, OIDC, SAML 等)
- 代理伺服器加入一個包含已驗證使用者身分的 header(例如
x-forwarded-user: nick@example.com) - OpenClaw 檢查請求是否來自 受信任的代理伺服器 IP(配置於
gateway.trustedProxies) - OpenClaw 從配置的 header 中提取使用者身分
- 如果一切正常,請求即獲得授權
Control UI 配對行為
Section titled “Control UI 配對行為”當 gateway.auth.mode = "trusted-proxy" 啟用且請求通過受信任代理檢查時,Control UI 的 WebSocket 連線不需要裝置配對身分即可連線。
影響如下:
- 在此模式下,配對不再是 Control UI 存取的主要門檻。
- 你的 reverse proxy 驗證策略與
allowUsers將成為實際的存取控制手段。 - 請務必將 Gateway 的入口限制在僅限受信任的代理伺服器 IP(
gateway.trustedProxies+ 防火牆)。
{ gateway: { // Use loopback for same-host proxy setups; use lan/custom for remote proxy hosts bind: "loopback",
// CRITICAL: Only add your proxy's IP(s) here trustedProxies: ["10.0.0.1", "172.17.0.1"],
auth: { mode: "trusted-proxy", trustedProxy: { // Header containing authenticated user identity (required) userHeader: "x-forwarded-user",
// Optional: headers that MUST be present (proxy verification) requiredHeaders: ["x-forwarded-proto", "x-forwarded-host"],
// Optional: restrict to specific users (empty = allow all) allowUsers: ["nick@example.com", "admin@company.org"], }, }, },}如果 gateway.bind 為 loopback,請在 gateway.trustedProxies 中包含 loopback 代理位址(127.0.0.1、::1 或等效的 loopback CIDR)。
| 欄位 | 必填 | 描述 |
|---|---|---|
gateway.trustedProxies | 是 | 要信任的代理伺服器 IP 位址陣列。來自其他 IP 的請求將被拒絕。 |
gateway.auth.mode | 是 | 必須為 "trusted-proxy" |
gateway.auth.trustedProxy.userHeader | 是 | 包含已驗證使用者身分的標頭名稱 |
gateway.auth.trustedProxy.requiredHeaders | 否 | 請求必須包含的其他標頭,才被視為受信任 |
gateway.auth.trustedProxy.allowUsers | 否 | 使用者身分允許清單。留空表示允許所有已驗證的使用者。 |
TLS 終端與 HSTS
Section titled “TLS 終端與 HSTS”請使用單一 TLS 終端點並在該處套用 HSTS。
建議模式:代理伺服器 TLS 終端
Section titled “建議模式:代理伺服器 TLS 終端”當你的 reverse proxy 負責 https://control.example.com 的 HTTPS 時,請在代理伺服器上為該網域設定 Strict-Transport-Security。
- 適合面向網際網路的部署。
- 將憑證與 HTTP 安全強化策略集中管理。
- OpenClaw 可以保持在代理伺服器後方的 loopback HTTP 運作。
Header 範例值:
Strict-Transport-Security: max-age=31536000; includeSubDomainsGateway TLS 終端
Section titled “Gateway TLS 終端”如果 OpenClaw 直接提供 HTTPS 服務(無 TLS 終端代理),請設定:
{ gateway: { tls: { enabled: true }, http: { securityHeaders: { strictTransportSecurity: "max-age=31536000; includeSubDomains", }, }, },}strictTransportSecurity 接受字串標頭值,或設為 false 以明確停用。
- 在驗證流量時,先從較短的 max age 開始(例如
max-age=300)。 - 只有在信心充足後,再增加到長效值(例如
max-age=31536000)。 - 僅在每個子網域都已準備好 HTTPS 時才加入
includeSubDomains。 - 僅在你打算讓整個網域集符合預載要求時才使用 preload。
- 僅限 loopback 的本地開發無法從 HSTS 獲益。
代理設定範例
Section titled “代理設定範例”Pomerium
Section titled “Pomerium”Pomerium 在 x-pomerium-claim-email(或其他 claim header)中傳遞身分,並在 x-pomerium-jwt-assertion 中傳遞 JWT。
{ gateway: { bind: "lan", trustedProxies: ["10.0.0.1"], // Pomerium 的 IP auth: { mode: "trusted-proxy", trustedProxy: { userHeader: "x-pomerium-claim-email", requiredHeaders: ["x-pomerium-jwt-assertion"], }, }, },}Pomerium 配置片段:
routes: - from: https://openclaw.example.com to: http://openclaw-gateway:18789 policy: - allow: or: - email: is: nick@example.com pass_identity_headers: trueCaddy 搭配 OAuth
Section titled “Caddy 搭配 OAuth”帶有 caddy-security 外掛的 Caddy 可以驗證使用者並傳遞身分標頭。
{ gateway: { bind: "lan", trustedProxies: ["127.0.0.1"], // Caddy's IP (if on same host) auth: { mode: "trusted-proxy", trustedProxy: { userHeader: "x-forwarded-user", }, }, },}Caddyfile 片段:
openclaw.example.com { authenticate with oauth2_provider authorize with policy1
reverse_proxy openclaw:18789 { header_up X-Forwarded-User {http.auth.user.email} }}nginx + oauth2-proxy
Section titled “nginx + oauth2-proxy”oauth2-proxy 驗證使用者並在 x-auth-request-email 中傳遞身分。
{ gateway: { bind: "lan", trustedProxies: ["10.0.0.1"], // nginx/oauth2-proxy IP auth: { mode: "trusted-proxy", trustedProxy: { userHeader: "x-auth-request-email", }, }, },}nginx 配置片段:
location / { auth_request /oauth2/auth; auth_request_set $user $upstream_http_x_auth_request_email;
proxy_pass http://openclaw:18789; proxy_set_header X-Auth-Request-Email $user; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";}Traefik 搭配 Forward Auth
Section titled “Traefik 搭配 Forward Auth”{ gateway: { bind: "lan", trustedProxies: ["172.17.0.1"], // Traefik 容器 IP auth: { mode: "trusted-proxy", trustedProxy: { userHeader: "x-forwarded-user", }, }, },}混合 Token 配置
Section titled “混合 Token 配置”OpenClaw 會拒絕模糊的配置,例如同時啟用 gateway.auth.token(或 OPENCLAW_GATEWAY_TOKEN)與 trusted-proxy 模式。混合 Token 配置可能會導致 loopback 請求在錯誤的驗證路徑上靜默通過驗證。
如果你在啟動時看到 mixed_trusted_proxy_token 錯誤:
- 使用 trusted-proxy 模式時請移除共享 token,或者
- 如果你打算使用基於 token 的驗證,請將
gateway.auth.mode切換為"token"。
Loopback 的受信任代理驗證也遵循「預設關閉」原則:同主機的呼叫者必須透過受信任代理提供配置的身分標頭,而不是被靜默驗證。
安全性檢查清單
Section titled “安全性檢查清單”在啟用 trusted-proxy 驗證前,請確認:
- 代理伺服器是唯一路徑:Gateway 連接埠已設定防火牆,僅允許來自代理伺服器的存取
- trustedProxies 已最小化:僅包含實際的代理伺服器 IP,而非整個子網域
- 代理伺服器會清除標頭:你的代理伺服器會覆寫(而非附加)來自用戶端的
x-forwarded-*標頭 - TLS 終端:你的代理伺服器處理 TLS;使用者透過 HTTPS 連線
- 已設定 allowUsers(建議):限制已知使用者,而非允許任何通過驗證的人
- 無混合 token 配置:不要同時設定
gateway.auth.token與gateway.auth.mode: "trusted-proxy"
openclaw security audit 會將 trusted-proxy 驗證標記為 critical(嚴重)等級的發現。這是故意的——為了提醒你正將安全性委託給代理伺服器設定。
稽核會檢查:
- 遺失
trustedProxies配置 - 遺失
userHeader配置 allowUsers為空(允許任何已驗證使用者)
”trusted_proxy_untrusted_source”
Section titled “”trusted_proxy_untrusted_source””請求並非來自 gateway.trustedProxies 中的 IP。請檢查:
- 代理伺服器 IP 是否正確?(Docker 容器 IP 可能會變動)
- 代理伺服器前方是否有負載平衡器?
- 使用
docker inspect或kubectl get pods -o wide來尋找實際 IP
”trusted_proxy_user_missing”
Section titled “”trusted_proxy_user_missing””使用者標頭為空或遺失。請檢查:
- 你的代理伺服器是否配置為傳遞身分標頭?
- 標頭名稱是否正確?(不區分大小寫,但拼字必須正確)
- 使用者是否確實在代理伺服器端通過驗證?
“trusted_proxy_missing_header_*”
Section titled ““trusted_proxy_missing_header_*””必要的標頭不存在。請檢查:
- 你的代理伺服器配置中是否包含這些特定標頭
- 標頭是否在傳遞鏈中的某處被清除
”trusted_proxy_user_not_allowed”
Section titled “”trusted_proxy_user_not_allowed””使用者已通過驗證,但不在 allowUsers 中。請將其加入或移除允許清單。
WebSocket 仍然失敗
Section titled “WebSocket 仍然失敗”請確保你的代理伺服器:
- 支援 WebSocket 升級(
Upgrade: websocket,Connection: upgrade) - 在 WebSocket 升級請求中傳遞身分標頭(而不僅僅是 HTTP)
- 沒有為 WebSocket 連線設定獨立的驗證路徑
從 Token 認證遷移
Section titled “從 Token 認證遷移”如果你正從 token 認證遷移到 trusted-proxy:
- 配置你的代理伺服器以驗證使用者並傳遞標頭
- 獨立測試代理伺服器設定(使用帶有標頭的 curl)
- 使用 trusted-proxy 驗證更新 OpenClaw 配置
- 重啟 Gateway
- 從 Control UI 測試 WebSocket 連線
- 執行
openclaw security audit並檢視結果
- Security — 完整安全性指南
- Configuration — 配置參考
- Remote Access — 其他遠端存取模式
- Tailscale — 僅限 tailnet 存取的簡單替代方案
下一步:
- 想要更快速的設定?試試 AI Setup Assistant
- 深入了解 Gateway 安全性配置
- 探索 Remote Access 最佳實踐
OpenClaw Expert
還是卡住了?
如果這篇文件沒有解決你的情境,直接問 OpenClaw Expert,拿到可執行步驟。