penicili/ctf-proxmoxer

GitHub: penicili/ctf-proxmoxer

一个基于 FastAPI 和 Ansible 的 CTF 挑赛实例自动化部署后端,与 CTFd 集成,在 Proxmox VE 上为每支队伍按需创建和管理隔离的虚拟机环境。

Stars: 0 | Forks: 0

# CTF Proxmoxer 平台 用于通过 Proxmox VE 管理基于虚拟机的 CTF 挑赛的后端服务。与 CTFd 插件 [CTFd-proxmoxer-client](https://github.com/penicili/ctfd-proxmoxer-client) 配合使用 ## 架构 ``` flowchart TB subgraph CTFd["CTFd"] core["CTFd Core\n(Challenges, Teams, Flags)"] plugin["ctfd-proxmoxer-client\n(Plugin)"] plugin -- "baca/tulis data" --> core end plugin -- "HTTP REST API" --> backend subgraph Backend["ctf-proxmoxer (FastAPI Backend)"] backend["/api/v1/levels\n/api/v1/challenges"] end backend -- "Ansible (SSH)" --> builder backend -- "Ansible (SSH)" --> vms backend -- "Proxmox API" --> pve_api[("Proxmox VE")] subgraph PVE["Proxmox VE"] pve_api builder["Image Builder\n10.10.10.110\n(docker build + push)"] registry["Docker Registry\n10.10.10.5:5000"] vms["Challenge VMs\n(per tim)"] builder -- "push image" --> registry registry -- "pull image" --> vms end ``` ## 技术栈 - **后端**: Python, FastAPI - **数据库**: SQLite (via SQLAlchemy) - **虚拟化**: Proxmox VE (`proxmoxer`) - **自动化**: Ansible (`ansible-runner`) - **容器**: Docker, Docker Registry (`registry:2`) ## 安装 ``` git clone https://github.com/penicili/ctf-proxmoxer.git cd ctf-proxmoxer python -m venv .venv source .venv/bin/activate # Linux/Mac # .venv\Scripts\activate # Windows pip install -r requirements.txt cp .env.example .env # isi sesuai environment uvicorn app:app --host 0.0.0.0 --port 8000 --reload ``` ## 所需的基础设施设置 在使用后端之前,请确保在 Proxmox VE 中已准备好以下组件: | 组件 | 类型 | IP | 功能 | |---|---|---|---| | Base Template VM | QEMU Template | — | 作为所有 challenge VM 的克隆源 | | Docker Registry | LXC | 10.10.10.5 | 存储 challenge 的 Docker image | | Image Builder | QEMU VM | 10.10.10.110 | 构建并推送 challenge 的 Docker image | 所有组件均在内部网络 `vmbr1` (`10.10.10.0/24`) 中运行。 ## Challenge 创建指南 Challenge 以包含存在漏洞的 Web 应用程序的 Git repository 形式创建。后端会自动为参赛者构建、推送并将 challenge 部署到 VM 中。 ### Repository 结构 ``` challenge-repo/ ├── Dockerfile # build image aplikasi challenge ├── docker-compose.yml # wajib ada ├── public-images.txt # opsional, list image publik yang dibutuhkan └── app/ └── ... ``` ### 1. Dockerfile 构建 challenge 应用程序的 image。Flag 通过环境变量 `FLAG` 注入。 ``` FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["python", "app.py"] ``` 在应用程序内部,从环境中读取 flag: ``` import os FLAG = os.environ.get("FLAG", "CTF{placeholder}") ``` ### 2. docker-compose.yml 必须使用系统在部署时注入的环境变量 `REGISTRY_HOST`、`IMAGE_TAG` 和 `FLAG`。 **单服务:** ``` services: app: image: ${REGISTRY_HOST}/${IMAGE_TAG}:latest ports: - "80:5000" environment: - FLAG=${FLAG} ``` **多服务(以 MySQL 为例):** ``` services: app: image: ${REGISTRY_HOST}/${IMAGE_TAG}:latest ports: - "80:5000" environment: - FLAG=${FLAG} - DB_HOST=db depends_on: - db db: image: ${REGISTRY_HOST}/mysql:8 environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=challenge ``` ### 3. public-images.txt (可选) 如果 challenge 需要公共 image(MySQL、Redis 等),请在此文件中列出。系统将在准备阶段把此类 image 镜像同步到内部 registry,从而使部署不依赖互联网。 ``` mysql:8 redis:7-alpine ``` `docker-compose.yml` 中的公共 image 必须以 `${REGISTRY_HOST}/` 为前缀编写,以便从内部 registry 而不是 Docker Hub 拉取。 ## 系统流程 ### 准备阶段 管理员触发准备 → 后端在 Image Builder 上运行 Ansible: 1. `git clone` challenge repository 2. `docker build` 应用程序 image 3. `docker push` 到内部 registry (`10.10.10.5:5000`) 4. 将 `public-images.txt` 中的公共 image 镜像同步到 registry(如果有) 5. `level.template_url` 被设置为 image tag (`level-{id}`) ### 部署 Challenge 管理员为团队部署 challenge → 后端: 1. 在 Proxmox 中克隆 base template VM 2. 等待 VM 启动 + cloud-init(约 30 秒) 3. 在 PVE 主机上设置 iptables 端口转发 4. Ansible 通过 SSH 连接到 VM(通过 PVE 的 ProxyJump): - `git clone` challenge repo(用于获取 `docker-compose.yml`) - 写入包含 `FLAG`、`REGISTRY_HOST`、`IMAGE_TAG` 的 `.env` 文件 - `docker compose up -d --pull always` 5. Challenge 状态 → `RUNNING` 6. 通过 API 在 CTFd 中创建 challenge 条目 + flag ### 终止 Challenge 管理员终止 → 后端: 1. 运行 `post_challenge.yml`(在 VM 中清理) 2. 删除 iptables 端口转发规则 3. 在 Proxmox 中停止 VM ## 环境变量 请查看 `.env.example` 获取完整列表。重要变量: | 变量 | 说明 | |---|---| | `PROXMOX_HOST` | Proxmox VE 的 IP | | `TEMPLATE_VMID` | base template VM 的 VMID | | `REGISTRY_HOST` | 内部 Docker Registry 的 Host:port | | `CI_RUNNER_IP` | Image Builder VM 的 IP | | `CTFD_URL` | CTFd 实例的 URL | | `CTFD_API_TOKEN` | 用于完成 challenge 的 CTFd API token | | `SSH_KEY_PATH` | 用于访问 PVE 和 VM 的 SSH key 路径 | | `VM_SSH_USERNAME` | challenge VM 中的 cloud-init 用户名 |
标签:Ansible, AV绕过, Docker, FastAPI, 安全防御评估, 系统提示词, 自动化运维, 虚拟化, 请求拦截, 逆向工具