cgfixit/Veeam-HealthCheck-Simplifier

GitHub: cgfixit/Veeam-HealthCheck-Simplifier

该项目是一个自动化分析 Veeam 备份系统健康检查数据的工具,能够发现合规差距并生成安全的 PowerShell 修复脚本与工单数据。

Stars: 0 | Forks: 0

# Veeam Health Check Simplifier **一个以安全为核心的 VBR pipeline,它接收来自 Veeam Backup & Replication (VBR) 服务器的 [Veeam Health Check](https://vee.am/vhc2) 导出数据,分析其中的合规差距,并生成安全、可审查的修复 artifact。** ## 什么是 Veeam Health Check? [Veeam Health Check (VHC)](https://vee.am/vhc2) 是一个基于 PowerShell 的诊断脚本,可在 Windows 上针对 Veeam Backup & Replication 服务器运行。它会导出涵盖以下内容的 CSV 和 JSON 文件: - **Jobs** — 备份作业配置(保留策略、加密、计划) - **Sessions** — 近期作业运行结果(成功、失败、警告) - **安全合规** — 最佳实践状态(MFA、RDP、加密、不可变性) - **Repositories** — 备份存储目标及不可变性支持 - **恶意软件事件** — inline 扫描、YARA 规则和熵检测结果 本项目获取这些原始导出文件,并将其转化为可操作的修复指南 —— 无需人工审查电子表格。 ### 支持的 VBR 版本 | VBR 版本 | Build | Windows Server | 状态 | |---|---|---|---| | v12.3.2 | 12.3.2.4643 | 2016, 2019, 2022, 2025 | 模拟 VHC fixture 覆盖 | | v13 | 13.0.x fixture 目标 | 2019, 2022, 2025 | 模拟 VHC fixture 覆盖 | ## 工作原理 ``` ┌─────────────────────────────────┐ │ Windows Server with VBR │ │ Run https://vee.am/vhc2 │ │ → Exports CSV/JSON files │ └───────────────┬─────────────────┘ │ ▼ ┌─────────────────────────────────┐ │ vhc_simplifier.py │ │ │ │ 1. Load exports (CSV or JSON) │ │ 2. Analyze across 5 domains │ │ 3. Enrich with remediation cmds │ │ 4. Generate artifacts │ │ 5. (Optional) Push to SF/Slack │ └───────────────┬─────────────────┘ │ ┌────────────────┼────────────────┐ ▼ ▼ ▼ remediation_ fixit.ps1 tickets.json summary.md (safe -WhatIf) (ITSM-ready) ``` ### 分析 Pipeline 1. **加载** — `_safe_load_csv()` / `_safe_load_json()` 支持 UTF-8 BOM 剥离、面向 Windows 的编码回退、损坏解码防护和空文件防护 2. **分析** — 故障隔离的 analyzers(`_run_analyzer()` wrapper 捕获每个 analyzer 的异常,绝不会中止运行): - `analyze_jobs()` — 保留策略、加密、计划差距 - `analyze_sessions()` — 近期的失败和警告 - `analyze_security()` — 最佳实践合规状态 - `analyze_repositories()` — 不可变性支持差距 - `analyze_malware()` — 感染/可疑的扫描结果 3. **丰富** — `enrich_findings()` 将每个发现与带有 KB 文章链接的 PowerShell 修复命令进行模式匹配,并应用 `_ps_quote()` 注入防护 4. **写入** — `_write_artifact()` wrapper 隔离每个文件的 IO 错误: - `remediation_summary.md` — 包含严重程度、PS 代码片段和 KB 链接的易读报告 - `fixit.ps1` — 可执行的修复脚本(所有 mutating verb 都包含 `-WhatIf`) - `tickets.json` — 兼容 ITSM 的 payload(仅限高/中等程度的发现) 5. **集成**(可选) — 将发现作为 Task 推送到 Salesforce,或将摘要发布到 Slack ## 功能 - **多格式输入** — CSV(默认,来自 [vee.am/vhc2](https://vee.am/vhc2))或 JSON(VBR REST API 导出) - **演示模式** — 使用内嵌的真实样本数据即时运行;无需输入文件 - **安全的 PowerShell 输出** — 所有 mutating 命令(`Set-`、`New-`、`Remove-` 等)默认包含 `-WhatIf` - **防止 PS 注入** — 带有控制字符的对象名称会被拒绝,不会被插值 - **Salesforce 集成** — 为高/中等程度的发现在 Account 记录上创建 Task - **Slack 通知** — 将严重程度摘要发送到传入的 webhook - **优雅降级** — 缺少输入文件会被记录但绝不是致命的;部分运行会继续;单个 analyzer 失败会被记录并跳过,而不会中止运行 - **稳健的编码处理** — 容忍 UTF-8 BOM(通常来自 Windows PowerShell `Export-Csv`)、UTF-16 变体和 Windows 代码页回退,同时拒绝损坏的 NUL 解码文件 - **代码中无机密** — Salesforce 凭证仅从环境变量中解析 ## 生成的 Artifact | 文件 | 描述 | |---|---| | `remediation_summary.md` | 包含 PowerShell 代码片段和 KB 链接的易读发现 | | `fixit.ps1` | 安全的预览修复脚本(所有 mutating 命令均带 `-WhatIf`) | | `tickets.json` | 兼容 ITSM 的 JSON payload(仅限高/中等程度的发现) | ## 要求 - Python 3.12+(已在 3.12 和 3.13 上测试) - `pandas`(核心依赖) - `simple-salesforce` *(可选 — 仅用于 `--sf-account-id`)* - `httpx` *(可选 — 如果缺失,Slack 回退将使用标准库 `urllib`)* - `pytest`, `pytest-cov` *(仅限开发/测试)* ``` pip install -r requirements.txt ``` ## 快速开始 ``` # Demo 模式(无需文件 — 使用内置示例数据) python vhc_simplifier.py --demo # 从 VBR 服务器导出真实 CSV(首先在 Windows 上运行 vee.am/vhc2) python vhc_simplifier.py --input-dir ./vhc-exports --output-dir ./results # JSON / VBR REST API 导出 python vhc_simplifier.py --input-dir ./vhc-json --input-format json # 带 Salesforce Task 创建 export SF_USERNAME=user@domain.com export SF_PASSWORD=yourpassword export SF_TOKEN=yoursecuritytoken python vhc_simplifier.py --demo --sf-account-id 001XXXXXXXXXXXX # 带 Slack 通知 python vhc_simplifier.py --input-dir ./vhc-exports \ --slack-webhook https://hooks.slack.com/services/T00/B00/xxx # Quiet 模式(无 console 输出,仅生成 artifacts) python vhc_simplifier.py --input-dir ./vhc-exports --quiet # 跳过 artifact 写入(仅分析) python vhc_simplifier.py --input-dir ./vhc-exports --no-artifacts ``` ## 在 Docker 中运行 ``` # 构建 image docker build -t vhc-simplifier . # 运行一次(Demo 模式,与 CI smoke test 相同) docker run --rm vhc-simplifier --demo --quiet --no-artifacts # 针对真实导出运行一次 docker run --rm \ -v $(pwd)/vhc-exports:/app/input:ro \ -v $(pwd)/output:/app/output \ vhc-simplifier --input-dir /app/input --output-dir /app/output ``` 对于周期性运行,请设置 `CRON_SCHEDULE` 环境变量(标准的 5 字段 cron 语法), 容器将在 `busybox crond` 下保持在前台运行,并在每次计划触发时 使用您传递的任何参数重新调用 CLI: ``` docker run -d --name vhc-simplifier \ -e CRON_SCHEDULE="0 6 * * *" \ -v $(pwd)/vhc-exports:/app/input:ro \ -v $(pwd)/output:/app/output \ vhc-simplifier --input-dir /app/input --output-dir /app/output ``` 容器始终以非 root 用户 `vhc` 的身份运行,包括 cron 进程 —— 镜像内部没有 root cron daemon。 ## CLI 参考 | 标志 | 默认值 | 描述 | |---|---|---| | `--input-dir` | `.` | 包含 VHC 导出文件的目录 | | `--output-dir` | `.` | 用于存放生成 artifact 的目录 | | `--input-format` | `csv` | 输入格式:`csv` 或 `json` | | `--demo` | off | 使用内嵌的样本数据(无需文件) | | `--no-artifacts` | off | 跳过写入 `.md`/`.ps1`/`.json` 文件 | | `--quiet` | off | 禁止控制台报告输出 | | `--verbose` | off | 启用详细/调试日志记录 | | `--sf-account-id` | — | 用于创建 Task 的 Salesforce Account ID | | `--sf-username` | — | SF 用户名(推荐使用 `SF_USERNAME` 环境变量) | | `--sf-password` | — | SF 密码(推荐使用 `SF_PASSWORD` 环境变量) | | `--sf-token` | — | SF 安全令牌(推荐使用 `SF_TOKEN` 环境变量) | | `--slack-webhook` | — | Slack 传入 webhook URL | ## 预期输入文件 这些文件是通过在安装了 VBR 的 Windows Server 上运行 [Veeam Health Check 脚本](https://vee.am/vhc2) 生成的: | 数据 | CSV 文件名 | JSON 文件名 | |---|---|---| | Jobs | `localhost_Jobs.csv` | `localhost_Jobs.json` | | Sessions | `VeeamSessionReport.csv` | `VeeamSessionReport.json` | | Security | `localhost_SecurityCompliance.csv` | `localhost_SecurityCompliance.json` | | Repositories | `localhost_Repositories.csv` | `localhost_Repositories.json` | | Malware | `localhostmalware_events.csv` | `localhostmalware_events.json` | 所有文件均为可选 —— 缺失的文件将被记录并跳过,不会导致中止。 ## 集成 ### Salesforce 为高和中等严重程度的发现在 Salesforce Account 记录上创建 Task。需要 `simple-salesforce` 并通过环境变量提供凭证: ``` export SF_USERNAME=user@domain.com export SF_PASSWORD=yourpassword export SF_TOKEN=yoursecuritytoken python vhc_simplifier.py --demo --sf-account-id 001XXXXXXXXXXXX ``` ### Slack 将严重程度摘要发送到 Slack 传入 webhook。会验证 webhook URL 是否使用 HTTPS 并指向 `hooks.slack.com` 或 `hooks.slack-gov.com`: ``` python vhc_simplifier.py --demo \ --slack-webhook https://hooks.slack.com/services/T00/B00/xxx ``` 如果可用则使用 `httpx`,否则回退到标准库 `urllib`。 ## Docker Compose 提供了一个 `docker-compose.yml`,用于在容器中构建和运行 CLI,而无需在本地安装 Python 或依赖项。 ``` mkdir -p vhc-exports output # 将您的 VHC 导出文件复制到 ./vhc-exports docker compose up --build ``` 这会将 `./vhc-exports` 以只读方式挂载到 `/app/input`,并将 `./output` 以读写方式挂载到 `/app/output`,然后运行 `vhc_simplifier.py --input-dir /app/input --output-dir /app/output --quiet`。如需使用其他标志(例如 Salesforce 或 Slack 集成),请覆盖默认命令: ``` docker compose run --rm vhc-simplifier \ --input-dir /app/input --output-dir /app/output \ --sf-account-id 001XXXXXXXXXXXX \ --slack-webhook https://hooks.slack.com/services/T00/B00/xxx ``` Salesforce 凭证(`SF_USERNAME`、`SF_PASSWORD`、`SF_TOKEN`)从宿主环境或 `.env` 文件中传递 —— 切勿将它们固化到镜像中。`./vhc-exports` 和 `./output` 都不应该被提交;两者均已包含在 `.gitignore` 中。 ## 测试 测试套件涵盖了 6 个文件中的 219 个测试,代码覆盖率达到 90%+: | 测试文件 | 测试 | 覆盖范围 | |---|---|---| | `test_vhc_simplifier.py` | 核心 helper、analyzer、loader、丰富功能、artifact writer、集成运行 | | `test_coverage_gaps.py` | 边缘情况:NaN 处理、空 DataFrame、编码、类型强制转换 | | `test_vbr_server_simulation.py` | VBR v12.3.2 和 v13 mock server 模拟及真实的导出数据 | | `test_windows_server_env.py` | Windows 路径、编码(BOM、UTF-16)、PowerShell 注入、服务器版本矩阵 | | `test_mock_veeam_environment.py` | 带有文件级故障注入的完整 mock VBR 环境 | | `conftest.py` | 包含真实 VBR v12 和 v13 CSV/JSON 导出数据的共享 fixture | ``` # 运行所有测试 python -m pytest tests/ -v # 运行并生成覆盖率报告 python -m pytest tests/ -v --cov=vhc_simplifier --cov-report=term-missing # 仅运行 VBR 服务器模拟测试 python -m pytest tests/test_vbr_server_simulation.py -v ``` ## CI/CD Workflow 六个 GitHub Actions workflow 会在每次向 `main` 分支进行 push 和 pull request 时运行: | Workflow | 文件 | 用途 | |---|---|---| | **CI** | `ci.yml` | Lint + 测试矩阵(在 ubuntu + windows 上的 Python 3.12/3.13),80% 覆盖率阈值 | | **Ruff** | `ruff.yml` | Python lint 和格式检查 | | **Gitleaks** | `gitleaks.yml` | 机密扫描(push、PR、每周) | | **DevSkim** | `devskim.yml` | 微软安全反模式检测(push、PR、每周) | | **CodeQL** | `codeql.yml` | GitHub 静态分析(push、PR、每周) | | **Dependency Review** | `dependency-review.yml` | PR 上的供应链漏洞检查 | | **Trivy** | `trivy.yml` | 容器/依赖项漏洞扫描(文件系统 + Docker 镜像),SARIF → GitHub 代码扫描(push、PR、每周) | ## 部署 提供两种部署选项: - **Docker** — 通过包含的 `Dockerfile` 构建并运行。 - **宿主机原生 (systemd)** — 面向不需要 Docker 的运维人员,`deploy/` 提供了一个 `oneshot` systemd 服务、一个每日的 calendar timer 以及 一个用于日志输出的 `logrotate` 配置。有关安装说明,请参阅 [`deploy/README.md`](deploy/README.md)。 ## 架构 ``` Input (CSV / JSON / --demo) | v _safe_load_*() <- adapter layer (BOM stripping, encoding fallback) | v _run_analyzer() <- fault isolation wrapper (records errors, never aborts) | v analyze_*() <- pure functions, domain-scoped (jobs, sessions, security, repos, malware) | v enrich_findings() <- pattern-matched remediation + PS injection guard (_ps_quote) | |---> _write_artifact() <- IO error isolation wrapper | |---> write_markdown() | |---> write_powershell_script() | `---> write_ticket_payload() |---> _push_to_salesforce() (optional) `---> _post_slack_summary() (optional) ``` ## 退出代码 | 代码 | 含义 | |---|---| | `0` | 成功 | | `1` | 未处理的异常 | | `2` | 发生处理错误(检查 stderr / 日志) | ## 安全说明 - **切勿提交凭证。** 使用环境变量(`SF_USERNAME`、`SF_PASSWORD`、`SF_TOKEN`)或 secrets manager。 - **在移除 `-WhatIf` 之前请审查其输出。** 首先在非生产环境中验证每个命令。 - **防止注入。** 带有 ASCII 控制字符(`0x00-0x1F`、`0x7F`)的对象名称将被完全拒绝,不会进入 PS 命令生成阶段。 - **Slack webhook 验证。** 仅接受 `https://hooks.slack.com/...` 和 `https://hooks.slack-gov.com/...` URL。 - **服务账号与 MFA。** 此工具使用的自动化账号(Salesforce、Slack 以及任何脚本化的 VBR REST API 访问)无法完成交互式 MFA 挑战 —— 有关安全界定非交互式凭证的指南,请参阅 [SECURITY.md](SECURITY.md#service-account--mfa-considerations)。 请参阅 [LICENSE.md](LICENSE.md)、[CONTRIBUTORS.md](CONTRIBUTORS.md) 和 [SECURITY.md](
标签:AI合规, IPv6, PowerShell, Veeam, 数据备份, 请求拦截, 运维, 逆向工具