nwarila-platform/secure-rockylinux9-template
GitHub: nwarila-platform/secure-rockylinux9-template
基于 Packer + Ansible 的 Rocky Linux 9 STIG 加固 VM 模板构建项目,为 Proxmox VE 自动产出合规镜像并通过 CI 流水线完成验证。
Stars: 0 | Forks: 0
# 安全的 Rocky Linux 9 模板
[](https://github.com/nwarila-platform/secure-rockylinux9-template/actions/workflows/packer.yaml)
[](https://github.com/nwarila-platform/secure-rockylinux9-template/actions/workflows/security.yaml)
[](https://github.com/pre-commit/pre-commit)
[](https://conventionalcommits.org)
[](LICENSE)
一个经过安全强化的 Rocky Linux 9 consumer profile,用于
[Proxmox VE](https://www.proxmox.com/en/proxmox-virtual-environment/overview)。此仓库
不提供独立的 `.pkr.hcl` 构建器。相反,它拥有位于
`packer/` 目录下的 consumer 输入,这些输入会被复制到
[proxmox-packer-framework](https://github.com/nwarila-platform/proxmox-packer-framework) 中,在那里
执行组合验证和特权 `packer build` 步骤。格式化保留在
仓库本地和 PR 门控路径中,而不是在受信任的部署运行器中。这里
被追踪的 Ansible playbook 是 consumer bootstrap 入口点;可重用的 Ansible roles 依然
保留在上游的 [ansible-framework](https://github.com/nwarila-platform/ansible-framework) 中。
## 此仓库的运作方式
1. 此仓库拥有 consumer profile 输入:
`packer/systems.auto.pkrvars.hcl`、`packer/ks.pkrtpl.hcl` 和 `packer/rocky-linux-9.yml`。
2. CI 会检出指定确切 SHA 的 `proxmox-packer-framework` 和 `ansible-framework`。
3. CI 会将此仓库的 consumer 文件复制到 `proxmox-packer-framework/packer`。
4. Packer 验证和构建在 framework 检出中运行,而不是仅在此仓库中。
## 验证依据
截至 2026 年 5 月 4 日,组合的 CI 路径锁定为:
| 组件 | 确切版本 / 锁定 | 真理来源 |
|---|---|---|
| Packer | `1.15.0` | `proxmox-packer-framework/packer/packer.pkr.hcl` |
| `proxmox-packer-framework` | `9b7701638f7fc091abd19412b84f162ba0dc65ac` (`v0.0.1`) | `.github/workflows/packer.yaml` |
| `ansible-framework` | `e1b52f33d9270b14ba55cdb5810a7a3de0c83b90` | `.github/workflows/packer.yaml` |
| Rocky 安装介质 | `Rocky-9.8-x86_64-dvd.iso` | `terraform/terraform.tfvars` |
锁定的 `ansible-framework` 提交目前要求 `Ansible Core >= 2.17, < 2.19` 以及
`Python >= 3.12` 作为其基线。Rocky Linux 9 可重用的强化 roles 仍然是上游的工作,
因此此仓库目前仅拥有 bootstrap playbook 入口点。
## 功能
| 类别 | 当前状态 |
|---|---|
| **OS 强化** | 此仓库中采用面向 CIS 的分区和挂载选项,SELinux 强制模式,启用 firewalld,锁定 root 账户 |
| **安装时合规性** | 通过 Kickstart `%addon com_redhat_oscap` 应用 DISA STIG 配置 |
| **Provisioning** | Consumer 拥有的 Kickstart 模板和被追踪的 Ansible bootstrap playbook 入口点;可重用的 roles 保留在 `ansible-framework` 中 |
| **基础设施** | 通过 `proxmox-packer-framework` 的 Proxmox VE 模板配置,UEFI/OVMF,Secure Boot,TPM 2.0,模板端 Cloud-Init 磁盘 |
| **格式化** | `packer fmt`,`yamllint`,`markdownlint-cli`,`.editorconfig`,VS Code 设置 |
| **安全** | Trivy,Gitleaks,CodeQL,锁定 release 的 `secure-packer-bootstrapper` 运行时凭证,`detect-private-key`,SHA 锁定的 GitHub Actions |
| **依赖管理** | 针对 GitHub Actions 和 `pre-commit` 的 Dependabot,以及针对被追踪的 `secure-packer-bootstrapper` release 锁定的 PR 自动化 |
## 前置条件
### 组合构建契约
| 工具 / 依赖 | 版本 | 说明 |
|---|---|---|
| [Packer](https://developer.hashicorp.com/packer) | `1.15.0` | 来自锁定的 `proxmox-packer-framework` 契约的确切要求 |
| [Ansible Core](https://pypi.org/project/ansible-core/) | `>= 2.17, < 2.19` (例如 `2.18.x`) | 来自锁定的 `ansible-framework` `requirements-dev.txt` 的确切限制;`2.20.x` 超出范围 |
| Python | `3.12.x` | 当前 `ansible-framework` / `ansible-core` 基线要求 |
| Rocky ISO | `Rocky-9.8-x86_64-dvd.iso` | 在通过 GPG 验证 Rocky 签名的 `CHECKSUM` 后,SHA256 被锁定在 `terraform/terraform.tfvars` 中 |
### 本地贡献者工具
| 工具 / 锁定 | 版本 | 说明 |
|---|---|---|
| [pre-commit](https://pre-commit.com/) | 最低 `4.5.1` | 由 `.pre-commit-config.yaml` 强制执行 |
| `pre-commit-hooks` | `v6.0.0` | `.pre-commit-config.yaml` 中的 hook 锁定 |
| [Gitleaks](https://github.com/gitleaks/gitleaks) | `v8.30.1` | `.pre-commit-config.yaml` 中的 hook 锁定 |
| [yamllint](https://pypi.org/project/yamllint/) | `1.38.0` | hook 锁定;VS Code 任务也期望本地有 CLI |
| [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli) | `v0.48.0` | hook 锁定;VS Code 任务也期望本地有 CLI |
| [conventional-pre-commit](https://github.com/compilerla/conventional-pre-commit) | `v4.4.0` | Commit-msg hook 锁定 |
## 入门指南
### 1. 克隆此仓库及所需的同级框架
```
git clone https://github.com/nwarila-platform/secure-rockylinux9-template.git
git clone https://github.com/nwarila-platform/proxmox-packer-framework.git
git clone https://github.com/nwarila-platform/ansible-framework.git
```
默认的 VS Code 任务和组合的本地验证路径期望存在这些同级目录:
```
../secure-rockylinux9-template
../proxmox-packer-framework
../ansible-framework
```
### 2. 安装 Pre-Commit Hooks
```
pip install pre-commit
pre-commit install --hook-type pre-commit --hook-type pre-push --hook-type commit-msg
```
### 3. 配置 GitHub 设置和运行时 Bootstrap 输入
以下设置分为静态仓库自有输入和运行时生成的 bootstrap
物料:
- GitHub 仓库密钥 / 变量使用第一列中面向人类的名称。
- 经过审查的 `secure-packer-bootstrapper` release 锁定位于
`.github/pins/secure-packer-bootstrapper.env` 中,并由工作流在 pull request 中刷新。
- 经过审查的 Rocky ISO 锁定位于 `terraform/terraform.tfvars`;使用
`terraform/scripts/fetch_rocky_iso_sha256.sh` 刷新它,以便仅在
验证 Rocky 签名的 `CHECKSUM` 后提取提交的 SHA256。
- ISO 管理器根目录的 Terraform state 使用 HCP Terraform 远程 state 和锁定,位于
`secure-rockylinux9-template-iso` 工作区中。
- 本地手动 Packer 运行可以直接导出确切的 `PKR_VAR_*` 名称,或者在
与 `packer validate` / `packer build` 相同的 shell 中 `eval`
`secure-packer-bootstrapper` release bundle。
在第一个发布的 `secure-packer-bootstrapper` release 存在且 PR 自动化刷新
提交的锁定文件之前,特权构建会故意封闭失败,而不是猜测
bundle URL 或 checksum。
| GitHub 设置 | 本地等效项 | 目的 / 优先级 |
|---|---|---|
| `PROXMOX_HOSTNAME` | `PKR_VAR_proxmox_hostname` | Proxmox API endpoint |
| `PROXMOX_PACKER_FRAMEWORK_TOKEN_ID` | `PKR_VAR_proxmox_api_token_id` | Proxmox API token ID |
| `PROXMOX_PACKER_FRAMEWORK_SECRET` | `PKR_VAR_proxmox_api_token_secret` | Proxmox API token secret |
| `PROXMOX_SKIP_TLS_VERIFY` | `PKR_VAR_proxmox_skip_tls_verify` | 顶层覆盖。设置后,它将优先于 `packer_image.insecure_skip_tls_verify`。此仓库在提交的 profile 中保留 `true` 作为文档记录的实验室例外情况。 |
| `PROXMOX_NODE` | `PKR_VAR_proxmox_node` | 顶层覆盖。设置后,它将优先于 `packer_image.node`。 |
| `DEPLOY_USER_NAME` | `PKR_VAR_deploy_user_name` | 客户机部署账户名 |
| `PROXMOX_VE_ENDPOINT` | provider env | Terraform ISO 管理器使用的 Proxmox API endpoint |
| `PROXMOX_VE_API_TOKEN` | provider env | Terraform ISO 管理器使用的 Proxmox API token |
| `TF_API_TOKEN` | `TF_TOKEN_app_terraform_io` | 用于远程 state 和锁定的 HCP Terraform token |
| `.github/pins/secure-packer-bootstrapper.env` | 被追踪的 release 锁定文件 | 经过审查的 release 仓库、tag、资源 URL 和 CI 使用的 SHA256 |
| `terraform/terraform.tfvars` | 被追踪的 ISO 锁定文件 | 经过审查的 Rocky ISO URL、SHA256 和 Terraform 使用的文件名 |
运行时 bootstrap 步骤会在 `packer validate` 和
`packer build` 之前立即生成以下值:
- `PKR_VAR_deploy_user_password`
- `PKR_VAR_deploy_user_password_hash`
- `PKR_VAR_deploy_user_key`
- `SPB_DEPLOY_USER_PASSWORD`
- `SPB_SSH_PRIVATE_KEY_FILE`
- `SPB_SSH_KEY_PASSPHRASE`
CI 使用生成的 SSH 密钥进行第一跳登录,生成的密码哈希用于 Kickstart
`user --iscrypted`,并且仅出于 sudo / Ansible `become` 的目的保留明文密码。
### 4. 自定义 Consumer 输入
- `packer/systems.auto.pkrvars.hcl` 包含了 VM ID、节点、存储、IP 和
VLAN 分配的真实所有者默认值。这些是保留的所有者默认值,而不是可移植的示例。
- `packer/ks.pkrtpl.hcl` 拥有安装时的客户机基线:分区、挂载选项、
OpenSCAP STIG 调用、用户创建和安装后强化命令。
- `packer/rocky-linux-9.yml` 拥有 consumer bootstrap playbook 入口点。可重用的 roles 保留
在上游的 `ansible-framework` 中。
- `terraform/terraform.tfvars` 锁定了确切的 Rocky ISO URL、文件名和
`terraform-proxmox-iso-manager-framework` 所使用的 SHA256。
要提升 Rocky ISO 的锁定版本,如果确切的文件名发生更改,请更新 `ROCKY_ISO_FILENAME`,运行
`terraform/scripts/fetch_rocky_iso_sha256.sh`,将打印出的 SHA256 复制到 `terraform.tfvars`,
更新 `iso_pin.url` 和 `iso_pin.filename`,然后在打开 PR 之前运行 Terraform 验证。
## 项目结构
```
.
|-- .github/
| |-- pins/ # Reviewed secure-packer-bootstrapper release pin
| |-- scripts/ # CI helper scripts
| `-- workflows/ # GitHub Actions workflows
|-- .config/ # Markdown/YAML lint configuration
|-- .vscode/ # Editor tasks/settings for the multi-repo workflow
|-- packer/
| |-- ks.pkrtpl.hcl # Consumer-owned Kickstart template
| |-- rocky-linux-9.yml # Consumer-owned bootstrap playbook entrypoint
| `-- systems.auto.pkrvars.hcl # Consumer-owned framework input profile
|-- terraform/
| |-- scripts/ # ISO checksum provenance helpers
| `-- terraform.tfvars # Reviewed Rocky ISO pin consumed by Terraform
|-- tests/ # Workflow-policy and pin-refresh unit tests
|-- .editorconfig
|-- .gitattributes
|-- .gitignore
|-- .pre-commit-config.yaml
|-- CHANGELOG.md
|-- CONTRIBUTING.md
|-- README.md
|-- SECURITY.md
`-- SUPPORT.md
```
## 验证策略
### 仓库本地检查
- `pre-commit run --all-files`
- `terraform/scripts/fetch_rocky_iso_sha256.sh`
- 针对提交的 consumer 文件运行 `yamllint` / `markdownlint-cli` / `packer fmt`
### 组合框架验证
此仓库真正的契约测试发生在 consumer 文件被复制到
`../proxmox-packer-framework/packer`(本地任务)或
`${{ github.workspace }}/proxmox-packer-framework/packer`(CI)之后。该组合路径执行:
1. 针对锁定的 `../ansible-framework/ansible.cfg` 进行 Ansible 语法检查
2. `packer init`
3. `packer validate`
### 分支提升门控
PR 工作流路径拥有非特权门控:
1. 验证被追踪的 `secure-packer-bootstrapper` release 锁定是最新的
2. 针对工作流契约和锁定刷新助手运行仓库原生自动化单元测试
3. 运行 `pre-commit run --all-files`
4. 在安装前,针对被追踪的 SHA256 验证锁定的 Packer 下载
5. 检出锁定的框架仓库
6. 运行 Ansible 语法验证以及组合的 `packer init` / `packer validate`
### 完整的集成构建
完整的构建验证需要自托管运行器、xmox 访问权限以及位于
`.github/workflows/packer.yaml` 中的特权 CI 路径。
### 原生 `packer test`
此仓库目前不提供本地的 `.pkr.hcl` 构建定义,因此仓库根目录的原生
`packer test` 不是此处的规范测试路径。
## VS Code 任务
按 `Ctrl+Shift+B` 运行默认的
**Full Validation (Requires sibling frameworks)** 任务。
支持框架的任务会被显式标记,并期望存在相邻的 `proxmox-packer-framework` 和
`ansible-framework` 检出。仓库本地的 lint 任务依然可单独使用。
## CI/CD 流水线
| 工作流 | 触发器 | 目的 |
|---|---|---|
| **PR Verify** | 针向 `main` 的 Pull request | 运行分支提升门控:锁定新鲜度、自动化单元测试、仓库本地检查、已验证的工具 bootstrap、Ansible 语法验证以及组合的 `packer validate` |
| **Refresh secure-packer-bootstrapper Pin** | PR 同步、每周计划、手动 | 刷新 `.github/pins/secure-packer-bootstrapper.env` 中被追踪的 release URL 和 SHA256 |
| **Packer Build** | 推送至 `main`,仅在 `main` 上手动触发 | 仅运行受信任的部署路径:加载经过审查的 release 锁定、生成运行时凭证、执行最终的 `packer validate` 并构建 |
| **Security Scan** | 推送、PR、每周计划 | Trivy 文件系统/密钥扫描以及 Gitleaks 历史扫描 |
| **CodeQL Analysis** | 推送、PR、每周计划 | GitHub Actions 工作流的静态分析 |
| **Release Please** | 推送至 `main` | 仅针对仓库源代码/配置进行语义化版本控制并生成更新日志 |
## GitHub 仓库控制
这些保护措施存在于 GitHub 设置中,而不是此检出中,但它们是
仓库契约的一部分,应与工作流集合保持一致:
- 默认分支上的活动规则集,用于签名提交、线性历史、受保护的 PR 合并,
和必需的状态检查:`Branch Promotion Gates`、`Trivy (Filesystem & Secrets)`、
`Gitleaks (Secret Scan)` 和 `CodeQL (actions)`
- 一个真实的 `packer-build` 环境,具有部署分支限制和审查者保护
- 仓库级别的 SHA 锁定要求用于 GitHub Actions
- 默认的 `GITHUB_TOKEN` 权限设置为只读,并禁用工作流审查批准
## VM 模板规格
| 组件 | 配置 |
|---|---|
| **OS** | Rocky Linux 9.7 (x86_64) |
| **启动** | UEFI (OVMF),Secure Boot,TPM 2.0 |
| **CPU** | 2 核心,host passthrough |
| **内存** | 4096 MB |
| **磁盘** | 100 GB LVM 布局,定义于 `packer/ks.pkrtpl.hcl` |
| **网络** | virtio 适配器,提交的 profile 中静态的所有者保留 IP/VLAN |
| **Provisioning** | Consumer 拥有的 Kickstart 模板、OpenSCAP STIG 安装 profile、bootstrap playbook 入口点 |
| **Cloud-Init** | 启用模板端 Cloud-Init 磁盘;客户机镜像安装 `cloud-init` 包,但 datasource 行为未经 CI 单独验证 |
### 磁盘分区
| 分区 | 大小 | 挂载点 | 选项 |
|---|---|---|---|
| EFI | 1024 MB | `/boot/efi` | `nodev,nosuid` |
| Boot | 1024 MB | `/boot` | `nodev,nosuid` |
| Root | 10240 MB | `/` | - |
| Home | 4096 MB | `/home` | `nodev,nosuid,noexec` |
| Opt | 2048 MB | `/opt` | `nodev` |
| Tmp | 4096 MB | `/tmp` | `nodev,noexec,nosuid` |
| Var | 2048 MB | `/var` | `nodev,nosuid` |
| Var-Tmp | 1000 MB | `/var/tmp` | `nodev,noexec,nosuid` |
| Var-Log | 4096 MB | `/var/log` | `nodev,noexec,nosuid` |
| Var-Audit | 500 MB | `/var/log/audit` | `nodev,noexec,nosuid` |
## 安全控制快照
### 此仓库中实现的直接控制
| 控制 | 证据 | 说明 |
|---|---|---|
| 锁定的 root 账户 | `packer/ks.pkrtpl.hcl` | `rootpw --lock` |
| SELinux 强制模式 | `packer/ks.pkrtpl.hcl` | 安装时的基线 |
| 启用 firewalld | `packer/ks.pkrtpl.hcl` | 明确允许 SSH |
| 固定的 LVM 布局和挂载选项 | `packer/ks.pkrtpl.hcl` | 上方的分区表反映了当前的 Kickstart |
| 部署用户创建和 SSH 访问 | `packer/ks.pkrtpl.hcl` | 使用 `user --iscrypted`,安装运行时生成的公钥,并禁用 SSH 密码验证 |
| SSH/SFTP 规范化 | `packer/ks.pkrtpl.hcl` 和 `packer/rocky-linux-9.yml` | 保持 communicator 在 bootstrap 期间工作 |
| Bootstrap playbook 就绪检查 | `packer/rocky-linux-9.yml` | 前置任务探测、连接重置、fact gathering |
| 安装 `cloud-init` 包 | `packer/ks.pkrtpl.hcl` | 从 Kickstart 安装客户机包 |
### 在安装时委托的控制
| 控制 | 所有者 | 说明 |
|---|---|---|
| DISA STIG profile 应用 | OpenSCAP / SCAP Security Guide | 通过 `%addon com_redhat_oscap` 应用 |
| 额外的 STIG 管理客户机设置 | OpenSCAP / SCAP Security Guide | 对版本敏感,未在此完全列举 |
### 继承自框架 / 平台连接的控制
| 控制 | 所有者 | 状态 |
|---|---|---|
| 模板端 Cloud-Init 磁盘附加 | `proxmox-packer-framework` + Proxmox VE | 在 consumer profile 中启用 |
| Ansible provisioner 连接和 `roles_path` 移交 | `proxmox-packer-framework` + `ansible-framework` | 活跃 |
### 尚未在此处获得证据的控制
| 控制 | 预期所有者 | 当前状态 |
|---|---|---|
| 可重用的 Rocky Linux 9 强化 roles | `ansible-framework` | 尚未在锁定的上游提交中获得证据 |
| 仓库拥有的运行时合规性验证 | 下游运营商或未来的 CI | 未在此仓库中实现 |
## 发布语义
此仓库中的 Git 标签和 GitHub Releases 仅对 consumer profile 源代码和
配置进行版本控制。它们本身并不能证明已构建的 Proxmox VM 模板构件。
自动生成的源代码归档已通过 `.gitattributes` 过滤;它们不是已发布的 VM
构件或完整的运营商 bundle。
## 安全
有关漏洞披露、运行器信任边界说明和
密钥检测覆盖限制,请参阅 [SECURITY.md](SECURITY.md)。
## 支持
有关此仓库、
`proxmox-packer-framework`、`ansible-framework` 和下游运行时操作之间的支持边界,请参阅 [SUPPORT.md](SUPPORT.md)。
## 许可证
此项目采用 [MIT License](LICENSE) 授权。
标签:Ansible, Packer, Proxmox, Rocky Linux, 安全合规, 系统加固, 系统提示词, 系统镜像构建, 网络代理, 逆向工具