生产环境中,OpenClaw Gateway 通常不直接对外—— 而是在前面架一层 Nginx/Caddy 等反向代理, 负责 HTTPS、域名绑定和统一认证。 这篇文章讲清楚怎么正确配置。
为什么需要反向代理?
不用反向代理:
用户 → ws://your-ip:18789(明文传输,没有 HTTPS)
用反向代理:
用户 → https://ai.example.com(HTTPS + 域名)
↓ Nginx/Caddy(认证 + 证书)
↓ ws://127.0.0.1:18789(内网 WebSocket)
OpenClaw Gateway
好处:
- 自动 HTTPS 证书(Let's Encrypt)
- 漂亮的域名,而非 IP:端口
- 统一认证入口(Basic Auth / OAuth / SSO)
- Gateway 只监听 localhost,不暴露到公网
Trusted Proxy 认证模式原理
1. 用户访问 https://ai.example.com
2. Nginx 验证用户身份(Basic Auth / OAuth)
3. Nginx 在请求头中添加 X-Forwarded-User: alice
4. 转发到 Gateway(ws://127.0.0.1:18789)
5. Gateway 信任这个头(trusted-proxy 模式),
认为已经过 Nginx 认证
OpenClaw 配置:
json
{
"gateway": {
"bind": "127.0.0.1",
"port": 18789,
"auth": {
"mode": "trusted-proxy",
"trustedProxyHeader": "X-Forwarded-User"
}
}
}Nginx + Basic Auth 配置
bash
# 创建密码文件
htpasswd -c /etc/nginx/.htpasswd your-usernamenginx
# /etc/nginx/sites-available/openclaw
server {
listen 443 ssl;
server_name ai.example.com;
ssl_certificate /etc/letsencrypt/live/ai.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ai.example.com/privkey.pem;
# 重要:允许下划线请求头(OpenClaw Codex 需要)
underscores_in_headers on;
location / {
auth_basic "OpenClaw";
auth_basic_user_file /etc/nginx/.htpasswd;
# 传递认证用户名给 Gateway
proxy_set_header X-Forwarded-User $remote_user;
# WebSocket 升级
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:18789;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Caddy + 自动 HTTPS 配置
Caddy 自动管理 Let's Encrypt 证书,配置更简洁:
caddy
# Caddyfile
ai.example.com {
basicauth {
your-username JDJhJDE0JHh4eHh4eHh4eHh4eHh4eA==
}
reverse_proxy localhost:18789 {
header_up X-Forwarded-User {http.auth.user.id}
# WebSocket 支持
transport http {
versions h1
}
}
}Caddy 自动申请和续期 HTTPS 证书,无需手动操作。
Cloudflare Access 零信任部署
使用 Cloudflare Access 做访问控制(无需密码,用 Email 一次性链接认证):
1. Cloudflare Dashboard → Access → Applications → Add
2. 域名:ai.example.com
3. Identity Provider:Email(发送一次性访问链接)
4. Policy:允许特定 Email 地址
Cloudflare Tunnel(替代 Nginx):
cloudflared tunnel create openclaw
cloudflared tunnel route dns openclaw ai.example.com
yaml
# config.yml
tunnel: your-tunnel-id
credentials-file: /path/to/credentials.json
ingress:
- hostname: ai.example.com
service: http://localhost:18789
- service: http_status:404OpenClaw 配置:
json
{
"gateway": {
"auth": {
"mode": "trusted-proxy",
"trustedProxyHeader": "Cf-Access-Authenticated-User-Email"
}
}
}常见问题排查
问题1:WebSocket 连接失败(101 升级失败)
症状:WebChat 无法连接,控制台报 WebSocket handshake failed
原因:Nginx 没有配置 WebSocket 升级头
修复:确认 Nginx 配置中有:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
问题2:Codex/Claude Code 长连接断开(sticky session)
症状:Codex CLI 会话频繁中断
原因:没有配置 underscores_in_headers on
修复(Nginx):
在 http {} 块中添加:
underscores_in_headers on;
问题3:401 循环(一直要求认证)
症状:输入密码后仍然返回 401
原因:Basic Auth 密码文件格式错误
修复:重新生成密码
htpasswd -c /etc/nginx/.htpasswd username
# 使用 bcrypt 加密,不要手动编辑密码文件
问题4:Gateway 被外网直接访问
检查 Gateway 绑定地址:
openclaw gateway status
应该显示:bind: 127.0.0.1(仅 localhost)
如果是 0.0.0.0,立即修改配置:
{ "gateway": { "bind": "127.0.0.1" } }
来源:OpenClaw 官方文档 - docs.openclaw.ai/gateway/trusted-proxy-auth