news 2026/8/28 16:32:53

Hermes Agent 容器镜像安全实战:4 个阶段锁死基础镜像风险

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Hermes Agent 容器镜像安全实战:4 个阶段锁死基础镜像风险

Hermes Agent 容器镜像安全实战:4 个阶段锁死基础镜像风险

【免费下载链接】hermes-agentThe agent that grows with you项目地址: https://gitcode.com/GitHub_Trending/he/hermes-agent

上周有用户反馈 Hermes Agent 容器里的行为跟上周对不上,翻构建日志,根因就一行:基础镜像的latest标签被上游悄悄更新了。那次复盘逼我们把 Hermes Agent 的容器镜像安全整条链路捋了一遍:基础镜像选型、镜像版本锁定、CI 更新流水线到运行时加固,文中每个动作都能直接在仓库里对着抄。

🔒 锁定基础镜像:别让 latest 替你选版本

latest标签为什么是定时炸弹

标签是指针,不是快照。你写FROM debian:latest,版本选择权就交给了上游,下一次构建可能比今天多一个补丁、少一个 CVE。麻烦在于:构建照样绿,问题要到生产才炸。所以基础镜像选型第一步是钉死具体版本,Hermes Agent 的 Dockerfile 里运行时镜像用的就是debian:13.4,版本写死,想升级只有你手动改才会变。换个说法:latest等于把"环境一致性"这条命交给了注册表的策略。

怎么把"锁版本"再锁一层

版本号还有一个口子:上游可能对同一个版本号重新打 tag,内容悄悄变了。真正的镜像版本锁定锁的是 digest。Hermes Agent 的 uv 来源阶段是这么写的:

FROM ghcr.io/astral-sh/uv:0.11.6-python3.13-trixie@sha256:b3c543…

digest 锁的是"这一串字节",不是"叫 0.11.6 的版本"。说白了,digest 是内容寻址,同一个 digest 永远指向同一组层;版本号是人起的名,人起的名会改。Node 来源阶段同样处理,将来升级只需换一行 digest,流水线其余部分不用动。

版本管"该是哪个",digest 管"到底是什么",两层都上才算锁死。

多阶段构建:把构建工具挡在运行时门外

锁版本是一方面,缩小攻击面是另一方面。Hermes Agent 把构建拆成多个阶段:sqlite_build阶段从源码编译指定版本的 SQLite(发行源里的包带着 WAL reset 的旧 bug),node_source阶段取 Node 二进制,运行时镜像只COPY --from拿最终产物。build-essential这类编译器和下载工具留在构建阶段,永远进不了最终镜像。一句话:不运行的东西,就是攻击者用不了的东西。

锁得再死,镜像也会老化——下一步把更新这件事交给流水线。

🔄 把更新写进流水线:三层分离的 CI 实践

怎么让 CI 自动追安全补丁

Hermes Agent 的 CI 更新流水线在 docker.yml,发布拆成三层,各干各的事:

职责关键设计
detect判断 PR 是否影响镜像tests-only 的 PR 跳过完整构建,省 45 分钟
build双架构构建 + 集成测试直接跑刚构建的:test镜像做 docker 测试
publish推送并打 tag唯一持有注册表凭据的 job,测试全过才运行

这样"更新基础镜像"就变成:改 Dockerfile 里的版本或 digest,提 PR,CI 自动验证兼容性,没有"手动推了再说"的环节。publish 与 build 拆开还有个安全原因:PR 构建 job 跑的是外部提交的代码,绝不能给它注册表凭据。

拉第三方二进制,怎么防"上游换货"

构建过程还会从 release 下载 s6-overlay 这类组件,Hermes Agent 的规则是:下载不做校验就不许解包。Dockerfile 里这段逻辑核心就两行:

printf '%s %s\n' "${S6_SHA256}" /tmp/s6.tar.xz > /tmp/s6.sha256 sha256sum -c /tmp/s6.sha256

任何一个 hash 不对,整条构建直接失败。sha256 值直接以 ARG 写在 Dockerfile 里,审计时对着上游 changelog 核一遍就行。这等于把"信任上游网站"换成了"信任仓库里这串字符"。此外还有 osv-scanner.yml 和 supply-chain-audit.yml 定期扫依赖漏洞。

流水线保证了"进来的干净",运行时加固则是容器镜像安全的最后一道门。

🛡️ 运行时加固:五步缩小攻击面

进程为什么必须以非 root 跑

容器里进程默认以 root 跑,进程一被攻破就是容器内最高权限。Hermes Agent 的做法是构建期建专用用户,拷贝时就把权限烙进去:

RUN useradd -u 10000 -m -d /opt/data hermes COPY --link --chmod=a+rX,go-w . .

第一行建 UID 10000 的用户,用高位段是为了不跟宿主机的 uid 撞车;第二行让非 root 用户对代码目录只有读和执行,没有写。docker exec入口也堵上了:一个降权 shim 检测到 root 调用时会自动以hermes用户重新执行,避免你在/opt/data下写出 root 属主的孤儿文件。

只读文件系统之外,还能砍掉哪些东西

动作做法少掉的风险
代码目录只读/opt/hermes非 root 只读,可写状态集中到/opt/dataAgent 运行时改不了自己的 venv 把自己搞坏
缓存清零装完依赖后清 APT 列表和 npm 缓存攻击面与镜像体积一起下降
构建信息入镜HERMES_GIT_SHA构建参数写入.hermes_build_sha线上排障能精确到具体 commit
只装生产依赖uv sync --frozen指定 extras,不用--all-extras开发/测试依赖不会顺带进生产镜像

--frozen这一步别省:它强制按仓库里提交的uv.lock解析,手改某个依赖版本不会在容器里静默生效。同理,npm 侧先拷贝清单再安装,锁文件一变才重新装,既省构建时间,也保证依赖可复现。

前面三个阶段走完,发布下一版镜像前,拿这张清单过一遍。

📋 落地自检清单

  • 所有FROM都有明确版本号或@sha256digest,不存在latest
  • 最终镜像里没有构建工具残留的编译器和下载器(docker history检查)
  • 第三方下载全部经过 sha256 校验才解包
  • 主进程以非 root 用户运行,且 exec 入口有降权兜底
  • 只读与可写目录分离:代码只读,可写状态集中在一个 volume
  • CI 在推送前先构建并跑集成测试,凭据只留在受保护的 job
  • 构建参数烙入源码 commit,任意容器可回溯版本
  • 依赖锁文件在仓库里,构建使用--frozen

【免费下载链接】hermes-agentThe agent that grows with you项目地址: https://gitcode.com/GitHub_Trending/he/hermes-agent

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/28 16:32:32

涉外必看:公证双认证什么意思?足不出户办理方法,无需来回对接

很多人准备出国留学、务工、移民或者开展跨境商务时,会被要求办理公证双认证,但大部分人并不清楚它到底是什么,线下来回跑多个部门对接,耗费大量时间精力。简单来说,公证双认证就是国内文书先完成涉外公证,…

作者头像 李华
网站建设 2026/8/28 16:32:00

MySQL-存储过程的创建和使用

文章目录* * 一、存储过程 * * 1.1 存储过程介绍 * 1.2 存储过程的创建与删除 * * 1.2.1 创建存储过程 * 1.2.2 删除存储过程 * 1.3存储过程的调用 * 1.4 存储过程中的变量使用 * * 1.4.1 局部变量 * 1.4.2 用户变量 * 1.4.3 将查询结果赋值给变量 * 1.5存储过程的参数 * * 1.5…

作者头像 李华
网站建设 2026/8/28 16:30:47

OpenCode 如何 5 分钟跑通:终端 AI 编程助手的完整安装配置指南

OpenCode 如何 5 分钟跑通:终端 AI 编程助手的完整安装配置指南 【免费下载链接】opencode The open source coding agent. 项目地址: https://gitcode.com/GitHub_Trending/openc/opencode OpenCode 是一个开源的终端 AI 编程助手:在命令行里直接…

作者头像 李华
网站建设 2026/8/28 16:30:06

如何快速用 Firecrawl 把网页变成 LLM 可读数据

如何快速用 Firecrawl 把网页变成 LLM 可读数据 【免费下载链接】firecrawl The context API to search, scrape, and interact with the web at scale. 🔥 项目地址: https://gitcode.com/GitHub_Trending/fi/firecrawl 给 Agent 喂网页内容,绕不…

作者头像 李华
网站建设 2026/8/28 16:30:01

响应式界面的线上观察

响应式界面的线上观察复杂表格连续筛选、排序后,页面可能出现 CPU 占用升高或无响应,但并不一定伴随 JavaScript 异常。原因可能是响应式更新循环,也可能是大量计算、布局或第三方逻辑,需要结合现场数据确认。 Vue 3 的 Proxy 响应…

作者头像 李华
网站建设 2026/8/28 16:25:37

利用MCP协议构建AI代理搜索器:从“人找工具”到“协议找工具”

过去一个月,我每次在 MCP 客户端里配置新工具时,都会卡在同一个环节:我得先知道某个工具的地址、用途和调用约定,然后手动写进配置文件。等你真正配完,你会意识到一个更根本的问题已经摆到眼前——AI 代理的数量已经多…

作者头像 李华