srini-cybersec/containershield

GitHub: srini-cybersec/containershield

一款纯离线的容器配置静态安全扫描器,通过 34 条 CIS 映射规则检测 Dockerfile、Compose 和 Kubernetes 清单中的配置错误。

Stars: 0 | Forks: 0

# 🛡️ ContainerShield [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/srini-cybersec/containershield/actions/workflows/ci.yml) [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) [![Coverage](https://img.shields.io/badge/coverage-97%25-brightgreen.svg)](#testing) [![Rules](https://img.shields.io/badge/rules-34-orange.svg)](#detection-rules) ContainerShield 是一款**纯 Python、完全离线**的静态分析工具,专门用于分析定义容器供应链的配置文件。它能够解析 Dockerfiles、`docker-compose.yml` 以及 Kubernetes manifests,随后会评估 **34 条检测规则**,这些规则映射了 **CIS Docker & Kubernetes Benchmarks**、NSA/CISA 加固指南以及 CWE 标识符。 它执行 **零网络调用**,绝不运行其扫描的内容,并会对发现的任何 secret 进行脱敏处理 —— 这使得它可以安全地集成到 CI 或气隙管道中。 ## 为什么选择 ContainerShield? 容器配置错误是导致云环境被攻破最常见 —— 也最容易被预防 —— 的原因之一:例如一个设置了 `privileged: true` 的 pod、挂载了 Docker socket、使用了 `:latest` 的基础镜像,亦或是被硬编码到镜像层中的 `AWS` 密钥。其中大多数问题在部署之前的*配置文件*中就已经清晰可见了。 ContainerShield 能够在最早的时机 —— **在编写代码时和 CI 阶段**,也就是在镜像构建或 pod 调度之前 —— 就将它们捕获。 - ✅ **一个工具,三种方言** — 通过单一的标准化引擎支持 Dockerfile、Compose 和 Kubernetes。 - ✅ **气隙安全** — 没有 daemon,没有 API,没有遥测,没有网络请求。 - ✅ **CI 原生** — 生成用于 GitHub Code Scanning 的 SARIF 2.1.0 + 支持 `--fail-on` 门禁拦截。 - ✅ **可解释性** — 每个发现都包含 CWE、CIS 控制、脱敏后的证据以及修复建议。 ## 架构 ``` flowchart LR A[Files / dirs] --> B[Detect type] B --> C1[Dockerfile parser] B --> C2[Compose parser] B --> C3[K8s parser] C1 & C2 & C3 --> D[Rule engine\n34 CIS-mapped rules] D --> E[Scoring 0-100\n+ verdict] E --> F[console / json / csv / sarif / html] E --> G{--fail-on} G -->|exceeded| X[exit 1] ``` 完整设计请参阅 [`docs/architecture.md`](docs/architecture.md)。 ## 安装 ``` # From source git clone https://github.com/srini-cybersec/containershield.git cd containershield pip install -e . # 或者引导一个开发环境(venv + dev deps + tests) ./scripts/setup.sh ``` 要求 **Python 3.11+**。运行时依赖项:`click`、`rich`、`PyYAML`、`Jinja2`。 ## 用法 ``` # 扫描单个文件(自动检测 type) containershield scan Dockerfile # 递归扫描整个项目目录 containershield scan ./deploy/ # 为 GitHub Code Scanning 输出 SARIF containershield scan ./deploy/ -f sarif -o results.sarif # 如果存在任何 HIGH+ issue 则使 CI job 失败 containershield scan ./deploy/ --fail-on HIGH # 仅显示 critical issue,并排除一个 noisy rule containershield scan Dockerfile --min-severity CRITICAL --exclude-rule CS-DKR-006 # 强制将文件视为特定的 type containershield scan my.tmpl --target kubernetes # 列出每个 built-in rule containershield rules containershield rules --target kubernetes --json ``` ### 输出示例 ``` ContainerShield Findings ┏━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Severity ┃ Rule ┃ Location ┃ Issue ┃ ┡━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ CRITICAL │ CS-CMP-001 │ compose.yml (web) │ Service runs in privileged │ │ │ │ │ mode… │ │ CRITICAL │ CS-CMP-003 │ compose.yml (web) │ Mounts the Docker daemon │ │ │ │ │ socket… │ │ HIGH │ CS-CMP-002 │ compose.yml (web) │ Host network namespace… │ └────────────┴────────────┴───────────────────┴────────────────────────────────┘ ╭──────────────────────────── Summary ────────────────────────────╮ │ Files scanned: 1 CRITICAL: 4 HIGH: 2 MEDIUM: 3 LOW: 1 │ │ Risk score: 100/100 Verdict: CRITICAL │ ╰──────────────────────────────────────────────────────────────────╯ ``` ## 检测规则 ContainerShield 内置了跨越三个类别的 **34 条规则**。完整列表请使用:`containershield rules`。 ### Dockerfile (`CS-DKR-*`, 11 条规则) | ID | 严重性 | 检查内容 | CIS | |----|----------|-------|-----| | CS-DKR-001 | HIGH | 容器以 root 用户运行(无非 root 的 `USER`) | 4.1 | | CS-DKR-002 | MEDIUM | 基础镜像使用了可变标签 / `:latest` | 4.2 | | CS-DKR-003 | LOW | 使用了 `ADD` 而非更安全的 `COPY` | 4.9 | | CS-DKR-004 | HIGH | 远程脚本通过管道传递给 shell(`curl \| bash`) | 4.7 | | CS-DKR-005 | CRITICAL | 在 `ENV` / `ARG` 中硬编码了 secret | 4.10 | | CS-DKR-006 | LOW | 未定义 `HEALTHCHECK` | 4.6 | | CS-DKR-007 | MEDIUM | 通过 `sudo` 提升权限 | 4.1 | | CS-DKR-008 | MEDIUM | 全局可写权限(`chmod 777`) | 4.1 | | CS-DKR-009 | LOW | 安装包时未锁定版本 | 4.2 | | CS-DKR-010 | MEDIUM | 暴露了敏感端口(SSH/RDP/Docker API) | 4.1 | | CS-DKR-013 | MEDIUM | `ADD` 获取远程 URL(无校验和) | 4.9 | ### Docker Compose (`CS-CMP-*`, 10 条规则) | ID | 严重性 | 检查内容 | CIS | |----|----------|-------|-----| | CS-CMP-001 | CRITICAL | 特权容器 | 5.4 | | CS-CMP-002 | HIGH | host 网络模式 | 5.9 | | CS-CMP-003 | CRITICAL | 挂载了 Docker socket | 5.31 | | CS-CMP-004 | HIGH | 添加了危险 capability(`SYS_ADMIN`, …) | 5.3 | | CS-CMP-005 | HIGH | 共享了 host PID/IPC namespace | 5.15 | | CS-CMP-006 | LOW | 根文件系统可写 | 5.12 | | CS-CMP-007 | MEDIUM | 未设置 `no-new-privileges` | 5.25 | | CS-CMP-008 | HIGH | 绑定挂载了敏感的 host 路径 | 5.5 | | CS-CMP-009 | CRITICAL | 在 `environment` 中硬编码了 secret | 5.10 | | CS-CMP-010 | MEDIUM | 容器以 root 用户运行 | 5.9 | ### Kubernetes (`CS-K8S-*`, 13 条规则) | ID | 严重性 | 检查内容 | CIS | |----|----------|-------|-----| | CS-K8S-001 | CRITICAL | 特权容器 | 5.2.1 | | CS-K8S-002 | HIGH | `allowPrivilegeEscalation` 未设置为 `false` | 5.2.5 | | CS-K8S-003 | HIGH | 可能以 root 运行(无 `runAsNonRoot`) | 5.2.6 | | CS-K8S-004 | HIGH | `hostNetwork: true` | 5.2.4 | | CS-K8S-005 | HIGH | 共享了 `hostPID` / `hostIPC` | 5.2.2 | | CS-K8S-006 | HIGH | 挂载了 `hostPath` 卷 | 5.2.4 | | CS-K8S-007 | HIGH | 添加了危险 capability | 5.2.9 | | CS-K8S-008 | MEDIUM | 根文件系统可写 | 5.2.11 | | CS-K8S-009 | MEDIUM | 缺少 CPU/内存限制 | 5.7.3 | | CS-K8S-010 | MEDIUM | 镜像使用了可变标签 | 5.5.1 | | CS-K8S-011 | LOW | 自动挂载 Service account token | 5.1.6 | | CS-K8S-012 | HIGH | RBAC 通配符权限 | 5.1.3 | | CS-K8S-013 | MEDIUM | 暴露了 `hostPort` | 5.2.4 | ## 配置 优先级(最高者生效):**CLI 标志 → 环境变量 → 配置文件 → 默认值**。 `.containershield.yml`: ``` min_severity: INFO # suppress findings below this severity fail_on: HIGH # exit 1 if any finding at/above this severity exclude_rules: - CS-DKR-006 # e.g. ignore missing HEALTHCHECK ``` 环境变量: ``` export CONTAINERSHIELD_MIN_SEVERITY=MEDIUM export CONTAINERSHIELD_EXCLUDE_RULES=CS-DKR-006,CS-CMP-006 export CONTAINERSHIELD_FAIL_ON=CRITICAL ``` ## 输出格式 | 格式 | 标志 | 用例 | |---------|------|----------| | Console | `-f console` | 人类可读的 Rich 表格(默认) | | JSON | `-f json` | 机器解析 / 管道 | | CSV | `-f csv` | 电子表格 / 工单系统 | | SARIF | `-f sarif` | GitHub Code Scanning,IDE 集成 | | HTML | `-f html` | 可分享的高管报告 | 风险评分映射到相应的结论:**CRITICAL** (≥80 或存在任何 critical 发现),**HIGH_RISK** (≥50 或存在任何 high 发现),**MODERATE** (≥25),**LOW_RISK** (>0),**CLEAN** (0)。 ## Docker 扫描器以经过加固的非 root 镜像形式发布: ``` docker build -t containershield . # 扫描一个 mounted 的项目,完全 sandboxed(无网络、read-only、无 caps) docker run --rm --network none --read-only \ -v "$PWD:/project:ro" containershield scan /project ``` 或者通过 Compose: ``` docker compose run --rm containershield scan /project ``` 镜像加固:非 root **UID 10001**、`read_only`、`cap_drop: ALL`、`no-new-privileges`、`network_mode: none`。 ## GitHub Actions 集成 ``` - name: ContainerShield scan run: | pip install containershield containershield scan . -f sarif -o containershield.sarif --fail-on HIGH - name: Upload SARIF uses: github/codeql-action/upload-sarif@v3 with: sarif_file: containershield.sarif ``` ## 测试 ``` pytest tests/ -v --cov=src --cov-report=term-missing ``` - **102 个测试**,**97% 覆盖率** - `black`、`ruff`、`mypy` 检查无误;`bandit` 报告 **零** 发现 - CI 会在 Python 3.11 和 3.12 上运行完整的门禁拦截,构建 Docker 镜像,并自检 sample manifests ## 安全考量 - **完全被动且离线。** ContainerShield 仅解析配置;它绝不会构建镜像、运行容器或联系任何网络 endpoint。运行它不需要任何授权。 - **Secret 脱敏。** 检测到的凭据在任何报告中出现之前都会被脱敏(仅保留一小段前缀用于分诊)。 - **防御性解析。** 格式错误或恶意的文件会记录为解析错误并被跳过 —— 它绝不会中止扫描或执行代码。 - **静态分析不能替代**运行时准入控制(例如 Pod Security Standards、OPA/Gatekeeper)或镜像漏洞扫描。请将 ContainerShield 用作安全左移的第一道防线。 ## License [MIT](LICENSE) © 2026 srini-cybersec
标签:Docker, Web截图, 子域名突变, 安全防御评估, 容器安全, 版权保护, 请求拦截, 逆向工具, 错误基检测, 静态代码分析