背景

在一次 OpenClaw 日常检查中,执行了如下命令:

openclaw doctor --non-interactive

检查结果显示 OpenClaw 本体运行正常,Skills 与 Plugins 均无明显异常:

Skills status:
  Eligible: 19
  Missing requirements: 0
  Blocked by allowlist: 0

Plugins:
  Loaded: 69
  Errors: 0

Memory search 处于明确关闭状态:

Memory search is explicitly disabled (enabled: false).

这不是故障,而是配置选择。

真正需要关注的是 Security 部分的两个提醒:

WARNING: openclaw.json contains plaintext secret-bearing config fields.
Paths: gateway.auth.password

WARNING: Gateway bound to "lan" (0.0.0.0) (network-accessible).

其中第二项表示 Gateway 监听 0.0.0.0,允许局域网访问。对于需要从局域网其他设备访问 OpenClaw 的场景,这属于有意配置,不是错误。

第一项则更值得处理:gateway.auth.password 以明文形式保存在 openclaw.json 中。虽然这不代表密码已经泄露,但如果本地 agent、插件或 workspace 工具可以读取配置文件,就有机会看到该明文密码。因此,本次处理重点是将该字段迁移到 SecretRef,也就是改为从环境变量读取。

当前状态判断

初始检查结果说明:

  • OpenClaw Gateway 可以正常运行;
  • Skills 依赖完整;
  • Plugins 加载正常;
  • Memory search 按配置关闭;
  • 主要问题是配置文件里存在明文密码;
  • 局域网监听提醒属于安全提示,不是运行故障。

因此,本次处理目标不是“修复坏掉的服务”,而是“收紧安全配置”。

修改前备份配置文件

在修改配置文件前,应先备份当前配置:

cp -av ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.$(date +%Y%m%d-%H%M%S)

备份完成后,再进行 SecretRef 迁移操作。

配置 Secret Provider

执行:

openclaw secrets configure

进入交互式配置后,首先添加 Secret Provider。

界面提示:

Configure secret providers
  Add provider
  Continue

选择:

Add provider

Provider source 选择:

env

Provider alias 保持默认:

default

Env allowlist 建议不要留空,而是只允许指定的环境变量,例如:

OPENCLAW_GATEWAY_PASSWORD

这样可以避免 env provider 读取过多不必要的环境变量。

选择要迁移的字段

随后进入 credential field 选择界面。可能会看到多个敏感字段,例如:

profiles.openai:xxxxx.key
profiles.openai:xxxxx.token
gateway.auth.password

本次只处理 doctor 明确提示的字段:

gateway.auth.password

不要顺手迁移其他 key 或 token。安全配置修改应尽量保持最小变更,避免影响 agent 的认证状态。

Secret source 选择:

env

Provider alias 选择:

default

Secret id 填写:

OPENCLAW_GATEWAY_PASSWORD

处理环境变量缺失问题

第一次配置时可能出现如下错误:

Secrets configure failed: Environment variable "OPENCLAW_GATEWAY_PASSWORD" is missing or empty.

这说明 OpenClaw 在迁移前会检查指定环境变量是否存在。如果环境变量不存在,它会拒绝继续迁移。这是合理的安全校验。

可以先从当前配置文件中读取原来的 Gateway 密码,并写入当前 shell 的环境变量:

export OPENCLAW_GATEWAY_PASSWORD="$(python - <<'PY'
import json
from pathlib import Path

p = Path.home() / ".openclaw" / "openclaw.json"
data = json.loads(p.read_text())
print(data["gateway"]["auth"]["password"])
PY
)"

test -n "$OPENCLAW_GATEWAY_PASSWORD" && echo "OPENCLAW_GATEWAY_PASSWORD is set"

这段命令不会把密码打印出来,只会确认环境变量已经设置。

然后重新执行:

openclaw secrets configure

再次选择:

gateway.auth.password
Secret source: env
Provider alias: default
Secret id: OPENCLAW_GATEWAY_PASSWORD

当出现:

Configure another credential?

选择:

No

接着出现迁移计划:

Preflight: changed=true, files=1, warnings=0.
Plan: targets=1, providerUpserts=0, providerDeletes=0.

这表示:

  • 会修改配置;
  • 只修改一个文件;
  • 预检查没有警告;
  • 只迁移一个目标字段;
  • 不会新增或删除 provider。

因此可以继续选择:

Apply this plan now? Yes

随后会提示:

This migration is one-way for migrated plaintext values.

这表示迁移后,配置文件中的明文值会被替换为 SecretRef。对于本次目标来说,这正是期望结果。确认后完成迁移。

成功时会看到类似输出:

Secrets applied. Updated 1 file(s).

验证明文密码警告是否消失

迁移完成后,再次执行:

openclaw doctor --non-interactive

如果原来的警告已经消失:

openclaw.json contains plaintext secret-bearing config fields
Paths: gateway.auth.password

说明 gateway.auth.password 已经不再以明文形式保存在 openclaw.json 中。

此时 doctor 中可能仍然保留:

WARNING: Gateway bound to "lan" (0.0.0.0) (network-accessible).

这表示 Gateway 仍然监听局域网地址。如果这是有意设置,用于局域网设备访问,则可以接受。需要注意的是,应确保:

  • Gateway 登录密码足够强;
  • 没有无认证访问;
  • 路由器没有把端口直接暴露到公网;
  • 反向代理没有绕过认证;
  • 公网访问应优先通过 SSH tunnel、Tailscale 等更可控的方式实现。

让 systemd 用户服务读取环境变量

因为 OpenClaw Gateway 是由 systemd --user 管理的,仅在当前终端中 export 环境变量还不够。需要把变量导入 user systemd 会话:

systemctl --user import-environment OPENCLAW_GATEWAY_PASSWORD

然后重启 Gateway 服务:

systemctl --user restart openclaw-gateway.service

检查服务状态:

systemctl --user status openclaw-gateway.service --no-pager

如果看到:

Active: active (running)

说明服务重启成功,Gateway 能够读取迁移后的 SecretRef。

最后再次执行:

openclaw doctor --non-interactive

如果 doctor 中只剩下局域网监听提醒,说明本次明文密码迁移已经完成。

最终状态

本次处理完成后,OpenClaw 状态如下:

OpenClaw Gateway 正常运行
明文 gateway.auth.password 已迁移为 SecretRef
openclaw.json 不再直接保存 Gateway 明文密码
Skills 依赖完整
Plugins 无错误
Memory search 按配置关闭
仅保留局域网监听安全提醒

其中 0.0.0.0 监听提醒需要根据实际使用场景判断。如果确实需要局域网访问,可以保留;如果只在本机使用,则改回 127.0.0.1 更安全。

后续注意点

本次通过:

systemctl --user import-environment OPENCLAW_GATEWAY_PASSWORD

把环境变量导入到了当前 user systemd 会话。该方式对当前登录会话有效,但重启电脑后是否仍然自动生效,需要另行验证。

重启电脑后建议检查:

systemctl --user status openclaw-gateway.service --no-pager
openclaw doctor --non-interactive

如果服务仍然是:

active (running)

且 doctor 不再提示明文密码,则说明配置稳定。

如果重启后 Gateway 无法启动,原因大概率是 OPENCLAW_GATEWAY_PASSWORD 没有持久注入到 systemd 用户环境中。届时需要为该环境变量配置持久化注入方式。

小结

这次处理的核心不是排障,而是配置安全收敛:

  1. 通过 openclaw doctor 发现明文密码警告;
  2. 使用 openclaw secrets configure 配置 env SecretRef;
  3. gateway.auth.password 迁移到 OPENCLAW_GATEWAY_PASSWORD
  4. 导入环境变量到 systemd user 会话;
  5. 重启 Gateway 并验证服务正常。

处理完成后,OpenClaw 的功能状态保持正常,同时减少了配置文件中明文敏感信息暴露的风险。

Leave a Reply

Your email address will not be published. Required fields are marked *