基础配置
需要一台 x64 的服务器,要提前安装好 Docker 、 Docker-Compose 和 Git
安装过程
docker 集群配置
启用 Docker Swarm,并为生成的 Manager 节点取一个别名
docker swarm init
docker node ls
docker node update --label-add name=linux-1 <节点 ID>
下载 CTFd 修改版
博主 Vicosna 已经对CTFd v3.3.1官方源码进行了更换国内镜像源、添加CTFd-Whale子模块、配置frp网络、设置静态文件CDN加速等工作,可前往使用作者修改的版本进行安装部署。
git clone -b frp https://github.com/vicosna/CTFd.git
但是现在看的时候,不知道为什么,已经找不到了。
我这里还有一份之前下过的,也可以用我的:CTFd.zip
执行如下命令更新CTFd-Whale子模块
cd CTFd
git submodule update --init
编辑 frp 配置文件
一个是服务端,一个是客户端,主要是修改一个密钥
编辑 frp/frpc.ini
[common]
token = 123456
server_addr = 172.1.0.1
server_port = 6490
pool_count = 200
tls_enable = true
admin_addr = 172.1.0.3
admin_port = 7400
编辑 frp/frps.ini
[common]
bind_port = 6490
token = 123456
确保 token 一样即可
修改 CTFd/themes/core/static/css/fonts.dev.css 和 fonts.min.css
将这两个文件中的 https://use.fontawesome.com/releases/v5.9.0/css/all.css 修改为 https://cdn.bootcss.com/font-awesome/5.13.0/css/all.css
编辑 DockerFile 和 docker-compose.yml
直接按照我的配置复制
DockerFile
FROM python:3.7-alpine
WORKDIR /opt/CTFd
RUN mkdir -p /opt/CTFd /var/log/CTFd /var/uploads
RUN sed -i 's/dl-cdn.alpinelinux.org/mirror.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && \
apk update && \
apk add \
linux-headers \
libffi-dev \
gcc \
make \
musl-dev \
py-pip \
mysql-client \
git \
openssl-dev
COPY . /opt/CTFd
RUN pip install -r requirements.txt -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/
RUN for d in CTFd/plugins/*; do \
if [ -f "$d/requirements.txt" ]; then \
pip install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com -r $d/requirements.txt; \
fi; \
done;
RUN chmod +x /opt/CTFd/docker-entrypoint.sh
RUN adduser -D -u 1001 -s /bin/sh ctfd
RUN chown -R 1001:1001 /opt/CTFd /var/log/CTFd /var/uploads
USER 1001
EXPOSE 8000
ENTRYPOINT ["/opt/CTFd/docker-entrypoint.sh"]
docker-compose.yml
version: '2.1'
services:
ctfd:
build: .
user: root
restart: always
ports:
- "8000:8000"
environment:
- UPLOAD_FOLDER=/var/uploads
- DATABASE_URL=mysql+pymysql://root:ctfd@db/ctfd
- REDIS_URL=redis://cache:6379
- WORKERS=1
- LOG_FOLDER=/var/log/CTFd
- ACCESS_LOG=-
- ERROR_LOG=-
volumes:
- .data/CTFd/logs:/var/log/CTFd
- .data/CTFd/uploads:/var/uploads
- .:/opt/CTFd:ro
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- db
networks:
default:
internal:
frp:
ipv4_address: 172.1.0.2
db:
image: mariadb:10.4
restart: always
environment:
- MYSQL_ROOT_PASSWORD=ctfd
- MYSQL_USER=ctfd
- MYSQL_PASSWORD=ctfd
- MYSQL_DATABASE=ctfd
volumes:
- .data/mysql:/var/lib/mysql
networks:
internal:
# This command is required to set important mariadb defaults
command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci, --wait_timeout=28800, --log-warnings=0]
cache:
image: redis:4
restart: always
volumes:
- .data/redis:/data
networks:
internal:
frpc:
image: glzjin/frp:latest
restart: always
volumes:
- ./frp:/conf/
depends_on:
- frps
entrypoint:
- /usr/local/bin/frpc
- -c
- /conf/frpc.ini
networks:
frp:
ipv4_address: 172.1.0.3
frp_containers:
frps:
image: glzjin/frp:latest
restart: always
volumes:
- ./frp:/conf/
entrypoint:
- /usr/local/bin/frps
- -c
- /conf/frps.ini
network_mode: host
networks:
default:
internal:
internal: true
frp:
driver: bridge
ipam:
config:
- subnet: 172.1.0.0/16
frp_containers:
driver: overlay
internal: true
ipam:
config:
- subnet: 172.2.0.0/16
编辑 requirements.txt
替换为如下内容
alembic==1.12.1
aniso8601==10.0.1
APScheduler==3.10.4
attrs==24.2.0
backports.zoneinfo==0.2.1
banal==1.0.6
bcrypt==3.1.7
boto3==1.10.39
botocore==1.13.50
certifi==2025.1.31
cffi==1.15.1
chardet==5.2.0
charset-normalizer==3.4.1
click==8.1.8
datafreeze==0.1.0
dataset==1.1.2
docker==4.1.0
docutils==0.15.2
Flask==1.1.2
Flask-APScheduler==1.11.0
Flask-Caching==1.4.0
flask-marshmallow==0.10.1
Flask-Migrate==2.5.2
flask-redis==0.4.0
flask-restplus==0.13.0
Flask-Script==2.0.6
Flask-SQLAlchemy==2.4.1
gevent==21.12.0
greenlet==1.1.3.post0
gunicorn==19.9.0
idna==3.10
importlib-metadata==6.7.0
importlib-resources==5.12.0
itsdangerous==1.1.0
Jinja2==2.11.3
jmespath==0.10.0
jsonschema==4.17.3
Mako==1.2.4
MarkupSafe==1.1.1
marshmallow==2.20.2
marshmallow-sqlalchemy==0.17.0
mistune==0.8.4
netaddr==0.7.19
normality==2.0.0
passlib==1.7.2
pathlib2==2.3.5
pkgutil_resolve_name==1.3.10
pycparser==2.21
PyMySQL==0.9.3
pyrsistent==0.19.3
python-dateutil==2.9.0.post0
python-dotenv==0.10.3
pytz==2025.2
PyYAML==6.0.1
redis==3.3.11
requests==2.31.0
s3transfer==0.2.1
six==1.13.0
SQLAlchemy==1.3.11
SQLAlchemy-Utils==0.36.0
text-unidecode==1.3
typing_extensions==4.7.1
tzlocal==5.1
urllib3==1.25.11
websocket-client==1.6.1
Werkzeug==0.16.0
zipp==3.15.0
zope.event==5.0
zope.interface==6.4.post2
部署并启动
直接部署并启动
docker-compose up -d
这里很可能会遇到下面这个错误
查看一下 frpc 的容器 ID
docker ps -a
删除然后用 --attachable 参数重新创建这个网络
docker network rm ctfd_frp_containers
docker network create --driver overlay --attachable ctfd_frp_containers
然后再启动就可以了
docker start 容器ID
如果发现 CTFd 容器出现以下报错:
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: exec: "/opt/CTFd/docker-entrypoint.sh": permission denied: unknown
给予脚本执行权限即可,然后重新启动 CTFd 即可
chmod +x docker-entrypoint.sh
如果 frpc 容器一直显示连接不到 frps 容器,看看是不是 docker 的 iptables 关掉了,要打开才能连上。
编辑 CTFd Whale 配置
参考下面的截图配置即可
这里填本机地址或自己的域名
这里直接复制 ftpc 的配置内容,注意全部复制过来
创建动态靶机
参考下图创建挑战
第一次启动的时候会很慢,因为要去下载镜像
然后去访问,应该就会有题目了