CTFd 踩坑
由于团队新开了 CTF 方向,为了方便后面进行队内训练和比赛,还是打算自己建一个 CTF 答题平台,不能受制于人,外界太不稳定了。看到 buuoj 用的是 CTFd 其他几个网址好像长得也差不多,索性就把这个项目搭起来试试。
搭建
这里有两种方式,一种是 git pull 下来自己 build docker 镜像,另外一种就是直接从 docker hub 拉取下来。
git 自建
首先把仓库 pull 下来
git clone https://github.com/CTFd/CTFd.git
然后需要修改一下 Dockerfile
,把 apt 和 pip 的源换成中国的
RUN sed -i s/deb.debian.org/mirrors.aliyun.com/g /etc/apt/sources.list && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
RUN pip config set global.index-url http://mirrors.aliyun.com/pypi/simple && pip config set install.trusted-host mirrors.aliyun.com
然后不知道为什么一直跑不起来,说找不到 entrypoint 的那个 bash 脚本
很打脑壳,但是我单独 docker build 之后进去看明明又是有这个文件的
很迷惑。
然后我又把 Dockerfile 里面的 ENTRYPOINT 写成了 ["/bin/bash", "/opt/CTFd/docker-entrypoint.sh"]
,结果又提示 invalid option nameypoint.sh: line 2: set: pipefail
,搜到是编码问题,于是 dos2unix 处理了一下居然就成功了,ENTRYPOINT 改回 ["/opt/CTFd/docker-entrypoint.sh"]
也能运行了,万万没想到这个问题他会直接跟你说 file not found。
之后就能正常跑起来了,由于后面在安装 CTFd-Whale 的时候发现它不能支持 3.x 的 CTFd,所以又跑回来 checkout 到了最新的 2.x,2.5.0。这个时候就又有一个坑了,requirements.txt 要改:
jinja2==2.10.1
markupsafe==2.0.1
gevent==21.12.0
flask_apscheduler==1.11.0
前两行要加上去,两个 gevent 要改新,还有一个是给 CTFd-Whale 准备的。另外就是 2.5.0 的 CTFd 的 Dockerfile 是基于 python:3.7-alpine 的,所以在改源的时候应该用下面这一行:
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
最后一个要改的地方还是在 Dockerfile 里面,ENTRYPOINT 要改为:
ENTRYPOINT ["/bin/sh", "/opt/CTFd/docker-entrypoint.sh"]
docker hub
没什么好说的,直接写 docker-compose 配置文件即可。
CTFd-Whale
没有这个插件就只能有类似 misc 类型的题目,因为原生 CTFd 只有个文件上传和下载,就像这种
有了 CTFd-Whale 之后就能在答题的时候一键创建并开启容器,就像下面这样
架构
CTFd-Whale 的架构相对而言还是比较复杂的,除了 CTFd 本身和 mysql、redis 之外,还要有创建、维护题目容器的部分
安装
在 CTFd/CTFd/plugins
文件夹下解压或 clone CTFD-Whale 的仓库,但是无论如何都是下面这个样子
后来发现这里不能用赵师傅的原版,他似乎已经弃坑了,并不能适配 3.x 的 CTFd,看到有人 fork 维护了另外一个 仓库 说是能用,但是我尝试之后发现还是一样的,可能是 CTFd 后面又 breaking change 了吧。看样子只能被迫用老版本的 CTFd 了。
坑
- 安装完成之后发现它的 renew 并不会重新 pull 更新 image,只有在 destroy 之后重新打开一个环境才会更新。
- 设置里面的
Frp config template
更改后会直接改变 frpc 里面的 frpc.ini,而且就算把文件改了也没用,只有到数据库里面改才会生效,因为 CTFd-Whale 会循环通过 frp 的 api 同步配置。