前言
参考资料
新版CTFd-Whale使用指南 - frankli0324
准备阶段
首先,服务器中需要已经安装 docker 和 docker-compose:
docker 安装可以参照官方文档:Install Docker Engine on Debian | Docker Documentation
docker-compose 安装直接 sudo apt install docker-compose
即可。
技术原理
主要技术:frp(fast reverse proxy),使 docker 容器中的内部网络穿透到外部网络中。
Frps服务:运行在服务器上的服务,用于将 frpc 的流量向外转发。
文档中使用的是 frps 容器,容器的做法需要一直启用题目的端口映射,当没有题目开启时会造成端口的浪费,而且修改端口范围时需要重启容器,本文沿用了旧版本 CTF 平台部署时使用的 frps 服务。
Frpc容器:与靶机容器同处在一个 docker 网络下,用于将靶机的流量发送到 frps
CTFd-Whale:作为 CTFd 的一个插件,它的作用是调用 docker 的接口生成独立的靶机容器,同时控制 frpc 接口转发靶机端口。
安装步骤
启动CTFd
创建docker集群
首先需要初始化一个 swarm 集群并给节点标注名称。
linux 节点名称需要以 linux-
打头,windows节点则以 windows-
打头
docker swarm init
docker node update --label-add "name=linux-1" $(docker node ls -q)
新版 ctfd-whale 利用 docker swarm 的集群管理能力,能够将题目容器分发到不同的节点上运行。选手每次请求启动题目容器时,ctfd-whale 都将随机选择一个合适的节点运行这个题目容器。
下载CTFd
git clone https://github.com/CTFd/CTFd --depth=1
# --depth=1 只克隆包含最近一次commit的一个分支,这样这个项目文件就不会恨大
# 如果 git clone 速度慢,可以把 https:// 换成 git:// 提速
cd CTFd # 注:以下全部内容的cwd均为此目录
修改docker-compose.yml文件
2.5.0+版本 CTFd 的 docker-compose.yml
中包含了一个 nginx
反代,占用了80端口,如不需要可注释或删除。
vim docker-compose.yml
version: '3.7' # 修改 docker-compose 版本
services:
ctfd:
build: .
user: root
restart: always
ports:
- "8000:8000" # 服务器端口:容器内端口
environment:
- UPLOAD_FOLDER=/var/uploads
- DATABASE_URL=mysql+pymysql://ctfd:ctfd@db/ctfd
- REDIS_URL=redis://cache:6379
- WORKERS=1
- LOG_FOLDER=/var/log/CTFd
- ACCESS_LOG=-
- ERROR_LOG=-
# - REVERSE_PROXY=true
volumes:
- .data/CTFd/logs:/var/log/CTFd
- .data/CTFd/uploads:/var/uploads
- .:/opt/CTFd:ro
depends_on:
- db
networks:
default:
internal:
# nginx:
# image: nginx:1.17
# restart: always
# volumes:
# - ./conf/nginx/http.conf:/etc/nginx/nginx.conf
# ports:
# - 80:80
# depends_on:
# - ctfd
···
修改Dockerfile换源
将容器的源换成国内的上交源,提高 build 速度。
vim Dockerfile
FROM python:3.7-slim-buster
WORKDIR /opt/CTFd
RUN mkdir -p /opt/CTFd /var/log/CTFd /var/uploads
# hadolint ignore=DL3008
RUN sed -i "s|http://deb.debian.org/debian|https://mirror.sjtu.edu.cn/debian|g" /etc/apt/sources.list \
&& apt-get update \
# 修改上面两行
&& apt-get install -y --no-install-recommends \
···
镜像加速可参照:官方镜像加速 - 容器镜像服务 ACR - 阿里云 (aliyun.com)
CTFd平台启动
在进行这一步之前,请确认服务器的时间正确,否则可能导致CTFd平台时间出错,容器连接超时等问题。
docker-compose up -d
若从旧版本平台升级,需要先删除或者 untag 旧版本的 ctfd_ctfd docker 镜像,否则启动时会出错,docker-compose logs ctfd 报错
ctfd_1 | standard_init_linux.go:228: exec user process caused: no such file or directory
若不幸在删除旧的镜像之前启动,则可能遇到数据库连接不上的问题,docker-compose logs ctfd 停留在
ctfd_1 | Waiting for mysql+pymysql://ctfd:ctfd@db to be ready
,解决方法是把整个.data
文件夹删除,或者重新git clone。
访问 http://localhost:8000,对CTFd进行初始配置。
安装启动frp服务
配置frps服务
下载安装frps
cd
wget https://github.com/fatedier/frp/releases/download/v0.36.2/frp_0.36.2_linux_amd64.tar.gz
tar -zxvf frp_0.36.2_linux_amd64.tar.gz
cd frp_0.36.2_linux_amd64
sudo cp systemd/* /etc/systemd/system/
sudo mkdir /etc/frp
sudo cp frpc.ini frps.ini /etc/frp/
sudo cp frpc frps /usr/bin/
sudo chmod a+x /usr/bin/frpc /usr/bin/frps
sudo systemctl enable frps
配置frps.ini
sudo vim /etc/frp/frps.ini
#frps.ini
[common]
bind_port = 7897
bind_addr = 0.0.0.0
token = thisistoken
# vhost_http_port = 80 # 如果要配置http动态域名则需要这个。80端口开启需要systemd使用root权限启用frp,在这里不需要
启动frps服务
sudo systemctl start frps
配置frpc容器
修改 docker-compose.yml 文件,添加一个 frpc 服务,并添加一个 frp 网络和题目容器网络;把 frpc 加入 ctfd 默认网络、frp 网络和题目容器网络,设置 frpc 在 frp 网络中的 ip 为 172.1.0.4,也就是 admin_addr。
vim docker-compose.yml
services:
···
frpc:
image: glzjin/frp:latest
restart: always
volumes:
- ./conf/frp:/conf/
entrypoint:
- /usr/local/bin/frpc
- -c
- /conf/frpc.ini
networks:
default:
frp_containers:
frp_connect:
ipv4_address: 172.1.0.4
networks:
···
frp_connect:
driver: overlay
internal: true
ipam:
config:
- subnet: 172.1.0.0/16
frp_containers:
driver: overlay
internal: true # 如果允许题目容器访问外网,则可以去掉
attachable: true
ipam:
config:
- subnet: 172.2.0.0/16
配置frpc.ini
mkdir ./conf/frp
vim ./conf/frp/frpc.ini
[common]
token = thisistoken
server_addr = 172.17.0.1 # 这里填写服务器ip addr之后docker0的ip地址
server_port = 7897 # 这里需与前面frps.ini的bind_port匹配
admin_addr = 172.1.0.4 # 这里填写frpc服务在frp网络中的ip
admin_port = 7400
# 这里需要留至少一行空行,因为新的 Whale 会把容器的转发代理写到这个文件里,没留空行的话会影响 admin_port。
检查frp配置
更新 docker-compose 配置后使用 logs 命令查看 frpc 服务日志。
docker-compose up -d
docker-compose logs frpc
出现下面的日志说明配置正常,frpc 与 frps 连接正常。
[service.go:224] login to server success, get run id [****], server udp port [****]
[service.go:109] admin server listen on 172.1.0.4:7400
CTFd
├── conf
│ └── frp
│ └── frpc.ini
├── docker-compose.yml
├── Dockerfile
│
配置CTFd
修改docker-compose.yml文件
映射 docker 启动接口,并把 ctfd 服务添加到 frp 网络中。
services:
ctfd:
...
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- frpc #frpc需要先运行
networks:
...
frp_connect:
下载 CTFd-Whale
git clone https://github.com/frankli0324/CTFd-Whale CTFd/plugins/ctfd-whale --depth=1
docker-compose build # 需要安装依赖
docker-compose up -d
进入 CTFd 平台之后,在 admin 页面选择 Whale
CTFd动态容器题目部署指南
点击 Finish 即可发布题目。