fortidz/xperts_threat_hunting
GitHub: fortidz/xperts_threat_hunting
基于 Terraform 的 Azure 威胁狩猎实验室一键部署方案,集成 FortiGate 防火墙、FortiAnalyzer 日志分析及模拟工作负载,实现从基础设施到安全策略的全自动化配置。
Stars: 0 | Forks: 0
# Xperts Threat Hunting Lab — Azure 基础设施
Xperts Threat Hunting 实验室环境在 Azure 上的 Terraform 部署方案。部署 FortiGate NVA、FortiAnalyzer、模拟工作负载 VM 以及日志归档存储账户——所有资源均位于单个资源组和双子网虚拟网络中。FortiGate 设备配置(防火墙策略、VPN、安全配置文件、日志记录)通过 `fortios` Terraform provider 进行管理。
## 架构
```
Internet
│
▼
┌─────────────────────────────────────────────────────────┐
│ Resource Group: │
│ │
│ threathunt-vnet (192.168.27.0/24) │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ snet-external 192.168.27.0/27 │ │
│ │ NSG: Allow 443 10443 80 622 541 8080 / Deny-All │ │
│ │ │ │
│ │ ┌─────────────────┐ ┌─────────────────────┐ │ │
│ │ │ DL-FG (port1) │ │ DL-FAZ │ │ │
│ │ │ Static IP │ │ Static IP │ │ │
│ │ │ DL-FG-PIP ──► │ │ DL-FAZ-PIP ──► │ │ │
│ │ └────────┬────────┘ └─────────────────────┘ │ │
│ └───────────│────────────────────────────────────┘ │
│ │ (FortiGate port2) │
│ ┌───────────▼────────────────────────────────────┐ │
│ │ snet-internal 192.168.27.32/27 │ │
│ │ NSG: Allow 22 / Deny-All │ │
│ │ UDR: 0.0.0.0/0 → fortigate_port2_ip │ │
│ │ │ │
│ │ ┌─────────────────┐ │ │
│ │ │ watchtower │ 192.168.27.37 │ │
│ │ │ Ubuntu 24.04 │ │ │
│ │ └─────────────────┘ │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ Storage Account: sdatalake │
│ Container: fazdatalake (accessible from snet-external)│
└─────────────────────────────────────────────────────────┘
```
**流量走向**:来自 `snet-internal` 的所有出站流量在到达互联网或其他子网之前,通过 UDR 经由 FortiGate port2 路由。FortiAnalyzer 收集 FortiGate 日志并将其归档到 Blob Storage 容器中。
## 前置条件
| 工具 | 最低版本 |
|------|----------------|
| Terraform | 1.5+ |
| AzureRM provider | ~> 4.0 |
| fortios provider | ~> 1.22 |
| Azure CLI | 2.x (用于认证) |
### Azure Marketplace 条款
FortiGate 和 FortiAnalyzer 属于 Marketplace 镜像。部署前需针对**每个订阅**接受一次条款:
```
# FortiGate
az vm image terms accept \
--publisher fortinet \
--offer fortinet_fortigate-vm_v5 \
--plan fortinet_fg-vm
# FortiAnalyzer
az vm image terms accept \
--publisher fortinet \
--offer fortinet-fortianalyzer \
--plan fortinet-fortianalyzer
```
### 认证
```
az login
az account set --subscription ""
```
### SSL 证书
FortiGate 管理 GUI 使用 Let's Encrypt 通配符证书(`*.sxroomec.net`)提供服务。部署前,请将证书文件复制到 `certs/` 目录:
```
cp /path/to/sxroomec.net/fullchain.pem certs/
cp /path/to/sxroomec.net/privkey.pem certs/
cp /path/to/sxroomec.net/chain.pem certs/
```
`certs/` 目录已被 git 忽略——私钥绝不能被提交。
## 快速开始
### 第一阶段 — Azure 基础设施
```
# 1. 克隆并进入 repo
git clone https://github.com/fortidz/xperts_threat_hunting.git
cd xperts_threat_hunting
# 2. 复制示例 vars 并填写值
cp terraform.tfvars.example terraform.tfvars
$EDITOR terraform.tfvars
# 3. 放置 SSL 证书
mkdir -p certs
cp /path/to/sxroomec.net/{fullchain,privkey,chain}.pem certs/
# 4. 将敏感值设置为 env variables(推荐 — 避免将 secrets 写入磁盘)
export TF_VAR_admin_password="YourStr0ng!Pass"
export TF_VAR_fortiflex_fgt_token="FGT_TOKEN" # optional
export TF_VAR_fortiflex_faz_token="FAZ_TOKEN" # optional
export TF_VAR_fortigate_api_token="API_TOKEN"
export TF_VAR_ipsec_psk="YourPSK"
export TF_VAR_vpnuser1_password="VpnUser1Pass!"
export TF_VAR_guest_password="GuestPass!"
# 5. 初始化、规划、应用
terraform init
terraform plan -out=tfplan
terraform apply tfplan
```
### 第二阶段 — FortiGate 配置
Azure 基础设施部署完成且 FortiGate VM 启动后:
1. 确保 DNS `dl-fg-.sxroomec.net` 解析到 FortiGate 公网 IP
2. 在 FortiGate 上创建 REST API admin token (System > Administrators > REST API Admin)
3. 在 `terraform.tfvars` 中设置 `fortigate_api_hostname`(例如 `dl-fg-01.sxroomec.net:10443`)
4. 再次运行 `terraform apply`——`fortios` provider 将配置该设备
## 变量
### 基础设施
| 变量 | 必填 | 默认值 | 描述 |
|---|---|---|---|
| `resource_group_name` | yes | — | Azure Resource Group 名称 |
| `location` | no | `eastus` | Azure 区域 |
| `admin_username` | no | `datalake` | 所有 VM 的管理员用户名 |
| `admin_password` | yes | — | 管理员密码(敏感) |
| `fortigate_port1_ip` | yes | — | FortiGate port1 静态 IP (snet-external, .1–.30) |
| `fortigate_port2_ip` | yes | — | FortiGate port2 静态 IP (snet-internal, .36–.62) |
| `fortianalyzer_ip` | yes | — | FortiAnalyzer 静态 IP (snet-external, .1–.30) |
| `deploy_date` | yes | — | 存储账户的 8 位日期前缀 (YYYYMMDD) |
| `fortigate_image_version` | no | `7.6.6` | FortiOS 镜像版本 |
| `fortianalyzer_image_version` | no | `7.6.6` | FortiAnalyzer 镜像版本 |
| `fortiflex_fgt_token` | no | `""` | FortiGate 的 FortiFlex token(敏感) |
| `fortiflex_faz_token` | no | `""` | FortiAnalyzer 的 FortiFlex token(敏感) |
| `tags` | no | `{}` | 所有资源的额外标签 |
### FortiGate 配置 (fortios provider)
| 变量 | 必填 | 默认值 | 描述 |
|---|---|---|---|
| `fortigate_api_hostname` | yes | — | FortiGate API FQDN (`dl-fg-.sxroomec.net:10443`) |
| `fortigate_api_token` | yes | — | REST API token(敏感) |
| `ipsec_psk` | yes | — | IPsec VPN 预共享密钥(敏感) |
| `vpnuser1_password` | yes | — | VPN 用户 `vpnuser1` 的密码(敏感) |
| `guest_password` | yes | — | 本地用户 `guest` 的密码(敏感) |
## 关键输出
| 输出 | 描述 |
|---|---|
| `fortigate_public_ip` | FortiGate 管理 / VPN 公网 IP |
| `fortigate_management_url` | `https://` |
| `fortigate_port1_private_ip` | FortiGate 内部 port1 IP (snet-external) |
| `fortigate_port2_private_ip` | FortiGate 内部 port2 IP (snet-internal / UDR 下一跳) |
| `fortianalyzer_public_ip` | FortiAnalyzer 公网 IP |
| `fortianalyzer_private_ip` | FortiAnalyzer 私网 IP |
| `watchtower_private_ip` | 工作负载 VM 私网 IP (应为 192.168.27.37) |
| `storage_account_name` | 解析后的存储账户名称 |
| `deployment_summary` | 所有已部署资源的结构化摘要 |
```
terraform output fortigate_management_url
terraform output deployment_summary
```
## 文件结构
```
xperts_threat_hunting/
├── SPEC.md # Azure architecture specification
├── SPEC_fortigate_config.md # FortiGate configuration deployment spec
├── README.md # This file
├── versions.tf # Terraform + AzureRM + fortios provider version pins
├── variables.tf # All input variables with validation
├── outputs.tf # All outputs organized by resource type
├── terraform.tfvars.example # Example values (no secrets)
├── .gitignore # Excludes .tfvars, state, .terraform/, certs/
│
├── locals_constants.tf # Named constants — ports, CIDRs, SKUs, names
├── locals_common.tf # Shared resource_group_name, location, tags
├── locals_network.tf # VNet, subnet, NSG, UDR configuration maps
├── locals_compute.tf # Public IP, NIC, VM configuration maps
├── locals_storage.tf # Storage account and container configuration
├── locals_fortigate.tf # FortiGate config values (system, firewall, VPN, etc.)
│
├── resource_resource_group.tf # Azure Resource Group
├── resource_virtual_network.tf # VNet + Subnets
├── resource_security_group.tf # NSGs + subnet associations
├── resource_route_table.tf # Route tables (UDR) + subnet associations
├── resource_public_ip.tf # Public IPs (DL-FG-PIP, DL-FAZ-PIP)
├── resource_network_interface.tf # NICs for all VMs
├── resource_virtual_machine.tf # FortiGate, FortiAnalyzer, watchtower VMs
├── resource_storage.tf # Storage account + blob container
│
├── resource_fortigate_system.tf # FortiGate global settings, DNS, password policy
├── resource_fortigate_interface.tf # FortiGate port1/port2 interface config
├── resource_fortigate_router.tf # FortiGate static routes
├── resource_fortigate_address.tf # Firewall address objects + groups
├── resource_fortigate_service.tf # Firewall service groups
├── resource_fortigate_user.tf # Local users + user groups
├── resource_fortigate_vpn.tf # IPsec VPN phase1 + phase2
├── resource_fortigate_security.tf # IPS sensor, app-ctrl, webfilter profiles
├── resource_fortigate_policy.tf # Firewall policies, VIP/DNAT, local-in policy
├── resource_fortigate_log.tf # FortiAnalyzer logging configuration
│
├── certs/ # SSL certificates (git-ignored)
│ ├── fullchain.pem # Server cert + intermediate chain
│ ├── privkey.pem # Private key
│ └── chain.pem # Let's Encrypt intermediate CA
│
└── cloud-init/
├── fortigate.tpl # Bootstrap: license, SSL certs, admin-server-cert
└── fortianalyzer.tpl # Bootstrap: hostname + FortiFlex license
```
## FortiGate 配置概述
`fortios` provider 管理完整的 FortiGate 设备配置:
| 类别 | 资源 |
|----------|-----------|
| **System** | 全局设置 (hostname, admin-sport 10443, admin-server-cert), DNS, 密码策略, 访问配置文件 |
| **SSL Certificates** | 启动时注入的 Let's Encrypt 通配符证书 (`*.sxroomec.net`),用于管理 GUI TLS |
| **Interfaces** | port1 (external), port2 (internal) 含静态 IP 和访问控制 |
| **Routing** | 经由 port1 的默认路由,经由 port2 的内部子网路由 |
| **Firewall Objects** | 地址对象 (ipmask, iprange, FQDN), 地址组, 服务组 |
| **Firewall Policies** | 5 条策略: 互联网访问, 远程访问 (SSH DNAT), IPsec-to-LAN, LAN-to-IPsec, IPsec-to-Internet |
| **VIP/DNAT** | WATCHTOWER_DNAT — port1:622 映射到 watchtower:22 |
| **Security Profiles** | IPS (仅监控), app-ctrl (监控所有), webfilter (监控所有) |
| **IPsec VPN** | 远程访问拨号 (IKEv2, AES256-SHA256, EAP, mode-cfg 池 10.10.100.0/24) |
| **Users** | 本地用户 (guest, vpnuser1), 用户组 (RA_IPSEC_USERS) |
| **Logging** | FortiAnalyzer 集成 (实时上传, 可靠传输) |
| **Local-In Policy** | 阻断来自 Tor 出口/中继节点和恶意服务器的入站流量 |
完整配置规范请参阅 `SPEC_fortigate_config.md`。
## FortiFlex 许可
当通过 Fortinet 私有优惠 (FortiFlex) 部署 BYOL 时,请提供 token 以便 VM 跳过交互式 FortiCloud 注册:
```
export TF_VAR_fortiflex_fgt_token="XXXXXXXXXXXXXXXX"
export TF_VAR_fortiflex_faz_token="YYYYYYYYYYYYYYYY"
```
该 token 通过 multipart/mixed MIME 启动脚本经 `custom_data` 注入。如果 token 留空,VM 仍会部署,但首次启动后需要手动授权。
## 故障排除
**部署后无法访问 FortiGate**
- 验证 `fortigate_port1_ip` 位于 `snet-external` 范围内(`192.168.27.1–.30`)
- 检查 NSG `nsg-snet-external` 是否允许端口 443 和 10443
- FortiGate 首次启动可能需要 5–10 分钟;请通过串口控制台监控
**fortios provider 连接错误**
- 确保 DNS `dl-fg-.sxroomec.net` 解析到 FortiGate 公网 IP
- 验证 REST API token 有效且具有正确的管理员配置文件
- 确认 `certs/` 目录中存在 SSL 证书文件(fullchain.pem, privkey.pem, chain.pem)
- 检查端口 10443 是否可达(优先级 105 的 NSG Allow-Admin-HTTPS 规则)
**fortios provider 上的 TLS 证书验证错误**
- `fortios` provider 使用 `insecure = false`——需要与主机名匹配的有效证书
- 验证 `fortigate_api_hostname` 中的 FQDN 与证书 SAN(`*.sxroomec.net`)匹配
- 确保 `certs/` 中的证书文件是最新的(Let's Encrypt 证书每 90 天过期)
**工作负载 VM 无法访问互联网**
- 确认 `fortigate_port2_ip` 与 `terraform output` 中显示的实际 port2 IP 一致
- 验证 UDR `rt-snet-internal` 已关联到 `snet-internal`
- 确保 FortiGate 具有允许 snet-internal 流量的默认路由策略
**存储账户访问被拒绝**
- FortiAnalyzer 必须位于 `snet-external` 以满足存储网络规则
- `snet-external` 上必须启用 `Microsoft.Storage` 服务端点(由 Terraform 处理)
**`terraform apply` 时 Marketplace 镜像错误**
- 运行前置条件中列出的 `az vm image terms accept` 命令
- 条款每个订阅只需接受一次,而非每次部署
## FortiCNAPP
FortiCNAPP 集成已**推迟**——将在后续阶段进行规划和实施。本次部署中不配置 FortiCNAPP 相关资源。
标签:Azure, Azure 虚拟网络, EC2, ECS, FortiAnalyzer, FortiGate, IaaS, IaC, Terraform, TGT, 安全模拟, 安全策略管理, 安全运营, 实验室环境, 扫描框架, 攻防演练, 日志归档, 特权提升, 网络安全, 网络架构, 网络虚拟设备 (NVA), 自动化部署, 资源部署, 防火墙配置, 隐私保护