基于 CTFd 与 Docker 搭建动态 CTF 竞赛靶场实战指南
前言
在网络安全竞赛(CTF)中,动态靶场能够提供隔离的、按需分配的实验环境,极大地提升了比赛的公平性和安全性。本文将以 CTFd 框架为基础,结合 Docker 技术,详细介绍如何从零开始搭建一个支持动态题目实例的 CTF 竞赛平台。我们将重点解决搭建过程中常见的环境冲突、配置错误及网络问题。
本文详细介绍了基于 CTFd 框架和 Docker 技术搭建动态 CTF 竞赛靶场的完整流程。内容涵盖 Ubuntu 环境准备、Docker 及 Docker-compose 安装、国内镜像源配置、CTFd 项目部署、Frp 内网穿透设置、Whale 插件配置以及动态题目的创建与测试。文章还补充了平台安全加固、数据库备份、性能调优及常见故障排查方案,旨在帮助技术人员高效构建稳定可靠的 CTF 竞赛基础设施。

在网络安全竞赛(CTF)中,动态靶场能够提供隔离的、按需分配的实验环境,极大地提升了比赛的公平性和安全性。本文将以 CTFd 框架为基础,结合 Docker 技术,详细介绍如何从零开始搭建一个支持动态题目实例的 CTF 竞赛平台。我们将重点解决搭建过程中常见的环境冲突、配置错误及网络问题。
推荐使用 Ubuntu 20.04 Server 版本。虽然 CentOS 也可用,但 SELinux 机制常与 Docker 容器权限产生冲突,排查难度较大,建议优先选择 Ubuntu。
注意:Python 3.6 与 pip 21.3 版本存在兼容性问题,可能导致依赖安装失败。如遇此情况,请升级 Python 或降级 pip 至兼容版本。
由于默认源位于海外,下载速度较慢,建议更换为阿里云、清华或中科大镜像源。
以阿里云源为例:
cp /etc/apt/sources.list /etc/apt/sources.list.bak
vim /etc/apt/sources.list
将内容替换为:
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
更新缓存:
apt-get update
依次安装 pip、git 和 curl:
apt-get install python3-pip git curl -y
pip3 install --upgrade pip
使用官方脚本快速安装:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
验证安装:
docker --version
pip3 install docker-compose -i https://pypi.tuna.tsinghua.edu.cn/simple
docker-compose --version
为避免拉取镜像过慢,建议配置 daocloud 和 aliyun 镜像加速器。
daocloud 配置: 访问 daocloud.io 获取 Linux 加速命令并执行。
阿里云配置: 登录阿里云控制台 -> 容器镜像服务 -> 镜像加速器,复制对应命令执行。
重启 Docker 服务使配置生效:
systemctl daemon-reload
systemctl restart docker
本项目基于 CTFd 框架,并集成了 ctfd-whale 插件以实现 Docker 动态靶机功能。
git clone https://github.com/Un1kTeam/CTFd --depth=1
cd CTFd
若无法直接拉取 GitHub 仓库,可尝试以下方法:
如需中文界面,可克隆汉化仓库并覆盖主目录:
git clone https://github.com/mcyydscc/CTFd_Chinese
cp -r CTFd_Chinese/* CTFd/
为了在公网访问本地服务的动态靶机,需配置 Frp。
编辑 frps.ini:
[common]
bind_port = 7000
vhost_http_port = 9123
token = your_token
# subdomain_host = node.vaala.ink
编辑 frpc.ini:
[common]
token = your_token
server_addr = 172.1.0.3
server_port = 7000
admin_addr = 172.1.0.4
admin_port = 7400
注意:确保
token一致,且server_addr指向正确的服务器 IP。
为解决超链接跳转问题,需修改 view.js 文件:
# 找到第 66 行附近,修改为
'<p class="card-text">' + response.user_access + '</p>' + '<p class="card-text"><a target="_blank" href="http://' + response.user_access + '">' + response.user_access + '</a>' + '</p>' +
编辑 docker-compose.yml,删除第 95 行和 102 行(具体视版本而定,通常涉及不必要的端口映射)。
创建单节点集群并添加标签:
docker swarm init
docker node update --label-add='name=linux-1' $(docker node ls -q)
进入项目目录并启动服务:
docker-compose up -d
等待构建完成,检查容器状态:
docker ps -a
浏览器访问 http://<服务器 IP>:9124,首次访问需进行管理员账号注册和数据库初始化。
进入后台管理页面,导航至插件设置中的 Whale 模块:
保存配置后点击 Submit 更新。
选择 dynamic_docker 类型题目,配置参数如下:
ctftraining/qwb_2019_supersqli)。创建完成后,点击 "Launch an instance" 启动题目实例。由于需要从 Docker Hub 拉取镜像,首次启动可能需要数分钟。启动成功后,点击链接即可进入题目环境。
定期备份 SQLite 或 PostgreSQL 数据库文件,防止数据丢失。
cp /var/lib/ctfd/data.db backup_data.db
开放必要端口(如 9124, 7000, 9123),限制其他端口的访问权限。
ufw allow 9124/tcp
ufw enable
生产环境建议使用 Nginx 反向代理并配置 SSL 证书,保障通信安全。
若并发用户较多,建议增加 Docker 容器的资源限制上限,并考虑使用 Redis 作为缓存后端以提升响应速度。
docker logs <container_id>,确认镜像是否存在或端口是否被占用。搭建 CTFd 动态靶场是一个涉及系统配置、网络调试及容器管理的综合过程。通过本文的步骤,您可以成功部署一套稳定的竞赛平台。随着经验的积累,您还可以进一步扩展插件功能、定制 UI 主题或实现自动化评分系统。希望本文能为您节省排查时间,助力网络安全竞赛的顺利开展。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online