Files
CTFd-Whale/docs/install.zh-cn.md
2025-09-19 15:59:08 +08:00

313 lines
9.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 使用指南
## TLDR
如果你从未部署过CTFd你可以通过执行:
```sh
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh --mirror Aliyun
docker swarm init
docker node update --label-add='name=linux-1' $(docker node ls -q)
git clone https://github.com/CTFd/CTFd --depth=1
git clone https://github.com/frankli0324/ctfd-whale CTFd/CTFd/plugins/ctfd-whale --depth=1
curl -fsSL https://cdn.jsdelivr.net/gh/frankli0324/ctfd-whale/docker-compose.example.yml -o CTFd/docker-compose.yml
# make sure you have pip3 installed on your rig
pip3 install docker-compose
docker-compose -f CTFd/docker-compose.yml up -d
docker-compose -f CTFd/docker-compose.yml exec ctfd python manage.py
```
脚本会在一台Linux机器上安装 ***docker.com版本的*** `docker-ce``python3-pip` 以及 `docker-compose`,请确保执行上述代码之前:
* 安装好curlgitpython3以及pip
* 网络环境良好能正常从GitHub克隆仓库
* 网络环境良好能正常从Docker Registry拖取镜像
## 手动安装
为了更好地理解ctfd-whale各个组件的作用更充分地利用ctfd-whale在真实使用ctfd-whale时建议用户手动、完整地从空白CTFd开始搭建一个实例。下面本文将引导你完成整个流程。
### 从零开始
首先需要初始化一个swarm集群并给节点标注名称
linux节点名称需要以 `linux-` 打头windows节点则以 `windows-` 打头
```bash
docker swarm init
docker node update --label-add "name=linux-1" $(docker node ls -q)
```
`ctfd-whale`利用`docker swarm`的集群管理能力,能够将题目容器分发到不同的节点上运行。选手每次请求启动题目容器时,`ctfd-whale`都将随机选择一个合适的节点运行这个题目容器。
然后我们需要确保CTFd可以正常运行。
注意2.5.0+版本CTFd的 `docker-compose.yml` 中包含了一个 `nginx` 反代占用了80端口
```bash
git clone https://github.com/CTFd/CTFd --depth=1
cd CTFd # 注以下全部内容的cwd均为此目录
```
先将 `docker-compose.yml` 的第一行进行修改,以支持 `attachable` 参数
`version '2'` -> `version '3'`
接着
```bash
docker-compose up -d
```
访问<http://localhost>或8000端口对CTFd进行初始配置
### 配置frps
frps可以直接通过docker-compose与CTFd同步启动。
首先在networks中添加一个网络用于frpc与frps之间的通信并添加frps service
```yml
services:
...
frps:
image: glzjin/frp
restart: always
volumes:
- ./conf/frp:/conf
entrypoint:
- /usr/local/bin/frps
- -c
- /conf/frps.ini
ports:
- 10000-10100:10000-10100 # 映射direct类型题目的端口
- 8001:8001 # 映射http类型题目的端口
networks:
default: # 需要将frps暴露到公网以正常访问题目容器
frp_connect:
networks:
...
frp_connect:
driver: overlay
internal: true
ipam:
config:
- subnet: 172.1.0.0/16
```
先创建目录 `./conf/frp`
```bash
mkdir ./conf/frp
```
接着创建 `./conf/frp/frps.ini` 文件,填写:
```ini
[common]
# 下面两个端口注意不要与direct类型题目端口范围重合
bind_port = 7987 # frpc 连接到 frps 的端口
vhost_http_port = 8001 # frps 映射http类型题目的端口
token = your_token
subdomain_host = node3.buuoj.cn # 访问http题目容器的主机名
```
### 配置frpc
同样在networks中再添加一个网络用于frpc与题目容器之间的通信并添加frpc service
```yml
services:
...
frpc:
image: glzjin/frp:latest
restart: always
volumes:
- ./conf/frp:/conf/
entrypoint:
- /usr/local/bin/frpc
- -c
- /conf/frpc.ini
depends_on:
- frps #frps需要先成功运行
networks:
frp_containers: # 供frpc访问题目容器
frp_connect: # 供frpc访问frps, CTFd访问frpc
ipv4_address: 172.1.0.3
networks:
...
frp_containers:
driver: overlay
internal: true # 如果允许题目容器访问外网,则可以去掉
attachable: true
ipam:
config:
- subnet: 172.2.0.0/16
```
同样,我们需要创建一个 `./conf/frp/frpc.ini`
```ini
[common]
token = your_token
server_addr = frps
server_port = 7897 # 对应 frps 的 bind_port
admin_addr = 172.1.0.3 # 请参考“安全事项”
admin_port = 7400
```
### 检查frp配置是否正确
此时可以执行 `docker-compose up -d` 更新compose配置
通过查看日志 `docker-compose logs frpc` 应当能看到frpc产生了以下日志
```log
[service.go:224] login to server success, get run id [******], server udp port [******]
[service.go:109] admin server listen on ******
```
说明frpc与frps皆配置正常
注:此例中目录结构为:
```
CTFd/
conf/
nginx # CTFd 2.5.0+中自带
frp/
frpc.ini
frps.ini
serve.py
```
### 配置CTFd
前面的工作完成后将本机docker的访问接口映射到CTFd所在容器内
并将CTFd添加到frpc所在network中注意不是containers这个network
```yml
services:
ctfd:
...
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- frpc #frpc需要先运行
networks:
...
frp_connect:
```
将CTFd-Whale克隆至CTFd的插件目录
```bash
git clone https://github.com/frankli0324/CTFd-Whale CTFd/plugins/ctfd-whale --depth=1
docker-compose build # 需要安装依赖
docker-compose up -d
```
进入Whale的配置页面( `/plugins/ctfd-whale/admin/settings` )首先配置docker配置项
需要注意的是 `Auto Connect Network` ,如果按照上面的配置流程进行配置的话,应当是 `ctfd_frp_containers`
如果不确定的话可以通过下面的命令列出CTFd目录compose生成的所有network
```bash
docker network ls -f "label=com.docker.compose.project=ctfd" --format "{{.Name}}"
```
然后检查frp配置项是否正确
* `HTTP Domain Suffix` 与 frps 的 `subdomain_host` 保持一致
* `HTTP Port` 与 frps 的 `vhost_http_port` 保持一致
* `Direct IP Address` 为能访问到 frps 相应端口(例子中为10000-10100) 的IP
* `Direct Minimum Port``Direct Maximum Port` 显然可得
* 只要正确填写了 `API URL` Whale 会自动获取 frpc 的配置文件作为 `Frpc config template`
* 通过设置 `Frpc config template` 可以覆盖原有 `frpc.ini` 文件
至此CTFd-Whale 已经马马虎虎可以正常使用了。
### 配置nginx
如果你在使用2.5.0+版本的CTFd那么你可以直接利用自带的nginx进行http题目的反代
首先去除docker-compose.yml中对frps http端口的映射(8001)
如果想贯彻到底的话,可以
* 为nginx添加internal与default两个network
* 去除CTFd的default network并去除ports项
`./conf/nginx/nginx.conf` 的http block中添加以下server block
```conf
server {
listen 80;
server_name *.node3.buuoj.cn;
location / {
proxy_pass http://frps:8001;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
```
## 部署题目
### 单容器题目环境
请参考<https://github.com/CTFTraining>中的镜像进行题目镜像制作Dockerfile编写。总体而言题目在启动时会向**容器**内传入名为 `FLAG` 的环境变量你需要编写一个启动脚本一般为bash+sed组合拳将flag写入自己的题目中并删除这一环境变量。
请出题人制作镜像时请理清思路,不要搞混容器与镜像的概念。这样既方便自己,也方便部署人员。
### 多容器题目环境
在题目镜像名处填写一个json object即可创建一道多容器的题目
```json
{
"hostname": "image",
}
```
Whale会保留json的key顺序并将第一个容器作为"主容器"映射到外网,映射方式与单容器相同
以buuoj上的swpu2019 web2为例可以配置如下
```json
{
"ss": "shadowsocks-chall",
"web": "swpu2019-web2",
...
}
```
其中shadowsocks-chall的Dockerfile:
```dockerfile
FROM shadowsocks/shadowsocks-libev
ENV PASSWORD=123456
ENV METHOD=aes-256-cfb
```
> 由于写README的并不是buuoj管理员故上述仅作说明用与实际情况可能有较大出入
## 安全事项
* 后台配置中flag与domain模版理论上存在sstifeature请不要将管理员账号给不可信第三方
* 由于例子中frpc并没有开启鉴权请不要将frpc的bind_addr设置为`0.0.0.0`。这样会导致利用任何一道能发起http请求的题目都能修改frpc配置。
* 如果出于配置复杂性考虑题目容器能够访问frpc请开启frpc的Basic Auth并以 `http://username:password@frpc:7400` 的格式设置frpc API URL
## 高级部署
用于下发靶机实例的服务器与运行 `CTFd` 网站的服务器分离,`CTFd-whale` 通过启用了 `TLS/SSL` 验证的 `Dockers API`进行下发容器控制
参见 [advanced.zh-cn.md](advanced.zh-cn.md)