Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • OpenClaw

    • OpenClaw 实战 01|总览:一个 config 驱动、会自己做梦的 Agent 工作区
    • OpenClaw 实战 02|定时任务:Heartbeat vs Cron,与那个 approve 救不了的死循环
    • OpenClaw 实战 03|架构:3 种部署形态 + Gateway 双 Token + 5 类对接链路
    • OpenClaw 实战 04|配置管理:双层模型注册 + Token 双源 + 4 处真实陷阱
    • OpenClaw 实战 05|安全边界:SSRF 策略、设备 scope、与会脑补截图的模型
      • §1 那个编造了订阅频道的 Agent
      • §2 边界一:browser SSRF 策略
      • §3 边界二:设备 scope(最小权限)
      • §4 边界三:凭证存哪、不存哪
      • §5 边界四:模型能力边界(回到脑补截图)
      • §6 边界五:破坏性操作要带外审批
      • §7 顺带澄清两个"看着像安全问题"的非安全项
      • §8 复用规则(一句话带走)
      • §9 下一篇
      • §10 Agent 可直接解析的元数据块
    • OpenClaw 实战 06|性能优化:上下文压缩、内存压力、冷启动的先 profile 原则
    • OpenClaw 实战 07|部署指南:3 形态决策树 + OpenWebUI 接入 + FreshRSS 跨实例
    • OpenClaw 实战 08|故障排除:Token Mismatch + SSRF 死循环 + "部分存活"假象
    • OpenClaw 实战 09|监控告警:7 个真正有用的信号与告警噪声治理
    • OpenClaw 实战 10|扩展开发:Skill / Tool / Plugin 区分 + 完整安装流程 + 链路证伪调优
    • OpenClaw 实战 11|最佳实践:10 条从真实翻车提炼的 SOP + 推送二次确认硬规则
  • Hermes-Agent

  • Claude-Code

  • AI-Agent
  • OpenClaw
Carry の Blog
2026-06-27
目录

OpenClaw 实战 05|安全边界:SSRF 策略、设备 scope、与会脑补截图的模型原创

# 安全边界:SSRF 策略、设备 scope、与会脑补截图的模型

这一篇讲 OpenClaw 真实存在的几道安全边界——不是"零信任架构"那套抽象话,而是 SSRF 策略、设备 scope、凭证存储、模型能力边界、破坏性操作审批这几个你装一台 OpenClaw 就会撞到的东西。

素材来自两套真实部署(海外容器 + 家用 NAS)的实际操作。先说清楚:OpenClaw 不靠一份"人格文件"保安全,它靠的是 gateway 的 scope/token 机制 + 几个内置 policy + 你自己的凭证卫生。


# §1 那个编造了订阅频道的 Agent

我让 OpenClaw 看一眼某个 YouTube 频道的订阅页。它截了图、说"看到了",然后报给我 6 个页面上根本不存在的频道。

复盘日志,链路是这样的:

  1. Agent 调 browser 截图,存到 ~/.openclaw/media/browser/<uuid>.png;
  2. 想把截图喂给模型——工具返回 model does not support images;
  3. 当时的主对话模型是 qwen3-coder,纯文本/代码模型,不吃图片;
  4. 它没说"我看不到",而是基于上下文脑补了一份订阅列表。

这件事暴露的不是"OpenClaw 不安全",而是两类边界你必须自己设:① 模型能力边界(谁能读图);② Agent 诚实边界(读不到时承认,而不是装懂)。下面把 OpenClaw 真正的几道边界逐个讲清。


# §2 边界一:browser SSRF 策略

OpenClaw 的 browser 工具自带 SSRF 策略(browser.ssrfPolicy),默认拦截访问内网/元数据地址的请求(localhost、私有 IP、metadata.google.internal 等)——防的是"Agent 被诱导去打内网"。

它真实的样子是:Agent 试图 open 一个被策略拦的 URL 时,工具返回:

browser endpoint blocked by policy
  raw_params={"action":"open","url":"https://example.com"}
1
2

这道边界的价值和代价:

  • 价值:默认安全——Agent 不会因为一句话就去探你的内网。
  • 代价:你真要它访问某个内网服务时,得显式把域名/网段加进白名单。改 browser.ssrfPolicy 属于 gateway 配置,改完要重启(不是热重载)。

⚠️ 别为了图省事把白名单开得太宽。SSRF 策略是少数几个"默认就帮你挡住一类攻击面"的地方,开宽了等于自己拆护栏。


# §3 边界二:设备 scope(最小权限)

OpenClaw 的 gateway 给每台连接的设备发 token,token 带 scope。这是它最核心的权限模型,5 个 scope:

scope 能干什么
operator.read 只读
operator.write 读 + 改配置/发消息
operator.admin 管理类操作(如 cron add、设备管理)
operator.approvals 批准别的设备的提权请求
operator.pairing 配对新设备

为什么这是安全特性而不是麻烦:一台只配了 operator.read/write 的 CLI 没法自己给自己升 admin——升级请求要由一台已有 operator.approvals 的设备(你的 Telegram / Control UI)批准。这正是"最小权限 + 带外审批"。

它的代价上一篇(02 定时任务 §4)已经踩过:cron add 需要 admin,普通设备会卡在 scope upgrade pending,而且 approve 因为 requestId 每次连接 churn 而救不了。解法是去 Telegram/Control UI 人工批,或改 ~/.openclaw/devices/paired.json 后重启 gateway。

复用规则:给设备配 scope 按"够用就行"——重操作(browser/admin)不要默认开给每台 CLI,需要时显式提权。


# §4 边界三:凭证存哪、不存哪

这是最容易自己捅娄子的一道。OpenClaw 的凭证有两个正确的家,和一个绝对错误的家:

  • ✅ API key / provider 密钥 → agent 的 sqlite(agents/main/agent/openclaw-agent.sqlite,按 provider 名索引)。openclaw.json 里通常只是占位串。
  • ✅ gateway token / 第三方服务密码 → 环境变量 / ~/.openclaw/secrets/ 下的 600 文件,openclaw.json 用 ${VAR} 引用。
  • ❌ 明文写进 markdown / SKILL.md / 对话历史 / git 仓库 —— 这是泄露的头号来源。

真实翻车:装 freshrss-reader skill 时需要 FreshRSS 的 API 密码。如果顺手写进 skill 目录的某个文件再 git push,它就进了 git 历史——删文件都救不回来,只能 rotate。

正确做法:

mkdir -p ~/.openclaw/secrets && chmod 700 ~/.openclaw/secrets
printf '%s' '<api-password>' > ~/.openclaw/secrets/freshrss.pwd
chmod 600 ~/.openclaw/secrets/freshrss.pwd
# skill 配置里只引用环境变量,不写明文:
export FRESHRSS_API_PASSWORD=$(cat ~/.openclaw/secrets/freshrss.pwd)
1
2
3
4
5

发布前自检(也是本博客 redact 流程的一部分):

grep -rnE '(api[_-]?password|secret|token)\s*[:=]\s*["'\'']?[A-Za-z0-9]{8,}' \
  ~/.openclaw/workspace/skills/ 2>/dev/null   # 期望:无输出
1
2

复用规则:密钥只进 sqlite / env / 600 文件,openclaw.json 用 ${VAR} 引用;任何东西 push 前先扫明文凭证。


# §5 边界四:模型能力边界(回到脑补截图)

§1 的幻觉,根因和修法都比"换个模型"更细。OpenClaw 支持模型角色——同一个 Agent 可以给不同能力挂不同模型:

角色 配置键 干什么
主对话 agents.defaults.model.primary 编排、对话
识图 agents.defaults.imageModel.primary image 工具的后端
语音转写 streaming.providers.<p>.model STT(独立 /v1/audio/transcriptions 端点)
推理 / 嵌入 reasoningModel / embeddingModel 各自子调用

关键认知(很多人搞反):主对话模型不会因为有图片就自动切成 imageModel。imageModel 只是 image 工具的后端子调用——也就是说,主模型即便是非视觉的 qwen3-coder,只要配好了 imageModel(如 qwen3-vl-235b),它就能通过 image 工具"看图"。§1 的幻觉,是因为那条链路没走到一个真正能读图的 imageModel,截图被直接塞给了主模型。

所以修法不是"把整个任务路由到视觉模型",而是:

{ "agents": { "defaults": { "imageModel": { "primary": "qwen3-vl-235b" } } } }
1

⚠️ STT 是另一回事:sttModel 已迁到 streaming.providers.<p>.model,且要专门的 whisper/ASR 端点(/v1/audio/transcriptions),不复用 /chat/completions。别把识图的写法套到音频上。

Agent 诚实边界:能力配好之前,宁可让它说"我读不到这张图"也别让它装懂。这条只能写进 AGENTS.md 的行为约束里——它是 OpenClaw 真实存在的指令文件(不是某些文章里那套"人格五件套")。


# §6 边界五:破坏性操作要带外审批

OpenClaw 在 Telegram/CLI 里执行终端命令时,对敏感操作有原生审批(native approval)机制——危险动作会弹出确认,由 owner 在带外通道点头。这和设备 scope 是配套的:能力授权(scope)+ 逐次确认(approval)。

但要注意一个真实的诊断陷阱(详见 08 故障排除):当 cron 走 gateway 而审批界面弹不出来时,命令会卡住。这不是"不安全",是审批通道没接通——属于配置问题。

对你自己的硬规则:push / rm -rf / 重启生产 / rotate 密钥这类不可逆操作,默认不让 Agent 自动执行,写进 AGENTS.md 要求逐次确认。这一条在 11 最佳实践 会展开成可落地的 SOP。


# §7 顺带澄清两个"看着像安全问题"的非安全项

这两件事常被当成安全故障,其实不是,放这里一并说清:

  • memory-wiki 的 9 个空报告:openclaw wiki init 后 wiki status 显示 9 个 reports 却是空的——那是知识库引擎的监控仪表盘(contradictions/lint/low-confidence…),ingest 内容前本就是空模板,不是泄露也不是故障。
  • Cloudflare Tunnel connection refused:多网卡 + OVS 桥接环境下 Tunnel 目标 IP 不可达,是网络可达性问题(详见 07 部署),不是 OpenClaw 的安全机制在拦你。

# §8 复用规则(一句话带走)

OpenClaw 的安全 = gateway 的 scope/token + 几个内置 policy(SSRF/审批)+ 你的凭证卫生 + 模型角色配对。 没有一份"宪法文件"能替代这些。

展开 4 条:

  1. 最小权限:设备 scope 够用就行,重操作显式提权;SSRF 白名单别开宽。
  2. 凭证只进 sqlite/env/600 文件,openclaw.json 用 ${VAR} 引用,push 前扫明文。
  3. 多模态靠配 imageModel,不是换主模型;读不到就承认,别装懂。
  4. 不可逆操作默认要确认,靠 scope + 原生审批两层兜底。

# §9 下一篇

下一篇:06|性能优化——OpenClaw 特有的三类慢(冷启动、上下文压缩、内存压力)怎么定位。


# §10 Agent 可直接解析的元数据块

{
  "_meta": {
    "doc_version": "2026-06-27",
    "article_id": "openclaw-05-security",
    "profile_context": "any",
    "estimated_read_time": "11min"
  },
  "security_boundaries": {
    "ssrf_policy": {
      "config": "browser.ssrfPolicy",
      "default": "拦截内网/元数据地址",
      "change_needs_restart": true,
      "note": "白名单别开宽"
    },
    "device_scopes": ["operator.read", "operator.write", "operator.admin", "operator.approvals", "operator.pairing"],
    "credential_storage": {
      "ok": ["agent sqlite (provider keys)", "env / ~/.openclaw/secrets 600 文件 + ${VAR} 引用"],
      "never": "明文进 markdown / SKILL.md / 对话历史 / git"
    },
    "model_roles": {
      "primary": "agents.defaults.model.primary",
      "image": "agents.defaults.imageModel.primary (image 工具后端;主模型非视觉也能借它读图)",
      "stt": "streaming.providers.<p>.model (独立 /v1/audio/transcriptions)",
      "key_fact": "主对话模型不会因图片自动切 imageModel"
    },
    "destructive_ops": "scope 授权 + 原生审批逐次确认;push/rm/restart/rotate 默认不自动执行"
  },
  "safety_rules": [
    "设备 scope 最小化,重操作显式提权",
    "SSRF 白名单别开宽",
    "密钥只进 sqlite/env/600 文件,openclaw.json 用 ${VAR}",
    "push 前扫明文凭证",
    "多模态靠配 imageModel,不是换主模型",
    "读不到就承认,AGENTS.md 写明禁止装懂",
    "不可逆操作默认要确认"
  ],
  "verification": {
    "credential_scan": "grep -rnE '(api[_-]?password|secret|token)\\s*[:=]' ~/.openclaw/workspace/skills/",
    "image_capability": "确认 agents.defaults.imageModel.primary 指向视觉模型",
    "ssrf_policy": "查 browser.ssrfPolicy 白名单是否过宽"
  },
  "not_security_issues": {
    "wiki_9_reports": "memory-wiki 监控仪表盘,空=正常",
    "tunnel_connection_refused": "OVS 多网卡可达性问题,非安全机制"
  },
  "reusable_rule": "OpenClaw 安全=gateway scope/token + 内置 policy + 凭证卫生 + 模型角色配对,没有宪法文件能替代"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

AI Agent 使用指南:

  • 当用户说"截图了 Agent 却在乱说" → 走 §5:确认 imageModel 配了视觉模型,没配就别让它装懂
  • 当用户说"装 skill 要写 API Key 吗" → 走 §4:只进 env/600 文件 + ${VAR} 引用,绝不进 git
  • 当用户说"browser 报 blocked by policy" → 走 §2:SSRF 策略拦的,确需访问就显式加白名单并重启
  • 当用户说"想让某台 CLI 能跑 cron/admin" → 走 §3:显式提权,别默认全开
  • 当用户说"wiki 9 个报告是空的 / Tunnel 连不上" → 走 §7:都不是安全问题
#OpenClaw#AI Agent#安全#SSRF#设备scope#凭证管理#多模态
上次更新: 6/28/2026

← OpenClaw 实战 04|配置管理:双层模型注册 + Token 双源 + 4 处真实陷阱 OpenClaw 实战 06|性能优化:上下文压缩、内存压力、冷启动的先 profile 原则→

最近更新
01
Hermes Agent 实战 15|告别临时 RAG:用 Karpathy 的 LLM Wiki 给 Agent 装上可生长的长期记忆 原创
06-29
02
OpenClaw 实战 11|最佳实践:10 条从真实翻车提炼的 SOP + 推送二次确认硬规则 原创
06-27
03
OpenClaw 实战 07|部署指南:3 形态决策树 + OpenWebUI 接入 + FreshRSS 跨实例 原创
06-27
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式