TacoRocket/terraform-labs-for-azurefox

GitHub: TacoRocket/terraform-labs-for-azurefox

一个基于 OpenTofu 的 Azure 靶场,托管可销毁资源以供 AzureFox 进行端到端验证与取证。

Stars: 1 | Forks: 0

# AzureFox OpenTofu 证明实验室

AzureFox OpenTofu Proof Lab logo

此仓库包含用于 AzureFox 的 OpenTofu 实验室环境。 它在可处置订阅中创建了一个小型 Azure 足迹,您可以部署并针对其运行 AzureFox,用于演示、验证运行以及能力证明测试。 与主 AzureFox 仓库不同,本仓库旨在保持动手实践且易于检查。目标是让实验室行为显而易见,而不是隐藏在额外封装之后。 ## 配套仓库 本实验室与主 AzureFox 项目配套: - 主仓库:[TacoRocket/AzureFox](https://github.com/TacoRocket/AzureFox) 使用本仓库部署和验证实验室环境。使用主 AzureFox 仓库获取 CLI、命令实现和发布源。 ## 本仓库用途 - 为 AzureFox 提供真实的 Azure 目标用于演示和验证运行 - 针对实时基础设施执行当前 AzureFox 命令集 - 提供可重复的 OpenTofu 部署与拆除流程 - 生成验证工件,展示 AzureFox 在已知实验室条件下的发现 ## AzureFox 覆盖范围 实验室用于验证此发布门槛下的 AzureFox 独立命令子集。AzureFox 在 `main` 分支上可能还有更多处于发现阶段或尚未具备确定性实验室证明对象的命令。 当前验证覆盖范围: - `whoami` - `inventory` - `automation` - `devops` - `arm-deployments` - `env-vars` - `tokens-credentials` - `rbac` - `principals` - `permissions` - `privesc` - `role-trusts` - `lighthouse` - `cross-tenant` - `resource-trusts` - `auth-policies` - `managed-identities` - `keyvault` - `storage` - `vms` - `vmss` - `nics` - `dns` - `endpoints` - `network-ports` - `workloads` - `app-services` - `functions` - `api-mgmt` - `aks` - `acr` - `databases` - `snapshots-disks` 可选的组合后续: - `chains credential-path` - `chains deployment-path` - `chains escalation-path` 本项目优先使用 OpenTofu,但 HCL 保持接近标准 Terraform 风格,以便大多数操作者熟悉。 当前检查点说明: - `docs/activity-log-bundles.md` - `docs/live-run-strategy.md` - `docs/phase2-secrets-config-resource-checkpoint.md` - `docs/phase3-compute-apps-network-checkpoint.md` - `docs/phase4-command-discovery-checkpoint.md` 当前发布边界: - 本仓库当前针对 AzureFox `1.3.0` 作为当前 parity 边界 - 确定性实验室支持的证明现已包含 `snapshots-disks`、`vmss` 以及一个 Automation 账户 - `lighthouse` 和 `cross-tenant` 作为证据驱动的租户面验证,而非固定行数证明 - `devops` 条件性验证:未配置 `AZUREFOX_DEVOPS_ORG` 时,验证器期望出现缺少组织的真实问题,而非假装存在流水线覆盖 - 组合的 `chains` 后续仍为可选;Firefox/AzureFox `1.3.0` 增加了更多实时证明感知的 `credential-path` 表述,但本实验室仍将组合链输出视为次要验证门 ## 实验室形态 - 四个资源组:`rg-network`、`rg-data`、`rg-workload`、`rg-ops` - 一个 VNet,包含一个工作负载子网和一个私有端点子网 - 一个名为 `vm-web-01` 的公共 Linux 虚拟机 - 一个名为 `vmss-api` 的 Linux 虚拟机规模集 - 一个名为 `ua-app` 的用户分配托管标识 - 两个应用注册及其支持的服务主体用于角色信任验证: `af-roletrust-api` 和 `af-roletrust-client` - `af-roletrust-api` 上的一个联合身份凭证 - 从 `af-roletrust-client` 到 `af-roletrust-api` 的一个内部应用角色分配 - 低影响的 `Reader` RBAC 分配,使服务主体对 AzureFox 可见 - 一个允许公共 Blob 访问且防火墙默认操作为 `Allow` 的存储账户 - 一个防火墙默认操作为 `Deny` 并带有私有端点的存储账户 - 一个公共 Blob 容器,用于托管链接的 ARM 模板和参数工件 - 四个 Key Vault,覆盖以下场景: 公共网络开放 公共网络启用但拒绝访问 公共网络加私有端点 仅私有端点 - 一个带有系统分配标识的 Linux 应用服务和一个明文的敏感设置 - 一个带有系统分配标识和用户分配标识的 Linux 函数应用,并使用 Key Vault 托管的应用设置 - 一个带有附加标识且应用设置为空的 Linux 应用服务 - 一个工作负载子网上的子网级 NSG 允许规则,使 `network-ports` 拥有公共入口的显式证据 - 一个带有系统分配标识的 API Management 服务,包含一个 API、一个后端和一个命名值 - 一个带有公共控制平面端点和系统分配标识的 AKS 集群 - 一个启用公共网络访问并开启管理员用户的 Azure 容器注册表 - 一个 Azure SQL 服务器,含一个用户数据库 - 一个带有系统分配标识的 Azure Automation 账户 - 一个公共 DNS 区域和一个私有 DNS 区域(带注册启用的 VNet 链接) - 三个部署历史对象: 一次成功的订阅级部署(带链接模板 URI) 一次成功的资源组部署(带链接参数 URI) 一次失败资源组部署(无输出) - 一个订阅范围的 `Owner` 角色分配,分配给托管标识 通过此设置,AzureFox 应能显示: - 来自 `whoami` 的订阅上下文 - 来自 `inventory` 的资源计数和资源类型 - 来自 `arm-deployments` 的部署历史立场和链接内容元数据 - 来自 `env-vars` 的管理平面应用设置暴露 - 来自 `tokens-credentials` 的跨应用、VM 和部署的相关令牌与凭证表面 - 来自 `rbac` 的提升角色分配可见性 - 来自 `principals` 的订阅可见主体普查 - 来自 `permissions` 的高影响角色分级 - 来自 `privesc` 的直接角色与公共身份提升线索 - 来自 `role-trusts` 的应用所有权、服务主体所有权、联合凭证与应用角色信任边 - 来自 `resource-trusts` 的存储与 Key Vault 暴露行 - 来自 `managed-identities` 的托管身份附加及高严重性发现 - 来自 `keyvault` 的 Key Vault 公共网络、私有端点与清除保护立场 - 来自 `storage` 的公共存储与开放防火墙发现 - 来自 `vms` 的公共虚拟机及其附加身份 - 来自 `vmss` 的一个内部虚拟机规模集足迹 - 来自 `nics` 的 NIC 附加与公共 IP 引用 - 来自 `endpoints` 的公共 IP 与 Azure 托管主机名可见性 - 来自 `network-ports` 的 NIC 支持的公共入口证据 - 来自 `workloads` 的联合计算与 Web 工作负载普查 - 来自 `app-services` 的应用服务主机名、身份与立场清单 - 来自 `functions` 的主机名、身份与部署信号清单 - 来自 `api-mgmt` 的 API 管理主机名、身份、订阅、命名值与后端深度 - 来自 `aks` 的 AKS 控制平面端点、代理池数量、OIDC 立场与插件可见性 - 来自 `acr` 的 ACR 登录服务器、管理员用户、Webhook、复制与策略立场 - 来自 `databases` 的 Azure SQL 端点、可见用户数据库清单与最小 TLS 立场 - 来自 `automation` 的 Azure Automation 账户身份与零对象执行立场 - 来自 `snapshots-disks` 的托管磁盘附加、网络访问与加密立场 - 来自 `lighthouse` 的委派管理证据(当订阅公开时) - 来自 `cross-tenant` 的跨租户信任证据(不将租户整体立场变为确定性行数) - 来自 `devops` 的 Azure DevOps 流水线证据(仅当配置了真实组织时) - 来自 `dns` 的 DNS 区域库存与私有端点支持的命名空间使用 - 可选的组合后续通过 AzureFox `chains` 系列进行更高层回顾 本仓库中 `auth-policies` 的处理方式略有不同: - 验证器会检查 AzureFox 是否准确报告了可读的租户身份验证元 - 验证器会明确记录权限拒绝或部分读取情况 - 本阶段不会修改租户范围的 Entra 身份验证策略状态 ## 警告 本实验室有意在 Azure 中创建高风险立场: - 公共 IP 暴露 - 公共 Blob 访问 - 订阅范围的 `Owner` RBAC 请使用专为测试设计的丢弃型订阅。不要部署到共享或 生产相关订阅。 本仓库可能部署一个不安全的 Azure 环境。您负责选择运行位置和方式,以及随之而来的任何成本、暴露、妥协、数据丢失或服务影响。 本仓库在此阶段不会更改租户范围的 Entra 身份验证控制。请保持此状态,除非团队明确决定增加的爆炸半径和回滚负担值得。 ## 先决条件 - [OpenTofu](https://opentofu.org/) 已安装并可用作 `tofu` - Azure CLI 已安装并可用作 `az` - 访问可处置的 Azure 订阅 - Python 3.11+ 用于 AzureFox CLI - 本地可用的 AzureFox 检出 - 在 Windows 10/11 上,建议使用内置 PowerShell 和 OpenSSH 客户端作为 shell/工具链 推荐的本地检查: ``` tofu version az version python3 --version ``` ## 认证到 Azure AzureFox 优先使用 Azure CLI 认证,因此请首先执行此操作: ``` az login az account set --subscription ``` OpenTofu 也会使用 Azure CLI 会话,除非您通过环境变量覆盖身份验证。 `tofu apply` 在部署历史记录盖章期间会使用本地的 `tofu`、`az` 和 `python3` 可执行文件。OpenTofu 会自动将所需值传递给辅助脚本,因此您无需手动设置额外环境变量。 以下示例使用 Bash(如有不同,PowerShell 等效命令会另行显示)。 ## 配置 复制示例变量文件并替换 SSH 公钥: ``` cp tofu.tfvars.example terraform.tfvars ``` ``` Copy-Item tofu.tfvars.example terraform.tfvars ``` 编辑 `terraform.tfvars` 并设置: - `ssh_public_key` 使用 RSA 公钥 - `name_prefix` 如需不同的全局唯一存储名称前缀 - 如需要,可覆盖 VM 规格 当前经过测试的备用默认值: - `location = "centralus"` - `vm_size = "Standard_D2s_v3"` - `vmss_sku = "Standard_D2s_v3"` 选择这些默认值的原因: - 较小的 B 系列及其他低成本 SKU 可能被新订阅或近期升级的订阅阻止(显示 `NotAvailableForSubscription`) - `Standard_D2s_v3` 在 `centralus` 已验证可用,且使用的系列在此订阅中具有非零默认配额 - 这是面向 POC 的备用配置,并非长期理想的成本配置 生成兼容的密钥对: ``` ssh-keygen -t rsa -b 4096 -f ~/.ssh/azurefox_lab_rsa -C "azurefox-lab" -N "" cat ~/.ssh/azurefox_lab_rsa.pub ``` ``` ssh-keygen -t rsa -b 4096 -f $HOME/.ssh/azurefox_lab_rsa -C "azurefox-lab" -N "" Get-Content $HOME/.ssh/azurefox_lab_rsa.pub ``` ## 部署 ``` tofu init tofu plan tofu apply ``` `tofu apply` 也会在链接模板工件存在后,通过一个小的 Azure CLI 辅助程序盖章 Phase 2 ARM 部署历史对象。它会创建一个成功的订阅级部署、一个成功的资源组部署和一个失败的资源组部署,以便 AzureFox 验证部署历史记录的覆盖情况。 应用后的有用输出: ``` tofu output subscription_id tofu output -json role_trusts_manifest tofu output -json validation_manifest ``` 如果更改了 `outputs.tf` 或清单期望,在重新运行验证之前,请刷新 OpenTofu 状态,以避免 `validation_manifest` 与当前分支不匹配: ``` tofu apply -refresh-only ``` ## 验证 AzureFox 对应的实验室 在首选环境中安装 AzureFox 包依赖项,然后运行: ``` python3 scripts/validate_azurefox_lab.py ``` 默认情况下,验证器会: - 读取 `tofu output -json validation_manifest` - 从 `--azurefox-dir` 执行 AzureFox - 以 `--mode full` 运行,执行当前发布门槛下的独立 AzureFox 命令集 - 将默认 `--mode full` 视为管理员证明路径 - 在每个 AzureFox 步骤前后打印进度行,包括耗时和输出目录 - 记录每个命令的 UTC 开始和结束时间戳及持续时间到 `command-timeline.json` - 将证明工件存储在 `proof-artifacts/latest` 现提供支持视角感知的验证: - `admin` 保持当前的发布门槛,应看到最完整的实验室真实情况 - `dev` 使用受限的工作负载 `Contributor` 服务主体,仍应返回有用的面向工作负载的输出,而无需订阅范围的真实情况 - `lower-privilege` 使用工作负载 `Reader` 服务主体,应返回诚实的部分可见性,而非误导性的空结果 缩减视角会故意运行更小的命令路径: - `whoami` - `principals` - `permissions` - `managed-identities` - `workloads` - `functions` 这些缩减路径用于证明在更窄立足点下的诚实行为,而不是替代管理员发布门槛。 若要获取更丰富的 `devops` 证明,请在运行验证器之前将 AzureFox 指向真实的 Azure DevOps 组织: ``` export AZUREFOX_DEVOPS_ORG= ``` 可选标志: ``` python3 scripts/validate_azurefox_lab.py \ --azurefox-dir /path/to/azurefox \ --artifacts-dir ./proof-artifacts/run-01 ``` 有用的范围限定重新运行: ``` python3 scripts/validate_azurefox_lab.py --mode commands-only python3 scripts/validate_azurefox_lab.py --mode full python3 scripts/validate_azurefox_lab.py --mode full --skip-command role-trusts python3 scripts/validate_azurefox_lab.py --mode commands-only --viewpoint dev python3 scripts/validate_azurefox_lab.py --mode commands-only --viewpoint lower-privilege python3 scripts/validate_azurefox_lab.py --viewpoint all ``` 运行时说明: - 使用 `--mode full` 作为端到端单次验证运行 - `commands-only` 现在是 `full` 命令系列的显式独立重新运行别名 - `--viewpoint admin` 是默认值,保持现有的发布门槛工件布局 - `--viewpoint dev` 和 `--viewpoint lower-privilege` 需要 `--mode commands-only`;它们使用敏感的 OpenTofu 输出以及隔离的 `AZURE_CONFIG_DIR` 会话,因此验证器不会覆盖操作员的主要 Azure CLI 登录 - `--viewpoint all` 会同时运行管理员路径和两个缩减路径,并将缩减路径工件存储在 `proof-artifacts/latest/viewpoints/` - 如果实验室已就绪且仅更改了输出或验证器期望,请在重新运行验证之前刷新 OpenTofu 状态,以避免因过时的 `validation_manifest` 数据导致误报不匹配 - 使用 `--mode commands-only` 当您只需要单个命令输出而不需要编排通过 - `role-trusts` 可能耗时较长,因为 Azure API 路径较慢;验证器现在会在该步骤期间输出周期性等待信息,而非显示挂起 - 在 `role-trusts` 首次验证后,重新运行可使用 `--skip-command role-trusts`,除非您更改了该切片或遇到指向它的阻塞问题 - Key Vault 替换在 `tofu apply` 期间可能耗时数分钟进入 Azure 软删除状态,然后重新创建完成;请将其视为已知缓慢路径,而非意外挂起 - 更一般地,请不要默认重新运行已知缓慢的验证路径;仅在确实需要时再执行 - 当变更的切片触及它、存在实时阻塞点,或团队明确需要额外证明时,才执行 - 使用 [docs/live-run-strategy.md](/Users/cfarley/Documents/Terraform Labs for AzureFox/docs/live-run-strategy.md) 作为完整运行与快速重新运行的策略规范 工件包括: - 每个 AzureFox 命令的一个 JSON 有效负载 - AzureFox 输出的副本(loot 文件) - `command-timeline.json` - `summary.json` - `summary.txt` - 当同时运行多个视角时,每个视角一个子文件夹,以及 `viewpoint-summary.json` 和 `viewpoint-summary.txt` - `azurefox-mismatch-report.md` - `identity-mismatch-report.md` 可选的 SOC/检测工件流程: - `command-timeline.json` 现在为每个 AzureFox 验证命令记录 UTC 开始和结束标记以及持续时间,以便分析师可将这些标记与 Azure 控制平面活动相关联 - 此时间戳工件仅覆盖验证器命令路径;请在需要时单独记录 `apply` 和 `destroy` 时间戳以获取完整实验室窗口 - 使用 [docs/activity-log-bundles.md](/Users/cfarley/Documents/Terraform Labs for AzureFox/docs/activity-log-bundles.md) 从本地提取 Azure 活动日志到整个实验室窗口,并与阶段标记和验证器命令标记一起打包 - 打包脚本为 [export_activity_log_bundle.py](/Users/cfarley/Documents/Terraform Labs for AzureFox/scripts/export_activity_log_bundle.py) ## 证据边界 本实验室用于验证 AzureFox 输出与实际 Azure 对象。它不是工具本身中清晰表述或基于证据的发现的替代。 AzureFox 可直接通过只读控制平面和 Graph 数据验证的内容: - 应用注册、服务主体、所有者边、联合凭证、应用角色分配或可读取 API 中的授权策略行是否存在 - 资源或身份是否可见,以及 AzureFox 如何对其进行汇总 - 当 Graph 返回权限或可见性错误时,策略表面是否部分不可读 - Key Vault 网络立场、私有端点存在与清除保护立场是否存在于管理元数据中 - 部署历史记录是否记录了输出、链接模板或参数 URI 以及失败状态元数据 - 应用服务与函数应用设置是否暴露了明文或 Vault 托管的配置路径 - 托管标识令牌表面是否在 Web 工作负载、VM 和部署历史记录中相关联 - Azure 托管的应用服务与函数应用主机名是否为可见控制平面端点路径,而非证明实时入口 - NIC 支持的公共入口证据是否来自可见的 NSG 允许规则,而非推测的可达性 - 存储、VMSS、自动化、API Management、AKS、ACR 和 Azure SQL 的深度是否保持基于证据,且仅凭管理元数据可见 - 当前 DNS 边界是否停留在区域库存和私有端点支持的命名空间使用上,而非记录导出或实时解析证明 - `lighthouse`、`cross-tenant` 和 `devops` 是否诚实地处理外部前提条件、租户形态或部分读取边界 仅实验室可确认的内容(一旦基础设施存在且验证器已运行): - RBAC 可见性是否足以让 AzureFox 提取预期的服务主体进入 `role-trusts` - 信任边是否在部署后存活并在实时租户中按预期显示 - AzureFox 表述是否偏离元数据实际证明的内容 - `tokens-credentials` 是否仍包含 Web 工作负载的身份标识(当该工作负载没有环境变量行时) - 组合的 `resource-trusts` 路径是否与存储和 Key Vault 的实时对象保持一致 - Key Vault 清除保护发现是否不包含在 `resource-trusts` 中 本阶段不测试的内容: - 来自外部颁发方的实时联邦令牌交换 - 通过真实登录流程执行的委托 OAuth 同意路径 - 租户范围的身份验证策略强制执行结果(如 Conditional Access 登录时的行为) - 通过运行工作负载实际检索 Key Vault 机密 - 工作负载本身的实时 IMDS 或托管标识令牌交换 - 私有端点从虚拟网络内的可访问性 - 记录内容、记录目标分析或实时 DNS 解析行为 ## 销毁 拆除实验室: ``` tofu destroy ``` 不要将本地 `tofu destroy` 退出视为最终真相。请先通过 Azure 确认已删除标记的实验室足迹,然后再宣布拆除完成: ``` az group list --query "[?tags.project=='azurefox-proof-lab'].{name:name,location:location,provisioningState:properties.provisioningState}" -o json az resource list --tag project=azurefox-proof-lab --query "[].{name:name,type:type,group:resourceGroup,location:location}" -o json ``` 如果任一查询仍返回实验室组或资源,请认为拆除不完整,并重试或 在关闭运行前清理剩余阻塞项。 ## Terraform 用户说明 如果您更习惯使用 Terraform,本实验室应该仍然熟悉: - 配置文件仍位于常规的 `.tf` 文件中 - 提供者配置使用 `hashicorp/azurerm` - 本地状态仍为 `terraform.tfstate` - 锁定文件仍为 `.terraform.lock.hcl` 需要注意的实际差异: - 运行 `tofu` 而非 `terraform` - 在 `tofu init` 后检查 `.terraform.lock.hcl` 变更 - 避免在相同状态上交替使用 `terraform` 和 `tofu`,除非团队明确支持该工作流 - 大多数 Azure 示例都基于 Terraform 风格,因此请仔细转换命令 ## 已知 OpenTofu 注意事项 - 工具链和 CI 作业需要调用 `tofu`,而非 `terraform` - 锁定文件名称仍为 `.terraform.lock.hcl`,熟悉但容易在审查时忽略 - 本地状态仍使用 `terraform.tfstate`,因此混合工具使用可能导致贡献者混淆(若未记录工作流) - 本 v1 实验室避免使用 OpenTofu 专属语言特性,以减少对 Terraform 用户的意外 - 如果实验室后续采用远程状态,请在与团队协商后端行为和工作流程后再标准化 ## 成本与容量说明 - 长期实验室形态倾向于在许可允许的情况下使用更低成本的 VM SKU - 某些新或近期升级的 Azure 订阅会返回 `NotAvailableForSubscription`,即使跨多个区域,小型 VM 系列也可能不可用 - 当前仓库默认使用 `Standard_D2s_v3`(位于 `centralus`),因为该组合已验证在此订阅中可部署 - 对于公开发布,请重新评估配额/SKU 访问权限,并在可能时改用更小的默认值 ## 发布准备 发布准备说明位于: - `VERSION` - `CHANGELOG.md` - `docs/release-process.md` - `docs/release-readiness-checklist.md` 使用这些文档保持可重复的发布决策。在此仓库中,发布准备主要关注 可部署性、验证质量、工件质量以及明确的配额或成本指导。发布标签 应镜像 AzureFox 的确切版本号。 ## 许可证 本仓库使用与主 AzureFox 项目相同的 MIT 许可证。请参见 [LICENSE](LICENSE)。
标签:ACR, AKS, API 管理, Azure, AzureFox, Azure 部署, CLI, DNS, EC2, ECS, IaC, Lighthouse, OpenTofu, PoC, RBAC, SEO: AzureFox 验证, SEO: Azure 实验室, SEO: OpenTofu 示例, SEO: 一次性订阅部署, Terraform, VMSS, WiFi技术, 一次性订阅, 代码分析, 凭证管理, 函数, 反取证, 取证, 可重复部署, 存储, 安全评估, 实验室环境, 密钥保管库, 应用服务, 快照与磁盘, 指标共享, 数据库, 暴力破解, 权限, 演示环境, 生成式AI安全, 网络, 网络调试, 自动化, 蓝军, 虚拟机, 覆盖范围, 角色信任, 资源发现, 跨租户, 逆向工具, 验证, 验证运行