阅读前记得关注+星标,及时获取更新推送
OpenClaw 安全加固系列 第6篇 前五篇我们把网络层封死了:端口改了、SSH 锁了、Gateway 绑到 loopback 或 tailnet。

但还有一个问题:如果有人通过合法渠道(SSH Tunnel、Tailnet)访问到了 Gateway,Token 是最后一道门。这道门够不够结实?
默认 Token 的三个问题,以及怎么解
OpenClaw 默认的 Token 配置非常简单,只做了最基础的"有没有 Token"校验,存在三个明显缺陷:
问题 1:无过期时间
Token 一旦生成,永久有效。如果 Token 泄露(被 prompt injection 读走、出现在日志里、被截包),攻击者可以永远使用它。
解法:OpenClaw 源码目前没有内置 TTL 机制。用 cron job 定期轮换来替代——每天自动生成新 Token 并重启 Gateway,泄露的 Token 最多用一天。后面有完整脚本。
问题 2:无 IP 绑定
同一个 Token 可以从任何 IP 使用。攻击者拿到 Token 后,理论上可以从世界任何地方访问你的 Gateway。
解法:这个问题不靠 Token 解决,靠网络层解决。前几篇配置的 loopback / tailnet 模式,Gateway 本身就不对公网暴露,外部根本连不进来。Token 只是最后一道门,门前的路已经封死了。如果你已经做了第三篇或第四篇的配置,这个问题已经解决了。
问题 3:无设备指纹校验
无法区分是你的设备在用,还是别人拿着你的 Token 在用。
解法:OpenClaw 没有内置设备指纹支持。实际防御靠两件事的组合:Token 强度(32 字节随机,暴力破解不现实)+ 网络隔离(只有 Tailnet 内的设备能访问)。两者结合后,设备指纹校验的必要性大幅降低——攻击者既拿不到 Token,也进不了网络。
源码里的 Token 验证逻辑
OpenClaw Gateway 的 Token 验证在 src/gateway/middleware/auth.ts 里:
export function authMiddleware(config: GatewayConfig) { return (req: Request, res: Response, next: NextFunction) => { const token = req.headers['authorization']?.replace('Bearer ', '') || req.query.token as string; // 默认配置:只检查 token 是否匹配,没有过期、没有 IP 校验 if (config.auth?.mode === 'token') { if (token !== config.auth.token) { return res.status(401).json({ error: 'Unauthorized' }); } } next(); };}就这么简单。字符串比对,匹配就放行,不匹配就 401。没有过期时间,没有 IP 检查,没有任何额外校验。
生成一个强 Token
先把默认的弱 Token 换掉。
# 生成 32 字节的强随机 Tokenopenssl rand -hex 32# 输出示例:a3f8c2e1d4b7a9f0e2c5d8b1a4f7c0e3d6b9a2f5c8e1d4b7a0f3c6e9d2b5a8f1# 或者用 Pythonpython3 -c "import secrets; print(secrets.token_hex(32))"写入配置文件:
{ "gateway": { "auth": { "mode": "token", "token": "a3f8c2e1d4b7a9f0e2c5d8b1a4f7c0e3d6b9a2f5c8e1d4b7a0f3c6e9d2b5a8f1" } }}不要用这个示例 Token,自己生成一个。
加固配置
OpenClaw 目前支持的 Token 配置比较简单,核心就是设置一个强随机 Token:
{ "gateway": { "auth": { "mode": "token", "token": "你生成的强随机Token" } }}token_ttl、require_device_fingerprint 等高级字段在当前版本源码中未经证实支持,不建议写进配置文件,避免被忽略或产生意外行为。
Token 定期轮换用 cron job 实现:
# 写一个轮换脚本 /usr/local/bin/rotate-openclaw-token.sh#!/bin/bashNEW_TOKEN=$(openssl rand -hex 32)jq --arg t "$NEW_TOKEN" '.gateway.auth.token = $t' \ ~/.openclaw/openclaw.json > /tmp/oc.tmp \ && mv /tmp/oc.tmp ~/.openclaw/openclaw.jsondocker restart openclawecho "[$(date)] Token rotated" >> /var/log/openclaw-token.log# 加执行权限chmod +x /usr/local/bin/rotate-openclaw-token.sh# 每天凌晨 3 点自动轮换echo "0 3 * * * /usr/local/bin/rotate-openclaw-token.sh" | crontab -Token 泄露了怎么办
立即吊销,重新生成:
# 生成新 TokenNEW_TOKEN=$(openssl rand -hex 32)# 更新配置文件# 用 jq 修改(如果安装了 jq)jq --arg t "$NEW_TOKEN" '.gateway.auth.token = $t' \ ~/.openclaw/openclaw.json > /tmp/openclaw.json.tmp \ && mv /tmp/openclaw.json.tmp ~/.openclaw/openclaw.json# 重启 Gateway 使新 Token 生效docker restart openclawecho "新 Token: $NEW_TOKEN"重启后旧 Token 立即失效。
Token 不要放在配置文件里
配置文件可能被 prompt injection 读走(第五篇讲过)。更安全的做法是用环境变量:
docker run -d \ --name openclaw \ -e OPENCLAW_GATEWAY_TOKEN="$(openssl rand -hex 32)" \ openclaw/openclawOpenClaw 会优先读取环境变量 OPENCLAW_GATEWAY_TOKEN,配置文件里的 token 字段留空或删掉。
这样即使攻击者读到了配置文件,也拿不到 Token。
检查 Token 是否在日志里泄露
Token 有时候会意外出现在日志里(比如作为 URL 参数传递):
# 检查 OpenClaw 日志里有没有 Tokendocker logs openclaw 2>&1 | grep -i "token\|authorization\|bearer"# 检查系统日志sudo grep -r "18789" /var/log/ | grep -i "token"如果发现 Token 出现在日志里,立即轮换。
防护效果
下一篇
Token 保护了 Gateway 的访问入口。但如果攻击者通过 Skill 植入恶意代码,Token 也帮不了你。
下一篇:《OpenClaw 安全第七课:Skill 白名单 - 第三方代码的沙箱》
夜雨聆风