lakatostomi/network-security-on-gcp
GitHub: lakatostomi/network-security-on-gcp
该项目是一个基于 GCP 的网络安全概念验证平台,使用 Terraform 构建完整的安全基础设施并通过交互式 Web UI 展示各项云安全控制的实际效果。
Stars: 0 | Forks: 0
# 🌐 Google Cloud 网络安全概念验证
**一个用于在 GCP 上演示现代云网络安全控制的端到端实操环境。**
该项目使用 Terraform 在两个 GCP 项目中配置了一个完整的、贴近生产环境的**网络安全 PoC**,并通过交互式的 **Streamlit Web UI** 展示每一项安全控制。它被设计为一个教学和演示平台——所有组件都被连接在一起,因此通过 UI 触发的安全事件可以立即在真实的基础设施日志中观察到。
## 📖 本项目演示的内容
| 安全领域 | GCP 功能 |
|---|---|
| 边界防御 | Cloud Armor (WAF, 速率限制, 地域封锁) |
| 网络分段 | 通过 VPC peering 实现的 Hub-and-spoke VPC 拓扑 |
| 基于身份的防火墙 | 带有安全标签的层级和区域防火墙策略 |
| 威胁情报拦截 | Google Threat Intelligence (Tor, 恶意 IP, 挖矿程序) |
| 安全出口 | 带有 TLS 检查和 URL 过滤的 Secure Web Proxy |
| 私有服务连接 | 带有 NEG 的 Private Service Connect (PSC) |
| 访问控制执行 | VPC Service Controls (资源边界) |
| 入侵检测 | 带有数据包镜像的 Cloud IDS (Palo Alto Networks) |
| 跨项目日志聚合 | 文件夹级日志接收器 → Pub/Sub |
| 安全 CI/CD | 带有 Workload Identity Federation 的 GitLab CI (无密钥认证) |
## 🗂️ 仓库结构
```
net_sec_poc_project/
│
├── infra/ # Terraform IaC — provisions all GCP resources
│ ├── locals.tf # Subnet ranges, IPs, region, zone, tag role sets
│ ├── variables.tf # Input variables (project IDs, org, policy IDs, etc.)
│ ├── provider.tf # Google Cloud provider configuration
│ ├── backend.tf # Terraform remote state (GCS)
│ ├── main.tf # Cloud Run, Serverless VPC Connector, Cloud Build trigger
│ ├── network.tf # Load balancers: Internal ALB (dev), PSC NEG ILB (hub), ext LBs
│ ├── vpcs.tf # VPCs + subnets + peering to dev/test/mgmt + Cloud NATs
│ ├── net-fw-policies.tf # Hierarchical + regional firewall policies, address groups
│ ├── cloud-armour.tf # Cloud Armor security policy (WAF, rate limit, geo-block)
│ ├── swp.tf # Secure Web Proxy + Private CA + TLS inspection config
│ ├── ids.tf # Cloud IDS endpoint + packet mirroring policy
│ ├── psc.tf # PSC NEG Internal ALB (hub → mgmt)
│ ├── instances.tf # Compute Engine VMs: backend-app, mock-api, IDS test, GTI test
│ ├── dns.tf # Private DNS zones: googleapis.com, dev.netservices.com, hub peering
│ ├── tags.tf # Secure tags for firewall policy targeting
│ ├── iam.tf # Service accounts + IAM bindings + custom CA role
│ ├── service_control.tf # VPC SC perimeters + access levels + ingress/egress policies
│ ├── log_sink.tf # Folder-level log sink → Pub/Sub topic
│ ├── storage.tf # GCS buckets (secret data, startup scripts) + Artifact Registry
│ └── versions.tf # Terraform and provider version constraints
│
├── frontend/ # Streamlit demo UI (deployed to Cloud Run)
├── backend/ # FastAPI backend app (Compute Engine MIG, dev-vpc)
├── mock-api/ # FastAPI mock database/API (Compute Engine, mgmt-vpc)
├── ids-demo/ # FastAPI app for Cloud IDS traffic mirroring target (test-vpc)
├── architecture_1.svg # High-level architecture diagram
├── architecture_2.svg # Detailed network security flow diagram
└── .gitlab-ci.yml # GitLab CI/CD pipeline (WIF auth, Terraform plan/apply/destroy)
```
## 🏗️ 架构
### 项目与 VPC 拓扑
该 PoC 在单个文件夹内的**两个 GCP 项目**中展开,使用通过 VPC peering 连接的 **hub-and-spoke 拓扑**。每个 spoke 都是隔离的——spoke 之间的流量必须通过 hub 传输。
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ PROJECT DEV │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ dev-vpc │ │ hub-vpc │ │ mgmt-vpc │ │
│ │ 10.1.1.0/24 │◀────▶│ 10.0.1.0/24 │◀────▶│ 10.3.1.0/24 │ │
│ │ │ │ │ │ │ │
│ │ Cloud Run (ST) │ │ PSC NEG ILB │ │ Mock API VM │ │
│ │ Backend App VM │ │ 10.0.1.10 │ │ Secure Web Proxy│ │
│ │ Int. ALB (L7) │ │ (hub-vpc DNS) │ │ 10.3.1.10 │ │
│ │ 10.1.1.10 │ │ │ │ PSC Producer LB │ │
│ │ (dev DNS) │ │ │ │ │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
│ │
│ Pub/Sub topic ← Folder log sink (firewall, LB, VPC SC, IDS logs) │
│ GCS buckets: startup scripts, secret data (VPC SC protected) │
│ Artifact Registry: Docker images for Cloud Run │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ PROJECT TEST [VPC Service Controls perimeter] │
│ │
│ ┌──────────────────┐ │
│ │ test-vpc │ │
│ │ 10.2.1.0/24 │ │
│ │ │ │
│ │ Cloud IDS app │──packet mirror──▶ Cloud IDS endpoint │
│ │ GTI test VM │ (Palo Alto NGFW) │
│ │ Ext. ALB (L7) │ │
│ │ Cloud NAT │ │
│ └──────────────────┘ │
│ │
│ GCS bucket: netsec-top-secret-data-bucket (restricted to LIST/GET only) │
│ Log sink → Pub/Sub in Project Dev (via approved VPC SC egress policy) │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 端到端请求流
```
Browser
└─▶ External ALB [dev-vpc]
└─▶ Cloud Run (Streamlit) [dev-vpc]
└─▶ Serverless VPC Connector (10.1.2.0/28) [dev-vpc]
└─▶ Internal ALB L7 — app.dev.netservices.com (10.1.1.10) [dev-vpc]
└─▶ Cloud Armor WAF (attached to backend service)
└─▶ Backend App VM (FastAPI) [dev-vpc]
└─▶ Internal ALB L7 — pscneg.hub.netservices.com [hub-vpc]
└─▶ PSC NEG
└─▶ PSC Producer (Internal Passthrough LB) [mgmt-vpc]
└─▶ Mock API VM (FastAPI) [mgmt-vpc]
└─▶ Secure Web Proxy (10.3.1.10) [mgmt-vpc]
└─▶ example.com (external SaaS)
```
## ⚙️ 基础设施详情
### 网络
启用了 Private Google Access 的**四个 VPC**,以及用于 L7 负载均衡器的专用纯代理子网:
| VPC | 子网 | 角色 |
|---|---|---|
| `dev-vpc` | `10.1.1.0/24` | 前端 Cloud Run,后端应用虚拟机,内部 ALB |
| `hub-vpc` | `10.0.1.0/24` | PSC NEG 端点,共享服务 hub |
| `mgmt-vpc` | `10.3.1.0/24` | 模拟 API 虚拟机,Secure Web Proxy,PSC 生产者 |
| `test-vpc` | `10.2.1.0/24` | Cloud IDS 目标,GTI 测试虚拟机,外部 ALB |
每个 spoke 都通过 **VPC peering** 连接到 hub。DNS peering 确保 `dev-vpc` 可以通过 hub 解析 `hub.netservices.com` 记录。**Cloud NAT** 部署在 `dev-vpc`、`mgmt-vpc` 和 `test-vpc` 中,用于虚拟机软件更新——应用程序出口流量完全且仅使用 Secure Web Proxy。
**私有 DNS 区域:**
- `dev.netservices.com` → `app.dev.netservices.com` → 位于 `10.1.1.10` 的内部 ALB
- `hub.netservices.com` → `pscneg.hub.netservices.com` → 位于 `10.0.1.10` 的 PSC NEG ILB
- `googleapis.com` (`dev-vpc` 中的私有区域) → `private.googleapis.com`
- `googleapis.com` (`test-vpc` 中的受限区域) → `restricted.googleapis.com`
### 防火墙策略
**层级策略** (文件夹级,适用于两个项目):
| 规则 | 优先级 | 操作 | 描述 |
|---|---|---|---|
| `deny-gti-tor` | 99 | 拒绝 + 记录日志 | 阻断所有 Tor 出口节点流量 |
| `deny-gti` | 100 | 拒绝 | 阻断已知的恶意 IP、加密挖矿程序、匿名代理 |
| `allow-iap-ssh` | 1001 | 允许 | 允许来自 `35.235.240.0/20` 的 IAP SSH |
| `allow-all-hc-ranges` | 1000 | 允许 | 允许 GCP 健康检查 IP 范围 |
| `goto-next-all-internal` | 1002 | 转至下一级 | 将内部 `10.0.0.0/14` 流量传递给 VPC 级别策略 |
| `goto_next-mirrored-vm` | 1005 | 转至下一级 | 将所有 TCP 流量传递给数据包镜像实例 |
| `allow-vm-updates` | 65330 | 允许 (出口) | 基于 FQDN 的允许:Debian 软件库、PyPI、Google 软件包 |
| `deny-all-ingress` | 65334 | 拒绝 | 默认拒绝所有剩余的入口流量 |
**区域策略** (dev, hub, mgmt VPC) — 基于标签:
- 到 `app-tier` 标签的入口流量:允许来自纯代理子网 (ILB 后端流量)
- 到 `mock-api` 标签的入口流量:允许来自 PSC 子网
- 来自 `mock-api` 标签的出口流量:仅允许发往 `example.com:443` (FQDN 规则)
- 到内部地址组 (`10.0.0.0/14` 聚合) 的出口流量:允许全部
**区域测试策略** (仅限 test-vpc):
- 到 `packet-mirrored` 标签的入口流量:允许来自 `0.0.0.0/0` 的 TCP 8080 端口 (IDS 目标虚拟机)
### Cloud Armor
区域后端安全策略 (`app-security-policy`) 附加到 `dev-vpc` 中的内部 ALB 后端服务,以保护后端应用程序:
| 规则 | 优先级 | 操作 | 详情 |
|---|---|---|---|
| 拒绝非 GET 方法 | 100 | `deny(403)` | 仅允许 `GET` 请求 |
| XSS (OWASP CRS v3.3) | 1000 | `deny(404)` | 敏感度级别 2,排除了两条规则 |
| SQLi (OWASP CRS v3.3) | 2000 | `deny(403)` | 敏感度级别 3 |
| 基于速率的封禁 | 3000 | `deny(429)` | 每个 IP 每 60 秒 10 次请求;每 300 秒 1000 次请求后封禁 60 秒 |
| 地域封锁 US | 4000 | `deny(502)` | 阻断所有来自 `region_code == "US"` 的流量 |
### Secure Web Proxy
SWP 位于 `mgmt-vpc` 中的 `10.3.1.10`,作为应用程序流量离开 `mgmt-vpc` 的**唯一出口路径**。它由**私有 CA** (`netsec-ca`,RSA 2048,1 年有效期) 提供支持,并对出站连接执行 **TLS 检查**。
策略规则:标记为 `mock-api` 的流量只能向 `example.com` 发出 `GET` 请求。所有其他出口流量默认都被阻断。
### Private Service Connect
`mgmt-vpc` 中的 Mock API 作为 **PSC 生产者**,通过带有服务附件的内部透传负载均衡器对外暴露。hub-vpc 通过由内部 ALB (L7) 支持的 **PSC NEG** 来使用它,使得该服务可以从任何已建立 peering 的 VPC 中通过 `pscneg.hub.netservices.com` 寻址——而无需通往 `mgmt-vpc` 的直接网络路径。
### Cloud IDS
Cloud IDS 部署在 `project-test` 中,使用建立 peering 的服务网络范围 (`/24`)。**数据包镜像策略**将来自标记为 `cloud-ids` 虚拟机的所有 TCP 流量 (双向) 复制到 IDS 端点的内部转发规则。IDS 严重性阈值设置为 `INFORMATIONAL`,可捕获所有级别的检测结果。
`cloud-ids-test-vm` (运行 `ids-demo/main.py`) 和 `gti-test-vm` (运行 Apache) 都被添加了标签并进行了镜像。**外部区域 ALB** 将 IDS 测试应用公开暴露,以便触发检测。
### VPC Service Controls
定义了三种访问级别:
- `corporate_access` — 基于 IP,用于企业网络 IP 范围
- `my_user_access` — 基于身份,用于管理员用户账号
- `gitlab_cicd_access` — 基于 IP,用于 GitLab CI runner IP 范围
**`dev-project` 边界:** 将 `iaptunnel.googleapis.com` 限制为仅限企业访问。
**`test-project` 边界** (更严格):限制 `storage.googleapis.com`、`pubsub.googleapis.com` 和 `iaptunnel.googleapis.com`。允许:
- **入口:** 来自 Project Dev 的 `backend-app-sa` 和 `frontend-app-sa` 只能调用 `storage.objects.list` 和 `storage.objects.get` — **不能**调用 `storage.objects.create`
- **出口:** 文件夹级日志记录服务账号可以发布到 Project Dev 中的 Pub/Sub topic
- **入口 (部署):** 来自 GitLab CI IP 范围的 GitLab 模拟 SA,可以调用任何 API 进行部署
这创造了一个可以直接演示的对比效果:列出 GCS bucket 会成功,但上传文件会被边界阻断,即使服务账号拥有 IAM 权限。
### 日志记录与可观测性
**文件夹级日志接收器** (`my-log-sink`) 将两个项目的过滤后的日志导出到 Project Dev 中的 `logging_topic` Pub/Sub topic。过滤器捕获:
- 防火墙策略允许/拒绝事件
- Cloud Load Balancing 日志条目
- VPC Service Control 违规事件
- Cloud IDS 端点检测结果
前端应用的日志查看器会从 `test-pull` 订阅中拉取最多 20 条消息,并将它们渲染为可折叠的 JSON 条目,在显示后确认消息。
### Compute Engine 实例
| 虚拟机 | VPC | 类型 | 用途 |
|---|---|---|---|
| `backend-app-vm` | dev-vpc | `e2-micro` | FastAPI 应用;通过 PSC 将请求转发给 Mock API |
| `mock-api-vm` | mgmt-vpc | `e2-micro` | FastAPI 模拟数据库;通过 Secure Web Proxy 流出 |
| `cloud-ids-test-vm` | test-vpc | `e2-micro` | IDS 流量目标;已被数据包镜像 |
| `gti-test-vm` | test-vpc | `e2-micro` | Apache 服务器;用于测试 GTI Tor 阻断 |
### 服务账号
| 服务账号 | 项目 | 角色 | 用途 |
|---|---|---|---|
| `dev-app-sa` | dev | `storage.objectUser`, `run.invoker` | 后端应用虚拟机 |
| `dev-run-sa` | dev | `artifactregistry.reader`, `pubsub.subscriber` | Cloud Run 前端 |
| `mock-api-sa` | dev | `storage.objectUser`, 自定义 CA 读取者 | Mock API 虚拟机 |
| `cloudbuild-sa` | dev | `logging.logWriter`, `artifactregistry.writer` | Cloud Build |
| `test-vm-sa` | test | `storage.objectUser` | IDS + GTI 测试虚拟机 |
## 🚀 CI/CD 流水线 (GitLab)
`.gitlab-ci.yml` 定义了一个使用 **Workload Identity Federation** 的**六阶段流水线** — GitLab 中不存储长期有效的服务账号密钥:
| 阶段 | 作业 | 描述 |
|---|---|---|
| `gcp_auth` | `gcp_auth` | 通过 WIF 将 GitLab OIDC token 交换为 GCP 凭据 |
| `tf_files` | `tf_files` | 从 GCS 下载 `terraform.tfvars.json` |
| `validate` | `fmt`, `validate` | `terraform fmt` 和 `terraform validate` |
| `plan` | `plan` | `terraform plan`,输出保存为 artifact |
| `deploy` | `deploy` | `terraform apply` (人工门禁) |
| `destroy` | `destroy` | `terraform destroy` (人工门禁,仅执行 destroy 操作) |
该流水线仅在从 `web` 或 `trigger` 来源推送到默认分支时触发。`ACTION` 变量 (`apply` / `destroy`) 控制哪些阶段。
该流水线在配置有 **Kubernetes executor 并托管在 GKE 上**的自定义 **GitLab runner** 上执行作业。该 runner 是使用 **Helm Charts** 配置的,该 runner 的公开仓库可以在[`这里`](https://github.com/lakatostomi/gitlab_runner_with_gke)找到!
## 📋 前置条件
- 位于共享**文件夹**内的两个 GCP 项目
- 用于 VPC Service Controls 的 GCP **Access Policy** (组织级)
- Terraform `>= 1.7.4`
- Google provider `~> 6.x`
- 配置了 Workload Identity Federation 的 GitLab 仓库
- 用于 Terraform 远程状态和 `terraform.tfvars.json` 的 GCS bucket
- 在两个项目中均启用以下 API:Compute Engine, Cloud Run, Cloud Build, Artifact Registry, Cloud IDS, Network Security, Certificate Authority Service, VPC Access, DNS, Secret Manager, Pub/Sub, Cloud Storage, Service Networking, IAP
## 🔧 部署
**1. 配置 Terraform 变量**
创建一个 `terraform.tfvars.json` (存储在 GCS 中,由 CI 拉取),内容如下:
```
{
"project_id": "your-dev-project-id",
"project_num": "123456789",
"test_project_id": "your-test-project-id",
"org_id": "your-org-id",
"policy_id": "your-vpc-sc-access-policy-id",
"my_user_account": "user@example.com",
"corp_range": ["203.0.113.0/24"],
"impersonate_sa": "gitlab-ci-sa@your-dev-project.iam.gserviceaccount.com",
"runner_ranges": ["34.1.123.234"]
}
```
**2. 通过 GitLab CI 部署 (推荐)**
使用 `ACTION = apply` 触发流水线。在审查 plan 之后,`deploy` 阶段需要经过人工审批门禁。
**3. 本地部署**
```
cd infra/
terraform init
terraform plan -var-file="terraform.tfvars.json"
terraform apply -var-file="terraform.tfvars.json"
```
**4. 构建并部署前端**
Cloud Build 触发器 (`st-app-trigger`) 会在推送到前端仓库的 `main` 分支时自动构建并推送 `st_fe_app:latest`。如需手动构建:
```
cd frontend/
docker build --platform linux/amd64 \
-t europe-west1-docker.pkg.dev/PROJECT_ID/frontend/st_fe_app:latest .
docker push europe-west1-docker.pkg.dev/PROJECT_ID/frontend/st_fe_app:latest
```
## 📊 架构图
**整体系统布局**
**详细网络安全流向**
## 📁 组件文档
| 组件 | 位置 | 描述 |
|---|---|---|
| 前端 (Streamlit) | [`frontend/README.md`](frontend/README.md) | 交互式演示 UI,功能拆解,本地开发指南 |
| 基础设施 | [`infra/`](infra/) | 所有 Terraform 模块和资源定义 |
| 后端 API | [`backend/main.py`](backend/main.py) | 通过 PSC 将请求转发给 Mock API 的 FastAPI 服务 |
| Mock API | [`mock-api/main.py`](mock-api/main.py) | 通过 Secure Web Proxy 发起 SaaS 调用的 FastAPI 服务 |
| IDS 演示应用 | [`ids-demo/main.py`](ids-demo/main.py) | 作为 Cloud IDS 数据包镜像目标的最小化 FastAPI 应用 |
标签:ECS, GCP, Kubernetes, Streamlit, Terraform, WAF, 网络安全, 访问控制, 请求拦截, 逆向工具, 防火墙策略, 隐私保护