codecamp

OpenClaw 可信代理认证指南

⚠️ 安全敏感功能。此模式会将认证完全委托给你的反向代理。错误配置可能会导致你的网关暴露在未授权访问之下。在启用前,请仔细阅读本页面。

适用场景

当你符合以下情况时,可使用可信代理认证模式:

  • 你在身份感知代理(Pomerium、Caddy + OAuth、nginx + oauth2-proxy、Traefik + forward auth)之后运行 OpenClaw
  • 你的代理处理所有认证,并通过请求头传递用户身份
  • 你处于 Kubernetes 或容器环境中,代理是访问网关的唯一路径
  • 你遇到了 WebSocket 1008 未授权错误,因为浏览器无法在 WS 负载中传递令牌

不适用场景

如果出现以下情况,请勿使用:

  • 如果你的代理不对用户进行认证(仅作为 TLS 终结器或负载均衡器)
  • 如果存在任何绕过代理访问网关的路径(防火墙漏洞、内部网络访问)
  • 如果你不确定你的代理是否正确清理 / 覆盖转发请求头
  • 如果你只需要个人单用户访问(可考虑使用 Tailscale Serve + 环回,配置更简单)

工作原理

  1. 你的反向代理对用户进行认证(OAuth、OIDC、SAML 等)
  2. 代理添加一个包含已认证用户身份的请求头(例如 x-forwarded-user: [email protected]
  3. OpenClaw 检查请求是否来自可信代理 IP(在 gateway.trustedProxies 中配置)
  4. OpenClaw 从配置的请求头中提取用户身份
  5. 所有校验通过后,请求将被授权

配置

{
  gateway: {
    // 必须绑定到网络接口(而非环回地址)
    bind: "lan",
    // 关键:仅在此处添加你的代理 IP
    trustedProxies: ["10.0.0.1", "172.17.0.1"],
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        // 包含已认证用户身份的请求头(必填)
        userHeader: "x-forwarded-user",
        // 可选:必须存在的请求头(代理校验)
        requiredHeaders: ["x-forwarded-proto", "x-forwarded-host"],
        // 可选:限制为特定用户(空 = 允许所有)
        allowUsers: ["[email protected]", "[email protected]"],
      },
    },
  },
}

配置参考

字段 是否必填 说明
gateway.trustedProxies 要信任的代理 IP 地址数组。来自其他 IP 的请求会被拒绝。
gateway.auth.mode 必须设置为 "trusted-proxy"
gateway.auth.trustedProxy.userHeader 包含已认证用户身份的请求头名称
gateway.auth.trustedProxy.requiredHeaders 请求被信任时必须存在的额外请求头
gateway.auth.trustedProxy.allowUsers 用户身份白名单。为空则表示允许所有已认证用户。

代理配置示例

Pomerium

Pomerium 会在 x-pomerium-claim-email(或其他声明请求头)中传递身份,同时在 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: [email protected]
  pass_identity_headers: true

Caddy with OAuth

搭配 caddy-security 插件的 Caddy 可以对用户进行认证,并传递身份请求头。

{
  gateway: {
    bind: "lan",
    trustedProxies: ["127.0.0.1"], // Caddy 的 IP(如果与网关同主机)
    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

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 with Forward Auth

{
  gateway: {
    bind: "lan",
    trustedProxies: ["172.17.0.1"], // Traefik 容器的 IP
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        userHeader: "x-forwarded-user",
      },
    },
  },
}

安全检查清单

在启用可信代理认证前,请确认:

  • 代理是唯一访问路径:网关端口已配置防火墙,仅允许你的代理访问,拒绝其他所有来源
  • trustedProxies 配置最小化:仅添加你实际的代理 IP,而非整个子网
  • 代理清理请求头:你的代理会覆盖(而非追加)来自客户端的 x-forwarded-* 请求头
  • TLS 终结:你的代理处理 TLS;用户通过 HTTPS 连接
  • 已设置 allowUsers(推荐):限制为已知用户,而非允许所有已认证用户

安全审计

openclaw security audit 会将可信代理认证标记为严重级别的审计发现。这是有意为之 —— 它是在提醒你,你正在将安全委托给你的代理配置。

审计会检查以下内容:

  • 缺失 trustedProxies 配置
  • 缺失 userHeader 配置
  • 空的 allowUsers(允许任意已认证用户)

故障排查

trusted_proxy_untrusted_source

请求并非来自 gateway.trustedProxies 中的 IP。请检查:

  • 代理 IP 是否正确?(Docker 容器 IP 可能会变化)
  • 你的代理前是否存在负载均衡器?
  • 使用 docker inspectkubectl get pods -o wide 来查找实际 IP

trusted_proxy_user_missing

用户请求头为空或缺失。请检查:

  • 你的代理是否配置为传递身份请求头?
  • 请求头名称是否正确?(不区分大小写,但拼写必须正确)
  • 用户是否已在代理处完成认证?

trusted_proxy_missing_header *

某个必填请求头不存在。请检查:

  • 你的代理针对这些特定请求头的配置
  • 这些请求头是否在链路中的某个位置被清理

trusted_proxy_user_not_allowed

用户已完成认证,但不在 allowUsers 列表中。你可以将该用户添加到列表,或移除白名单。

WebSocket 仍然失败

请确保你的代理:

  • 支持 WebSocket 升级(Upgrade: websocketConnection: upgrade
  • 在 WebSocket 升级请求中传递身份请求头(而非仅在 HTTP 请求中)
  • 没有为 WebSocket 连接设置单独的认证路径

从令牌认证迁移

如果你正在从令牌认证迁移到可信代理:

  1. 配置你的代理以对用户进行认证并传递请求头
  2. 独立测试代理配置(使用带请求头的 curl 命令)
  3. 更新 OpenClaw 配置为可信代理认证
  4. 重启网关
  5. 从控制 UI 测试 WebSocket 连接
  6. 运行 openclaw security audit 并检查审计结果
OpenClaw 密钥应用计划契约指南
OpenClaw 渠道连接的健康检查步骤
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

OpenClaw 消息渠道

OpenClaw 工具

OpenClaw 模型

OpenClaw 平台

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }