可信代理认证

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

何时使用

在以下情况下使用 trusted-proxy 认证模式?

-您在身份感知代理(Pomerium、Caddy + OAuth、nginx + oauth2-proxy、Traefik + forward auth)后运行 OpenClaw

  • 您的代理处理所有认证,并通过 header 传递用户身?
  • 您在 Kubernetes 或容器环境中,代理是进入网关的唯一路径
  • 您遇?WebSocket 1008 未授权 错误,因为浏览器无法?WS 有效载荷中传递令?

何时不使?

  • 如果您的代理不进行用户认证(仅是 TLS 终止或负载均衡器?
  • 如果存在任何绕过代理进入网关的路径(防火墙漏洞、内部网络访问)
  • 您不确定您的代理是否正确剥离/覆盖转发 header
  • 如果您只需要个人单用户访问(考虑使用 Tailscale Serve + loopback 以获得更简单的设置?

工作原理

  1. 您的反向代理认证用户(OAuth、OIDC、SAML 等)
  2. 代理添加带有认证用户身份?header(例?x-forwarded-user: [email protected]?
  3. OpenClaw 检查请求是否来?可信代理 IP*(在 gateway.trustedProxies 中配置)
  4. OpenClaw 从配置的 header 中提取用户身?
  5. 如果一切检查通过,请求被授权

控制 UI 配对行为

?gateway.auth.mode = "trusted-proxy" 处于活动状态且请求通过可信代理检查时,控?UI WebSocket 会话可以无需设备配对身份连接?

影响?

  • 配对不再是此模式下控?UI 访问的主要门槛?
  • 您的反向代理认证策略?allowUsers 成为有效的访问控制?
  • 保持网关入口仅锁定到可信代理 IP(gateway.trustedProxies + 防火墙)?

配置

{
  gateway: {
    // 对于同主机代理设置使?loopback;对于远程代理主机使?lan/custom
    bind: "loopback",

    // 关键:仅在此添加代理?IP
    trustedProxies: ["10.0.0.1", "172.17.0.1"],

    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        // 包含认证用户身份?header(必需?
        userHeader: "x-forwarded-user",

        // 可选:必须存在?header(代理验证)
        requiredHeaders: ["x-forwarded-proto", "x-forwarded-host"],

        // 可选:限制特定用户(空 = 允许所有)
        allowUsers: ["[email protected]", "[email protected]"],
      },
    },
  },
}

如果 gateway.bind ?loopback,则?gateway.trustedProxies127.0.0.1::1 或等?loopback CIDR)中包含 loopback 代理地址?

配置参?

字段必需描述
gateway.trustedProxies?要信任的代理 IP 数组。来自其?IP 的请求被拒绝?
gateway.auth.mode?必须?"trusted-proxy"
gateway.auth.trustedProxy.userHeader?包含认证用户身份?header 名称
gateway.auth.trustedProxy.requiredHeaders?必须存在的附?header 才能信任请求
gateway.auth.trustedProxy.allowUsers?用户身份白名单。空意味着允许所有认证用户?

TLS 终止?HSTS

使用一?TLS 终止点,并在那里应用 HSTS?

推荐模式:代?TLS 终止

当您的反向代理为 https://control.example.com 处理 HTTPS 时,在该域的代理处设?Strict-Transport-Security?

  • 适合面向互联网的部署?
  • 将证?+ HTTP 强化策略保持在一处?
  • OpenClaw 可以在代理后面的 loopback HTTP 上保持运行?

示例 header 值:

Strict-Transport-Security: max-age=31536000; includeSubDomains

网关 TLS 终止

如果 OpenClaw 本身直接提供 HTTPS(无 TLS 终止代理),设置?

{
  gateway: {
    tls: { enabled: true },
    http: {
      securityHeaders: {
        strictTransportSecurity: "max-age=31536000; includeSubDomains",
      },
    },
  },
}

strictTransportSecurity 接受字符?header 值,?false 明确禁用?

推出指南

  • 首先从短 max age 开始(例如 max-age=300),同时验证流量?
  • 仅在高度自信后增加到长期值(例如 max-age=31536000)?
  • 仅在每个子域都支?HTTPS 时添?includeSubDomains?
  • 仅在您故意满足完整域集的预加载要求时使用 preload?
  • Loopback 仅本地开发不能从 HSTS 中受益?

代理设置示例

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: [email protected]
    pass_identity_headers: true

Caddy 配合 OAuth

带有 caddy-security 插件?Caddy 可以认证用户并传递身?header?

{
  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 配合 Forward Auth

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

安全检查清?

在启用可信代理认证之前,验证?

  • 代理是唯一路径:网关端口仅从您的代理防火墙隔离
  • trustedProxies 最小化:仅是您实际的代?IP,而非整个子网
  • 代理剥离 header:您的代理覆盖(而非追加)客户端?x-forwarded-* header
  • TLS 终止:您的代理处?TLS;用户通过 HTTPS 连接
  • **allowUsers 已设?*(推荐):限制到已知用户而非允许任何认证用户

安全审计

openclaw security audit 将以严重级别标记可信代理认证。这是故意的 —?它提醒您将安全委托给代理设置?

审计检查:

  • 缺少 trustedProxies 配置
  • 缺少 userHeader 配置
  • allowUsers 为空(允许任何认证用户)

故障排除

”trusted_proxy_untrusted_source”

请求未来?gateway.trustedProxies 中的 IP。检查:

  • 代理 IP 正确吗?(Docker 容器 IP 可能改变?
  • 代理前面有负载均衡器吗?
  • 使用 docker inspect ?kubectl get pods -o wide 查找实际 IP

”trusted_proxy_user_missing”

用户 header 为空或缺失。检查:

  • 您的代理配置是否传递身?header?
  • header 名称正确吗?(不区分大小写,但拼写重要)
  • 用户在代理处实际认证了吗?

“trustedproxy_missing_header*”

必需?header 不存在。检查:

  • 您代理配置中的特?header
  • 链中是否?header 被剥?

“trusted_proxy_user_not_allowed”

用户已认证但不在 allowUsers 中。要么添加他们,要么移除白名单?

WebSocket 仍然失败

确保您的代理?

  • 支持 WebSocket 升级(Upgrade: websocketConnection: upgrade?
  • ?WebSocket 升级请求上传递身?header(不仅仅?HTTP?
  • WebSocket 连接没有单独的认证路?

从令牌认证迁?

如果您从令牌认证迁移到可信代理:

  1. 配置您的代理认证用户并传?header
  2. 独立测试代理设置(带 header ?curl?
  3. 使用可信代理认证更新 OpenClaw 配置
  4. 重启网关
  5. 从控?UI 测试 WebSocket 连接
  6. 运行 openclaw security audit 并审查结?

相关