nedlir/dasel-hardened-container

GitHub: nedlir/dasel-hardened-container

基于 melange/apko 构建的 dasel v3.3.1 加固容器镜像,修补了 YAML 别名展开漏洞并提供极简、可复现、纵深防御的运行时环境。

Stars: 0 | Forks: 0

# dasel v3.3.1 加固容器 这是一个针对 [dasel v3.3.1](https://github.com/TomWright/dasel/releases/tag/v3.3.1) 的 melange 软件包和 apko 容器镜像,包含针对 [CVE-2026-33320](https://github.com/TomWright/dasel/security/advisories/GHSA-4fcp-jxh7-23x8)(无限制 YAML 别名展开)的构建时补丁。该镜像完全由本地生成的 APK 构建而成 - 未使用任何预构建的上游镜像。 ## 前置条件 | 工具 | 已测试版本 | 用途 | | ------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | | Docker | 29.3.1 | 容器运行时,通过 `compose.yaml` 运行 melange/apko | | melange | 0.50.5 (Docker image `cgr.dev/chainguard/melange@sha256:b6f11bb45a6090c182986028fd2249fb1a18dcb6e173c4ce001dd3fb4cb1dd71`) | APK 软件包构建器 | | apko | 1.2.10 (Docker image `cgr.dev/chainguard/apko@sha256:20dfc1f5e3461b5eaf3279f762cd4bf86c7f3635d2a9642f905cf583525f9ee6`) | OCI 镜像构建器 | - 架构:仅限 **x86_64** - 初始构建需要互联网访问(获取源码压缩包、Go 模块、Wolfi 软件包) ### Windows 要求 所有构建和加载命令均可在任何终端(PowerShell、CMD 或 bash)下运行。仍有一个步骤需要 Unix shell: - `bash tests/test.sh` — 测试脚本使用了 bash 和 coreutils(`timeout`、`grep`、`sed`) 在运行镜像测试之前,请安装 **Git Bash**(随 [Git for Windows](https://git-scm.com/download/win) 附带提供)。 ## 项目结构 ``` . ├── melange/ │ ├── dasel.yaml │ └── CVE-2026-33320.patch ├── apko/ │ └── dasel.yaml ├── tests/ │ └── test.sh ├── compose.yaml ├── keys/ # Generated, gitignored │ ├── melange.rsa │ └── melange.rsa.pub ├── sbom/ # Generated, gitignored │ ├── sbom-x86_64.spdx.json │ └── sbom-index.spdx.json ├── packages/ # Generated, gitignored │ └── x86_64/ │ ├── dasel-3.3.1-r0.apk │ └── APKINDEX.tar.gz └── README.md ``` ## 构建 ``` # 1. 生成签名密钥(一次性) docker compose run --rm melange keygen keys/melange.rsa # 2. 构建 APK 包(拉取源代码,应用 CVE 补丁,编译) docker compose run --rm melange build melange/dasel.yaml --arch x86_64 --signing-key keys/melange.rsa # 3. 构建 OCI 镜像(使用本地 APK) docker compose run --rm apko build apko/dasel.yaml dasel:3.3.1 dasel.tar --arch x86_64 --sbom-path sbom/ ``` 步骤 2 会自动生成并签名 `packages/x86_64/APKINDEX.tar.gz`。 ## 运行 加载镜像后,运行 dasel: ``` docker load --input dasel.tar # 示例:查询 JSON 文件 echo '{"name": "dasel"}' | docker run --rm \ --read-only \ --cap-drop=ALL \ --security-opt=no-new-privileges \ -i dasel:3.3.1-amd64 \ -i json 'name' ``` 这些标志强制执行了 [镜像加固](#image-hardening) 中描述的纵深防御策略的运行时层:不可变的根文件系统、零 Linux capabilities,以及无特权升级路径。 ## 测试 ``` docker compose run --rm melange test melange/dasel.yaml --arch x86_64 ``` **镜像测试:** ``` # 加载镜像(适用于 PowerShell、CMD 或 bash) docker load --input dasel.tar # 运行测试脚本(在 Windows 上需要 Git Bash) bash tests/test.sh ``` 测试脚本验证了: - 镜像加载成功且 `dasel version` 报告为 `v3.3.1` - JSON 键提取(`-i json 'test'`) - JSON 到 YAML 的转换(`-i json -o yaml --root`) - CVE 补丁:恶意的十亿笑声 YAML 会触发 `"yaml expansion budget exceeded"` 而非挂起 ## CVE-2026-33320 修复 该漏洞允许通过指数级嵌套的 YAML 别名(十亿笑声攻击)造成无限制的 CPU/内存消耗。位于 `melange/CVE-2026-33320.patch` 的补丁为 dasel 的 YAML 读取器增加了两道防线:一个是限制递归别名嵌套的展开深度限制(32),另一个是限制每个文档总别名解引用次数的展开预算(1000)。当触及任一限制时,解码将立即返回错误。 ## 安全性、可复现性与极简性 - **安全性**:CVE-2026-33320 在构建时已被修补。所有软件包均已签名。镜像仅包含 3 个 APK 软件包(wolfi-baselayout、ca-certificates-bundle、dasel) - **可复现性**:软件包和镜像均采用声明式 YAML。源码压缩包通过 SHA256 固定。所有工具版本均已记录在案。Go 二进制文件使用 `-trimpath` 构建,以剥离本地构建路径 - **极简性**:最终镜像中没有 shell,也没有软件包管理器 - 仅有 dasel 二进制文件、CA 证书和 baselayout ### 镜像加固 该镜像在最小化打包的基础上应用了纵深防御: | 层级 | 措施 | 效果 | | ------- | ---------------------------------- | --------------------------------------------------- | | 构建 | 非 root 用户 (UID 65532) | 容器进程永远不会以 root 身份运行 | | 构建 | `-s -w` ldflags + 自动 `-trimpath` | 经过剥离的二进制文件,无本地路径泄露 | | 构建 | 仅 3 个软件包 | 最小攻击面,没有 shell 或软件包管理器 | | 运行时 | `--read-only` | 不可变的根文件系统 | | 运行时 | `--cap-drop=ALL` | 零 Linux capabilities | | 运行时 | `--no-new-privileges` | 防止通过 setuid/setgid 进行特权升级 | ## 漏洞扫描 构建好的镜像(`dasel.tar`)使用行业标准工具进行了扫描,以验证超出 CVE 补丁本身的安全态势。 ### Syft (SBOM 生成) Syft 通过检查 Go 二进制文件的模块元数据,从镜像中提取了 **36 个软件包**: - **3 个 APK 软件包**:`wolfi-baselayout` 20230201-r29、`ca-certificates-bundle` 20260413-r0、`dasel` 3.3.1-r0 - **32 个 Go 模块**:包括 `go.yaml.in/yaml/v4`、`github.com/hashicorp/hcl/v2`、`github.com/pelletier/go-toml/v2`、`github.com/goccy/go-json`、`github.com/charmbracelet/bubbletea`、`golang.org/x/sys`、`golang.org/x/text`、`stdlib` go1.25.9,以及另外 25 个 - **清点的 19 个文件**:`/usr/bin/dasel`、`/etc/ssl/certs/ca-certificates.crt`、APK DB、每个软件包的 SBOM,以及 baselayout 配置文件 ### Grype (漏洞扫描器) 我生成的 SBOM 使用 Grype 进行了检查,在所有 32 个 Go 模块或 3 个 APK 软件包中未发现其他漏洞。 ## 提交 ### 假设 - **仅限 x86_64** - 单架构构建。多架构构建将需要额外的 `--arch` 标志 - **一次性签名密钥** - 在本地生成并已被 gitignore。在生产环境中,私钥签名密钥应存储在 secrets manager 中,而不是本地文件系统上。因为即使是被 gitignore 的文件,也可能通过备份工具、容器卷挂载或受损的工作站暴露。 - **Wolfi OS 依赖** - 构建和最终镜像依赖于 Wolfi 软件包(`busybox`、`go`、`ca-certificates-bundle`)。如果在这些上游软件包中的任何一个发现漏洞,也将影响此镜像。在生产中,保持 Wolfi 软件包最新或订阅其安全建议是必要的 - **Docker Compose 包装器** - melange 和 apko 通过 `compose.yaml` 作为 Docker 容器运行。此项在 Kali 2025.3 上开发,并在带有 Docker Desktop 29.3.1 的 Windows 10 上进行了验证 - **测试脚本需要 bash** - `tests/test.sh` 使用 `timeout`(coreutils)和 Docker CLI。所有其他命令都是纯粹的 `docker` 命令,可在 PowerShell 或 CMD 中运行。在 Windows 上,请从 Git Bash 运行测试脚本(参见 [Windows 要求](#windows-requirements)) ### SBOM 覆盖范围缺口 apko 在构建时会自动将 SPDX SBOM 生成到 `sbom/` 目录中(`sbom/sbom-x86_64.spdx.json`、`sbom/sbom-index.spdx.json`)。它们跟踪 3 个已安装的 APK 软件包的版本、CPE、来源证明和 Melange 构建定义引用。然而,它们**不**包括编译到 `dasel` 二进制文件中的 Go 模块依赖。我决定对它们进行扫描,并使用 Syft 通过从二进制文件的嵌入元数据中提取所有 32 个 Go 模块来弥补这一缺口。 对于生产环境,应该有一些自动化 SBOM 提取的工具来定期轮询。然后也许可以使用我用 Golang 编写的类似 [https://github.com/nedlir/CVEnotifier](https://github.com/nedlir/CVEnotifier) 的工具附加 SBOM 结果,以发现供应链中的新漏洞。 ### 运行的命令及结果 | 命令 | 结果 | | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | | `docker compose run --rm melange keygen keys/melange.rsa` | 通过 | | `docker compose run --rm melange build melange/dasel.yaml --arch x86_64 --signing-key keys/melange.rsa` | 通过 - 已应用补丁 (7/7 hunks),生成了 APK | | `docker compose run --rm melange test melange/dasel.yaml --arch x86_64` | 通过 - 版本、JSON 键提取、JSON 数组访问 | | `docker compose run --rm apko build apko/dasel.yaml dasel:3.3.1 dasel.tar --arch x86_64 --sbom-path sbom/` | 通过 - 已安装 3 个软件包,生成了 OCI 压缩包 | | `docker load --input dasel.tar` | 通过 - 已加载 `dasel:3.3.1-amd64` | | `bash tests/test.sh` | 通过 - 所有测试(版本、键提取、格式转换、YAML 别名、CVE 补丁) | | `docker run --rm -v ... anchore/grype:latest /work/dasel.tar` | 通过 - 1 个发现(针对已修补 CVE 的预期误报) | | `docker run --rm -v ... anchore/syft:latest /work/dasel.tar` | 通过 - 编录了 36 个软件包 (3 APK + 32 Go + 1 stdlib) | ### 未来改进 - **多架构构建** - 支持多种架构来构建此容器。 - **CI/CD 流水线** - 在 GitHub Actions 中通过 melange/apko 容器操作自动化构建和测试 - **melange 中的 Go 级别 SBOM** - 在 melange 构建流水线期间运行 `syft`,并将 Go 模块 SBOM 与 APK 一起嵌入
标签:Apko, APK打包, Chainguard, CVE-2026-33320, Dasel, DevSecOps, Docker, GitHub Advanced Security, Go语言, Melange, OCI镜像, Wolfi Linux, x86_64架构, YAML反序列化安全, 上游代理, 安全加固, 安全补丁, 安全防御评估, 容器化构建, 容器镜像安全, 数据选择器, 日志审计, 漏洞修复, 程序破解, 网络安全培训, 请求拦截