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 ``` ## 📊 架构图 **整体系统布局**

High-level architecture diagram

**详细网络安全流向**

Detailed network security flow diagram

## 📁 组件文档 | 组件 | 位置 | 描述 | |---|---|---| | 前端 (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, 网络安全, 访问控制, 请求拦截, 逆向工具, 防火墙策略, 隐私保护