tbcsec/Flagpost

GitHub: tbcsec/Flagpost

Flagpost 是一个开箱即用、支持自托管和全程实时更新的开源 CTF 竞赛运行平台,帮助组织者高效管理从挑战发布到计分排名的完整赛事流程。

Stars: 3 | Forks: 0

Flagpost **一个现代的、开源的 Capture the Flag 竞赛运行平台 ——
支持自托管、实时更新,且功能完备。** [![License: AGPL v3](https://img.shields.io/badge/license-AGPL--3.0-2bbd7e.svg)](LICENSE) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/tbcsec/flagpost/actions/workflows/ci.yml) [![欢迎 PR](https://img.shields.io/badge/PRs-welcome-2bbd7e.svg)](CONTRIBUTING.md) ![Backend: FastAPI](https://img.shields.io/badge/backend-FastAPI-009688.svg) ![Frontend: Next.js](https://img.shields.io/badge/frontend-Next.js%2015-black.svg) [亮点](#-highlights) · [功能](#-features) · [快速开始](#-quick-start) · [部署](#-deploying-to-production) · [文档](#-documentation)
Flagpost 是一款为 CTF 组织者打造的完整竞赛平台:发布挑战、 在提交瞬间完成评分、支持参赛者,并实现整个赛事的自动化 —— 所有这些都集于一个可自托管的应用中。它从根本上支持多租户(一次 安装即可运行多场赛事),全程实时更新(使用 WebSockets,而非 轮询),并以一条命令的生产级技术栈开箱即用。 目前仅支持密码身份验证;SSO/LDAP 和 AI 助手已列入路线图,但 特意暂未开发。 ## ✨ 亮点 让 Flagpost 脱颖而出的特性 —— 每一项都**已在当下构建并正常运行**: - **⚡ 全程实时。** 计分板、“谁正在查看此挑战” 在线状态、通知和支持工单线程,所有这些均通过 WebSockets 实时更新。无需刷新,无需轮询。 - **🤖 可视化自动化引擎。** 零代码的 **When → If → Then** 规则构建器: 针对任意事件,执行操作 —— 发送通知、调用(经过 SSRF 加固的) webhook、发送电子邮件、 发布提示、解锁附加挑战、打开问卷、调整分数、颁发 奖项、冻结榜单或发布公告。包括基于时间的触发器, 例如*“在结束前一小时,打开反馈问卷。”* - **📝 实时协作笔记。** 真正的 CRDT (Y.js) 共同编辑:每个团队的每个挑战都有一个共享的草稿本, 每张工单上都有私密的内部人员笔记 —— 所有人都可以同时 输入,互不冲突。 - **🛡️ 权限即数据。** 非硬编码的 RBAC:可视化的角色编辑器 允许你克隆内置角色,并精细地创建具有每个赛事范围或全站范围的自定义角色。 - **🧩 真正深度的挑战模型。** 支持静态、正则表达式和多项选择题的 flag; 动态(衰减)计分;前置解锁链;定时/分批发布; 标签和难度;以及每个赛事的猜测限制。 - **🏆 完善的计分板。** 带有“一血”(first-blood)的实时排名,并行的 **分组/赛区**,最后阶段的**冻结**,公开的**观战 板**,以及 **CTFtime feed**,让评级赛事完美运行。 - **🔁 兼容 CTFd 且完全可移植。** 以 **ctfcli YAML** 格式批量导入/导出挑战,以及一键、高保真的**平台备份** (导出/导入你安装的任何部分)。 - **🔒 默认安全。** argon2 哈希,每次安装时自动派生的 JWT 密钥 (不含任何内置凭据 —— 首次运行的设置向导将创建你的所有者账户), 经过 SSRF 加固的 webhook,受 ReDoS 约束的正则表达式 flag,以及时间安全的身份验证。 - **🚀 一条命令投入生产。** `docker compose up` 会在单个源上通过 Caddy 反向代理拉起整个技术栈 —— 当你将其 指向一个域名时,会自动配置 HTTPS。 ## 📸 截图
Live scoreboard
Live scoreboard — real-time standings, first blood, brackets & freeze
Challenges
Challenges — cards, hints, live solves & flag submission
Automation builder
Automation builder — visual When → If → Then rules
Operational dashboard
Operational dashboard — drag-and-drop widgets for organisers
## 🧩 功能
**赛事** - 每场赛事支持团队**或**个人模式 - 公开/私有可见性 & 自助加入或通过邀请码加入 - 排期、**暂停**、归档以及一键**克隆** - 每个赛事的模块开关(开启/关闭功能) **挑战** - 分类、静态 / 正则表达式 / **多项选择**的 flag - **动态(衰减)**或静态计分 - 提示、文件附件 (S3/MinIO) - **前置解锁链**、定时发布 - 受管理的**标签与难度**词表 - 批量 **ctfcli YAML** 导入/导出 - 手动重置多项选择的猜测限制 **计分与计分板** - 通过 WebSocket 实时更新、**一血**标记 - **动态价值收敛**(对所有解题者保持公平) - **分组 / 赛区**、计分板**冻结** - 公开的**观战板** + **CTFtime feed** - 人工判定奖项与分数调整 **团队与参赛者** - 邀请码、可选的**队长审批**、人数上限 - 团队主页;个人模式下的名单及排名 **沟通与协作** - **支持工单**,带有实时的内部处理队列与提示音 - **公告**(实时横幅) - **在线状态** —— “N 人正在查看”、“裁判正在查看” - 关于挑战和工单的**CRDT 协作笔记** **自动化、反馈与洞察** - 可视化**自动化**规则构建器(§ 亮点) - **反馈问卷** + 解题后的**挑战评分** - **挑战与团队分析** - 带有拖拽小部件的运营**仪表板** **管理** - **用户**目录 + 软封禁 / 生命周期管理 - 数据驱动的**角色与权限**编辑器 - 全站**主题与品牌**(自定义 logo、调色板) - SMTP、注册策略、跨赛事**审计日志** - 完整的**导出 / 导入**备份(包括密钥)
## 🚀 快速开始 需要安装带有 Compose 的 [Docker](https://docs.docker.com/get-docker/)。默认的 技术栈适用于**生产环境**:在 Caddy 反向代理后运行构建好的镜像,并集成了 Postgres、 Redis 和 MinIO。 ``` git clone https://github.com/tbcsec/flagpost.git cd flagpost docker compose up --build ``` 打开 **http://localhost:8080** 并完成一次性的**设置向导**,以 创建你的所有者账户。就这样 —— 应用本身、其 API 以及其实时的 WebSocket 更新,都通过 Caddy 在同源下提供服务,因此在本地运行时无需再进行其他 配置。 ## 🌅 部署到生产环境 默认的 compose *即*生产技术栈,因此上线主要就是 在 `.env` 中进行配置(复制 `.env.example`): | 变量 | 作用 | |---|---| | `SITE_ADDRESS` | 你的域名,例如 `ctf.example.com`。Caddy 会**自动获取并续期 TLS**。映射端口 `80` + `443`。 | | `PUBLIC_ORIGIN` | 面向浏览器的源,例如 `https://ctf.example.com`。会在构建时嵌入到前端 —— 请在 `docker compose build` 之前设置好。 | | `JWT_SECRET` | 一串较长的随机值(多主机部署时必填;否则应用会自动派生并持久化一个)。 | | `POSTGRES_PASSWORD`, `MINIO_ROOT_USER/PASSWORD` | 真实的凭据。 | | `MINIO_PUBLIC_ENDPOINT` | 浏览器可访问的 MinIO 主机,用于带签名的附件下载。 | 后端在设计上以**单进程运行**(WebSocket 层 处于进程内)。要在**不使用 Docker** 的情况下运行:构建并托管前端,运行 `npm run build && npm run start`,并在你自己的 TLS 终结代理后,通过 `alembic upgrade head` 然后运行 `uvicorn main:app`(不要加 `--reload`)来运行后端。 ### 📌 带版本号的镜像(直接拉取而非构建) 每次发布标签都会向 GHCR 发布**锁定的、可复现的镜像**: ``` ghcr.io/tbcsec/flagpost-backend:v1.1.0 (also :latest) ghcr.io/tbcsec/flagpost-frontend:v1.1.0 (also :latest) ``` 已发布的前端是在**同源模式**下构建的 —— API 调用和 WebSockets 会自动解析为提供页面服务的任意源 —— 因此只需一个镜像,即可在任何同源代理后 运行,无需内置域名,也无需因为 `PUBLIC_ORIGIN` 而重新构建。将 compose 中的 `frontend`/`backend` 服务指向这些镜像 (只需两行覆盖配置),即可通过标签进行升级,而无需从源代码重新构建。 ## 🛠️ 本地开发 开发技术栈会挂载源代码并运行支持热重载的开发服务器: ``` docker compose -f docker-compose.dev.yml up --build # frontend → http://localhost:3000 · backend → http://localhost:8000/docs ``` 或者直接运行各端(后端需要 Python 3.12+ 和 venv;前端需要 Node 20+ —— 随包提供的镜像运行的是 3.14 和 26 版本,这也是 CI 测试的环境): ``` # 后端 cd backend && python3 -m venv .venv .venv/bin/pip install -r requirements-dev.txt .venv/bin/alembic upgrade head # against a reachable Postgres .venv/bin/uvicorn main:app --reload # 前端 cd frontend && npm install && npm run dev ``` 在提交 PR 之前,运行一下 CI 所执行的检查: ``` cd backend && .venv/bin/pytest # SQLite-backed, no infra needed cd frontend && npm run test # vitest cd frontend && npx tsc --noEmit && npx eslint . ``` ## 🧱 技术栈 **后端** —— Python · FastAPI · SQLAlchemy 2 (异步) · Alembic · PostgreSQL · Redis · MinIO/S3 · JWT + argon2 · 一流的异步事件总线。 **前端** —— TypeScript · Next.js 15 (App Router) · React 19 · TanStack Query · Zustand · Tailwind v4 · TipTap + Y.js (CRDT)。 **实时通信** —— 全面采用 WebSockets。**部署** —— Docker Compose + Caddy。 ## 📚 文档 | 文档 | 内容 | |---|---| | [`docs/VISION.md`](docs/VISION.md) | Flagpost 是什么及其存在的原因 | | [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | 绑定的技术设计 | | [`docs/ROADMAP.md`](docs/ROADMAP.md) | 构建顺序及后续规划 | | [`docs/adr/`](docs/adr/) | 架构决策记录 —— 解释事物*为什么*是现在的样子 | ## 📄 许可证 Copyright © 2026 **Tom Collier**. Flagpost 采用 **[GNU Affero General Public License v3.0](LICENSE)** 授权。 你可以自由使用、修改和自托管它;如果你将**修改后**的版本作为 网络服务运行,AGPL 的 §13 条款要求你向用户提供其源代码。内置的“Powered by Flagpost”页脚会将每个页面链接到本仓库,这 正是 Flagpost 向远程用户展示其源代码的方式。
为 CTF 社区而生。展起你的旗帜。 🚩
标签:AV绕过, CTF平台, FastAPI, WebSockets, 搜索引擎查询, 测试用例, 版权保护, 网络调试, 自动化, 逆向工具