BabsBBG/project-citadel

GitHub: BabsBBG/project-citadel

以虚构金融公司 Nexus Financial Services 为场景,在 Azure 免费层上端到端构建一套涵盖身份、网络、计算、存储、机密、日志、态势管理、SIEM 检测、事件响应与合规策略的安全云环境实施方案。

Stars: 1 | Forks: 0

# Citadel 项目 ### 具备监控与威胁检测功能的安全 Azure 云环境 **客户:** Nexus Financial Services(虚拟) | **工程师:** Tobi Babalola ## 概述 Citadel 项目是一个为 Nexus Financial Services(一家正在建立其首个安全云环境的虚构中型金融科技公司)构建的端到端 Azure 云安全实施方案。该项目涵盖了云安全的各个层面:身份、网络、计算、存储、机密管理、日志记录、威胁检测、事件响应、合规执行以及基础设施即代码。 该项目旨在反映真实的安全工程决策,以理解每项控制措施存在的理由以及缺少它们可能导致的后果。默认实施最小权限原则,采用身份优先架构,推行持续合规而非单点时间加固,并包含从检测到遏制、完整的 SOC 风格事件响应工作流。 ** --- ## 架构 ``` ┌─────────────────────────────────────────────┐ │ NEXUS FINANCIAL SERVICES │ │ Azure Subscription │ └─────────────────────────────────────────────┘ │ ┌────────────────────▼────────────────────────┐ │ Citadel-RG │ │ Region: West US 2 │ └─────────────────────────────────────────────┘ │ ┌───────────────────────────────┼────────────────────────────┐ │ │ │ ┌────────▼─────────┐ ┌─────────▼────────┐ ┌─────────▼────────┐ │ IDENTITY LAYER │ │ NETWORK LAYER │ │ SECRETS LAYER │ │ │ │ │ │ │ │ Entra ID │ │ Citadel-VNet │ │ Citadel-KV-0 │ │ Abigail Analyst │ │ 10.0.0.0/16 │ │ Key Vault │ │ SecurityTeam │ │ │ │ Managed Identity│ │ RBAC: Reader │ │ PublicSubnet │ │ Access Policies │ │ MFA: Enabled │ │ 10.0.1.0/24 │ └──────────────────┘ └──────────────────┘ │ │ │ PrivateSubnet │ │ 10.0.2.0/24 │ │ │ │ Citadel-NSG │ │ Allow SSH: MyIP │ │ Deny: All │ └────────┬─────────┘ │ ┌────────▼─────────┐ │ COMPUTE LAYER │ │ │ │ Citadel-VM │ │ Ubuntu 24.04 │ │ SSH Key Auth │ │ Root: Disabled │ │ Passwd: Off │ └────────┬─────────┘ │ ┌──────────────────▼──────────────────────────┐ │ STORAGE LAYER │ │ │ │ citadelstore │ citadel-data container │ │ TLS 1.2 │ Private Access Only │ │ HTTPS Only │ Entra ID Auth │ │ No Public Blob │ No Key Access │ └──────────────────┬──────────────────────────┘ │ ┌──────────────────▼──────────────────────────┐ │ VISIBILITY LAYER │ │ │ │ Citadel-LAW │ │ Log Analytics Workspace │ │ │ │ VM Logs (AMA) │ Storage Diag Settings │ │ Syslog (DCR) │ Azure Activity Logs │ │ auth/authpriv │ Heartbeat Alerts │ └──────────────────┬──────────────────────────┘ │ ┌─────────────────────────────┼──────────────────────────┐ │ │ │ ┌────────▼──────────┐ ┌──────────▼──────────┐ ┌──────────▼──────────┐ │ POSTURE LAYER │ │ DETECTION LAYER │ │ COMPLIANCE LAYER │ │ │ │ │ │ │ │ Defender for │ │ Microsoft Sentinel │ │ Azure Policy │ │ Cloud │ │ │ │ │ │ Foundational │ │ Azure Activity │ │ SecureTransfer │ │ CSPM │ │ Connector │ │ NetworkAccess │ │ │ │ KQL Detection Rule │ │ PublicAccess │ │ 50/63 controls │ │ Failed Login Alert │ │ All: Audit Mode │ │ 0 Critical │ │ Threshold: 3 hits │ │ │ │ 0 High findings │ │ Window: 5 minutes │ │ Scope: Citadel-RG │ └───────────────────┘ └──────────────────────┘ └─────────────────────┘ ``` Citadel-RG ## 构建内容 | 层级 | 服务 | 配置 | |-------|---------|---------------| | 身份 | Entra ID | 用户、组、RBAC、MFA | | 网络 | Virtual Network | VNet、子网、NSG 规则 | | 计算 | Virtual Machine | Ubuntu 24.04、SSH 密钥、加固 | | 存储 | Storage Account | 专用、HTTPS、Entra ID 认证 | | 机密 | Key Vault | 托管标识、访问策略 | | 日志记录 | Log Analytics | AMA、DCR、诊断设置 | | 警报 | Azure Monitor | 心跳警报规则 | | 安全态势 | Defender for Cloud | 基础 CSPM,50/63 项控制 | | SIEM | Microsoft Sentinel | Azure Activity 连接器,KQL 规则 | | 合规性 | Azure Policy | 3 项策略,审计模式 | | IaC | ARM Template | 完整的 RG 导出 | ## 实施说明 ### 模块 1 — 身份与访问管理 **目标:** 在部署任何资源之前强制实施最小权限和强身份验证。 在 Entra ID 中创建了一个非管理员用户 `abigail.analyst`,日常操作绝不应在全局管理员账户下运行。将其分配至 `SecurityTeam` 组,以实现基于角色的规模化访问管理。在订阅级别分配了 `Reader` RBAC 角色 —— 默认为只读,任何写入操作都需要显式授权。为所有非管理员账户启用了 MFA。 **核心原则:** 身份是新的边界。每一个访问决策都流经 Entra ID。 MFA enabled for Abigail Analyst ### 模块 2 — 网络安全 **目标:** 对环境进行网络分段并显式控制所有流量。 构建了包含公用子网和专用子网的 `Citadel-VNet`,因为具有不同信任级别的工作负载永远不应共享同一个网段。部署了带有两条入站规则的 `Citadel-NSG`: - `Allow-SSH-MyIP`(优先级 100) - 仅允许来自工程师 IP 的 SSH - `Deny-All-Inbound`(优先级 200) - 阻断其他所有流量 将此 NSG 关联到 `Citadel-PublicSubnet`。任何流量如果不显式通过这些规则,都无法到达 VM。 ### 模块 3 — VM 部署与加固 **目标:** 在安全的网络边界内部署计算资源并减少攻击面。 在 `Citadel-PublicSubnet` 内部署了 `Citadel-VM`(Ubuntu 24.04 LTS,Standard_B1s)。在部署时强制使用 SSH 密钥身份验证 —— 从未启用过密码身份验证。 部署后的加固: ``` # 禁用 root 登录 sudo sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config # 禁用密码认证 sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config # 应用更改 sudo systemctl restart ssh # 验证 sudo grep -E "PermitRootLogin|PasswordAuthentication" /etc/ssh/sshd_config ``` **结果:** `PermitRootLogin no` | `PasswordAuthentication no` ### 模块 4 — 存储安全 **目标:** 消除最常见的云存储错误配置。 在创建存储账户时强制执行了四项安全控制: | 控制 | 设置 | 原因 | |---------|---------|-----| | 安全传输 | 已启用 | 强制使用 HTTPS,禁止明文 HTTP | | Blob 公共访问 | 已禁用 | 任何容器都不允许匿名读取 | | 存储账户密钥访问 | 已禁用 | 消除共享密钥身份验证,强制使用 Entra ID | | 最低 TLS 版本 | 1.2 | 阻止已弃用的 TLS 1.0/1.1 | **验证:** 上传文件至 `citadel-data` 容器后,尝试直接通过 URL 访问 —— 返回 `PublicAccessNotPermitted`。 Browser - PublicAccessNotPermitted error on blob URL ### 模块 5 — 机密管理 (Key Vault) **目标:** 使用托管标识消除计算资源中的硬编码凭证。 使用保管库访问策略权限模型创建了 `Citadel-KV-0`。存储了一个模拟的生产机密: ``` Name: NovaPay-DB-ConnectionString Value: Server=nexusfinancial-db.postgres.database.azure.com;Database=novapayprod;User=dbadmin;Password=Citadel@2026! Type: database/connection-string ``` 在 `Citadel-VM` 上启用了系统分配的托管标识。授予了 Key Vault 访问策略 —— 仅对机密具有 `Get` 和 `List` 权限。没有其他权限。最小权限原则应用于机密访问。 **概念验证 - 零硬编码凭证从 VM 检索机密:** ``` az login --identity az keyvault secret show --vault-name Citadel-KV-0 --name NovaPay-DB-ConnectionString --query value -o tsv ``` **输出:** `Server=nexusfinancial-db.postgres.database.azure.com;Database=novapayprod;User=dbadmin;Password=Citadel@2026!` Terminal — secret value retrieved showing full connection string **链路:** VM → 托管标识 (MSI) → Azure AD Token → Key Vault 访问策略 → 返回机密。VM 上任何地方都没有存储密码。 ### 模块 6 — 日志记录与监控 **目标:** 在叠加威胁检测功能之前,建立对环境的完整可见性。 创建了 `Citadel-LAW` Log Analytics Workspace,作为所有资源的集中日志目标。 **VM 日志收集:** - 通过 Azure Monitor Agent 在 Monitoring → Logs 将 VM 连接到工作区 - 创建了 `Citadel-DCR-Syslog` 数据收集规则,针对 LOG_DEBUG 级别的 `auth` 和 `authpriv` Syslog 设施 **存储日志收集:** - 在 blob 服务上启用了诊断设置 - StorageRead、StorageWrite、StorageDelete → `Citadel-LAW` **警报:** - 创建了 `Citadel-Alert-VMHeartbeat` - 当 VM 停止向工作区发送心跳信号时触发 Log analytics — syslog facility count — authpriv 18, auth 6 ### 模块 7 — 云安全态势 (Defender for Cloud) **目标:** 根据安全最佳实践对环境进行持续自动化评估。 在订阅上启用了基础 CSPM(免费层)。评估完成后: | 指标 | 结果 | |--------|--------| | 已评估资源 | 6 | | 严重发现 | 0 | | 高危发现 | 0 | | MCSB 控制通过数 | 50/63 | | 合规领域 | NS, IM, PA, DP, AM, LT, IR, PV, ES, BR, DS, GS | **Defender 识别出的已知缺陷(未来改进点):** - 未在 VM 上配置 Azure Backup - 未针对高严重性警报启用电子邮件通知 - 未启用 Azure Disk Encryption - 未部署漏洞评估解决方案 - 未安装 Guest Attestation 扩展 这些已被刻意记录下来 Regulatory compliance — 5063 controls passed ### 模块 8 — SIEM (Microsoft Sentinel) **目标:** 在日志记录管道之上构建 SOC 级别的检测和警报。 部署了 Sentinel 并连接到 `Citadel-LAW`。 **数据连接器 — Azure Activity:** 通过 Azure Policy 分配向导进行连接 - 将所有订阅级别的活动日志流式传输到工作区。 **检测规则 — 失败的登录尝试:** ``` AzureActivity | where OperationNameValue contains "signin" or ActivityStatusValue == "Failed" | where TimeGenerated > ago(5m) | summarize FailedAttempts = count() by CallerIpAddress, Caller | where FailedAttempts >= 3 ``` - 严重性:中等 - 评估频率:每 5 分钟 - 事件创建:已启用 Analytics rule citadel-rule-failedlogins overview incident simulation-response ### 模块 9 — 事件模拟与响应 **目标:** 端到端验证完整的检测管道,并演示 SOC 响应工作流。 #### 攻击模拟 使用一个不存在的密钥文件对 `Citadel-VM` 执行了 15 次 SSH 暴力破解尝试: ``` for ($i=1; $i -le 15; $i++) { ssh -i "wrongkey.pem" -o StrictHostKeyChecking=no -o ConnectTimeout=5 azureuser@20.3.20.191 Start-Sleep -Seconds 2 } ``` **结果:** 15 × `Permission denied (publickey)` - 连接尝试已记录在 VM 上。 #### 调查 — VM 端 ``` sudo journalctl -u ssh --since "1 hour ago" | tail -20 ``` **发现:** 在 systemd journal 的 preauth 阶段确认了来自 `197.210.52.203` 的全部 15 次连接重置。 #### 调查 — Log Analytics ``` Syslog | where Facility == "auth" or Facility == "authpriv" | where TimeGenerated > ago(1h) | where SyslogMessage contains "197.210.52.203" | project TimeGenerated, Facility, SyslogMessage | order by TimeGenerated desc ``` **发现:** 在 Log Analytics 中确认了攻击者 IP `197.210.52.203` - 会话事件通过云端日志管道进行了追踪。 #### MITRE ATT&CK 映射 | 战术 | 技术 | ID | 观察到的活动 | |--------|-----------|-----|---------| | 初始访问 | 暴力破解:密码猜测 | T1110.001 | 来自单一 IP 的 15 次失败 SSH 尝试 | | 初始访问 | 有效账户 | T1078 | 攻击者针对已知账户 `azureuser` | | 发现 | 网络服务发现 | T1046 | 在定位端口 22 之前隐含了侦察行为 | | 防御规避 | 使用备用身份验证材料 | T1550 | 尝试绕过公钥认证 | | 初始访问 | 利用面向公众的应用程序 | T1190 | 推荐使用 Azure Bastion,已记录为已知缺陷 | #### 遏制响应 添加了阻断攻击者 IP 的 NSG 入站拒绝规则: | 规则 | 优先级 | 源 IP | 操作 | |------|----------|-----------|--------| | Allow-SSH-MyIP | 100 | 工程师 IP | 允许 | | Deny-Attacker-IP | 105 | 197.210.52.203 | 拒绝 | | Deny-All-Inbound | 200 | 任意 | 拒绝 | **结果:** 攻击者 IP 已在网络层被阻断。后续的连接尝试将在到达 VM 之前被丢弃。 Terminal — journalctl showing connection reset from 197 210 52 203 NSG inbound rules — all three rules including Deny-Attacker-IP at 105 ### 模块 10 — 合规执行 (Azure Policy) **目标:** 将一次性手动加固转变为持续的自动化合规。 将三项内置策略分配给 `Citadel-RG` 范围,并设为审计模式: | 策略 | 分配名称 | 强制执行的内容 | |--------|----------------|------------------| | 应启用安全传输到存储账户 | Citadel-Policy-SecureTransfer | 所有存储强制仅使用 HTTPS | | 存储账户应限制网络访问 | Citadel-Policy-NetworkAccess | 禁止无限制的网络访问 | | 应禁止存储账户公共访问 | Citadel-Policy-StoragePublicAccess | 禁止匿名 blob 访问 | **为何采用审计模式:** 在生产环境中,应从审计模式开始以获取可见性,然后再切换为拒绝模式。在活跃环境中直接切换为拒绝模式可能会破坏现有的不合规资源Policy assignments — all three citadel policies listed scoped to Citadel-rg ### 模块 11 — 基础设施即代码 (ARM Template) **目标:** 使整个环境可复现,而不仅仅是文档化。 通过 Portal → Resource Groups → Export template 将 `Citadel-RG` 导出为 ARM 模板。 **输出:** - `template.json` — 完整的环境定义 - `parameters.json` — 用于重新部署的参数化值 Portal 还生成了相同基础设施的 **Bicep** 版本,这两种格式均可在 `/arm-template` 目录中找到。 ## 仓库结构 ``` project-citadel/ ├── README.md ├── arm-template/ │ ├── template.json │ └── parameters.json ├── screenshots/ │ ├── 01-identity/ │ ├── 02-network/ │ ├── 03-vm-hardening/ │ ├── 04-storage/ │ ├── 05-key-vault/ │ ├── 06-logging/ │ ├── 07-defender/ │ ├── 08-sentinel/ │ ├── 09-incident-response/ │ ├── 10-azure-policy/ │ └── 11-arm-template/ └── incident-report/ └── citadel-incident-report.md ``` ## 关键经验与问题 | 问题 | 根本原因 | 解决方案 | |-------|-----------|-----| | East US 中的 vCPU 配额限制 | 免费层订阅限制 | 在 West US 2 中重新构建了所有内容 | | 找不到 `sshd` 服务 | Ubuntu 24.04 使用 `ssh` 而不是 `sshd` | `sudo systemctl restart ssh` | | 禁用密钥访问后 Portal 被阻止 | 存储上没有 Entra ID 角色 | 通过 IAM 分配了 Storage Blob Data Contributor | | 内容中心重定向到 Defender portal | Microsoft 将其永久迁移 | 使用 defender.microsoft.com 作为内容中心 | | Azure Activity 连接器上的修复任务失败 | `Microsoft.PolicyInsights` 未注册 | 手动注册提供程序并创建了任务 | | Ubuntu 24.04 上的 Syslog 为空 | 从 syslog 迁移到了 systemd journal | 使用 `journalctl -u ssh` 进行 VM 端调查 | | 缺少旧版代理管理 | 已从较新的工作区中移除 | 改用数据收集规则 (DCR) | | 托管标识 token 终结点无响应 | VM 已解除分配,连接丢失 | 重启 VM,重新安装 Azure CLI | ## 展示的技能 - Azure 身份与访问管理(Entra ID、RBAC、MFA) - 网络分段与流量控制(VNet、NSG) - Linux 服务器加固(SSH、sshd_config) - 云存储安全(访问控制、Entra ID 认证) - 机密管理(Key Vault、托管标识) - 日志摄取与管道配置(AMA、DCR、诊断设置) - 云安全态势管理(Defender for Cloud、MCSB) - SIEM 配置与 KQL 检测工程(Microsoft Sentinel) - 事件模拟、日志调查与遏制响应 - 合规策略执行(Azure Policy) - 基础设施即代码(ARM 模板、Bicep、Terraform 导出) - MITRE ATT&CK 框架映射 *Project Citadel — Nexus Financial Services | 基于 Microsoft Azure 免费层构建*
标签:AMSI绕过, Azure, 云迁移, 威胁检测, 子域名变形, 安全合规, 安全工程, 安全日志, 安全架构, 持续合规, 端到端安全, 网络代理, 网络安全, 网络安全审计, 身份与访问管理, 金融科技, 隐私保护, 零信任架构