[TOC]
-
主机:Ubuntu 20.10
- 本篇文章使用的机器的IP:192.168.2.151
-
Docker版本:20.10.2
-
Docker-compose版本:1.25.0
apt-get install vim
因为是官方源,所以会比较慢,后面会进行换源。
这里以Ubuntu20.10为例:ubuntu | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
vim /etc/apt/sources.list
将原有的内容删除,往source.list里面加入以下内容,加完之后保存退出。
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ groovy main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ groovy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ groovy-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ groovy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ groovy-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ groovy-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ groovy-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ groovy-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ groovy-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ groovy-proposed main restricted universe multiverse
**注意:**一定要更新一下镜像源!!(不然后面没法安装包)
apt-get update
apt-get install docker.io
输入y后回车
apt-get install docker-compose
同样按y后回车
apt-get intsall git
一般来说,安装过docker之后,git也已经安装好了,不过我们还是再确认一下。
进入阿里云镜像服务官网:容器镜像服务 (aliyun.com)
根据下方教程配置自己的Docker静态加速器。
镜像地址每个人都不一样,根据每个人的情况设置。
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
这一个CTFd是赵师傅改写的,链接在下方。之所以要使用赵师傅改写的CTFd,是因为官方CTFd可能会与动态靶机插件ctf-whale冲突。
git clone https://github.com/glzjin/CTFd.git
如果clone的过程中卡住了,可以尝试Ctrl+C将命令掐断,然后重新执行,实在不行的话,可以挂代理。
下载frpc:
wget https://github.com/fatedier/frp/releases/download/v0.29.0/frp_0.29.0_linux_amd64.tar.gz
同样的,如果clone的过程中卡住了,可以尝试Ctrl+C将命令掐断,然后重新执行,实在不行的话,可以挂代理。
将下载下来的frpc解压:
tar -zxvf frp_0.29.0_linux_amd64.tar.gz
地址:https://github.com/glzjin/CTFd-Whale
git clone https://github.com/glzjin/CTFd-Whale.git
**注意:**这个时候要将CTFd-Whale文件夹重命名为小写。
mv CTFd-Whale/ ctfd-whale
地址:https://github.com/glzjin/Frp-Docker-For-CTFd-Whale
git clone https://github.com/glzjin/Frp-Docker-For-CTFd-Whale
**注意:**将Frp-Docker-For-CTFd-Whale也重命名为小写
mv Frp-Docker-For-CTFd-Whale/ frp-docker-for-ctfd-whale
接下来就开始配置CTFd的一些文件了!
先初始化:
docker swarm init
将刚刚初始化的这个集群加入到节点当中,命令执行后,返回的就是节点ID了,暂时不用管这个节点ID。
docker node update --label-add='name=linux-1' $(docker node ls -q)
如下图所示:
mv ctfd-whale/ CTFd/CTFd/plugins/
进入该目录:
cd frp-docker-for-ctfd-whale/
启动该docker:
docker-compose up -d
耐心等待镜像构建。
完成以后,可以使用docker ps
查看是否正在运行。
这个时候我们查看一下frps的配置。
frps/frps.ini文件如下:
[common]
bind_port = 6490
token = randomme
这里的token可以改也可以不改,一般也就不改了。
这一步骤实际上就是:将frpc,frpc.ini,frpc_full.ini,LICENSE这四个文件放在CTFd/frpc文件夹中。
进入CTFd目录中,新建一个frpc文件夹
cd CTFd/
mkdir frpc
进入frpc的目录(frp_0.29.0_linux_amd64)
cd ../frp_0.29.0_linux_amd64
将上述四个文件移动到frpc文件夹中
mv frpc.ini ../CTFd/frpc/
mv frpc_full.ini ../CTFd/frpc/
mv frpc ../CTFd/frpc/
mv LICENSE ../CTFd/frpc/
进入frpc目录中,修改frpc.ini文件
[common]
token = randomme
server_addr = 172.1.0.4
server_port = 6490
pool_count = 200
tls_enable = true
admin_addr = 172.1.0.3
admin_port = 7400
进入ctfd目录,将下方内容复制到Dockerfile中
FROM python:3.7-alpine
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.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 #这里注意1
RUN adduser -D -u 1001 -s /bin/bash ctfd
WORKDIR /opt/CTFd
RUN mkdir -p /opt/CTFd /var/log/CTFd /var/uploads
COPY requirements.txt .
RUN apk add gcc
RUN apk add musl-dev
RUN apk add libxslt-dev
RUN apk add g++
RUN apk add make
RUN apk add libffi-dev
RUN apk add openssl-dev
RUN apk add libtool
RUN pip install -r requirements.txt -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/ #这里注意2
COPY . /opt/CTFd
RUN for d in CTFd/plugins/*; do \
if [ -f "$d/requirements.txt" ]; then \
pip install -r $d/requirements.txt -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/ ; \
fi; \
done; #同样注意2
RUN chmod +x /opt/CTFd/docker-entrypoint.sh
RUN chown -R 1001:1001 /opt/CTFd
RUN chown -R 1001:1001 /var/log/CTFd /var/uploads
USER 1001
EXPOSE 8000
ENTRYPOINT ["/opt/CTFd/docker-entrypoint.sh"]
version: '2.2'
services:
ctfd-nginx:
image: nginx:1.17
volumes:
- ./nginx/http.conf:/etc/nginx/nginx.conf #这里注意
user: root
restart: always
ports:
#- "85:80" #我将这里注释掉了,这里通过nginx转发感觉速度访问速度会变慢,可能因为我的配置问题,多次尝试之后直接开8000端口访问不会对服务造成影响
- "443:443"
networks:
default:
internal:
depends_on:
- ctfd
cpus: '1.00' #可改
mem_limit: 150M #可改
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=-
- REVERSE_PROXY=true
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
cpus: '1.00' #可改
mem_limit: 450M #可改
db:
image: mariadb:10.4
restart: always
environment:
- MYSQL_ROOT_PASSWORD=ctfd
- MYSQL_USER=ctfd
- MYSQL_PASSWORD=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]
cpus: '1.00' #可改
mem_limit: 750M #可改
cache:
image: redis:4
restart: always
volumes:
- .data/redis:/data
networks:
internal:
cpus: '1.00' #可改
mem_limit: 450M #可改
frpc:
image: glzjin/frp:latest #赵师傅tql
restart: always
volumes:
- ./frpc:/conf/ #这里注意
entrypoint:
- /usr/local/bin/frpc
- -c
- /conf/frpc.ini
networks:
frp:
ipv4_address: 172.1.0.3 #记住此处
frp-containers:
cpus: '1.00' #可改
mem_limit: 250M #可改
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
这里主要是修改gevent的版本号,原本是1.4.0的,我这边修改成了20.9.0
Flask==1.1.1
Werkzeug==0.16.0
Flask-SQLAlchemy==2.4.1
Flask-Caching==1.4.0
Flask-Migrate==2.5.2
Flask-Script==2.0.6
SQLAlchemy==1.3.11
SQLAlchemy-Utils==0.36.0
passlib==1.7.2
bcrypt==3.1.7
six==1.13.0
itsdangerous==1.1.0
requests>=2.20.0
PyMySQL==0.9.3
gunicorn==19.9.0
normality==2.0.0
dataset==1.1.2
mistune==0.8.4
netaddr==0.7.19
redis==3.3.11
datafreeze==0.1.0
python-dotenv==0.10.3
flask-restplus==0.13.0
pathlib2==2.3.5
flask-marshmallow==0.10.1
marshmallow-sqlalchemy==0.17.0
boto3==1.10.39
marshmallow==2.20.2
gevent==20.9.0
在docker-compose.yml的目录下,新建一个nginx文件夹
mkdir nginx
进入nginx文件夹
cd nginx
创建一个文件http.conf,输入以下内容:
worker_processes 4;
events {
worker_connections 1024;
}
http {
# Configuration containing list of application servers
upstream app_servers {
server ctfd:8000;
}
server {
listen 80;
client_max_body_size 4G;
# Handle Server Sent Events for Notifications
location /events {
proxy_pass http://app_servers;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
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;
}
# Proxy connections to the application servers
location / {
proxy_pass http://app_servers;
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;
}
}
}
保存后退出。
进入docker-compose.yml所在的文件目录下
docker-compose up -d
耐心等待。。。
完成后应该是这个样子
我们先看一下现在的容器状态:
docker ps -a
可以看到ctfd_frpc_1这个容器的状态是退出状态。
我们再看一下现在docker的网络:
docker network ls
一会我们需要将ctfd_frpc_1,frp-docker-for-ctfd-whale_frps_1,ctfd_ctfd_1这三个容器加入到ctfd_frp网络中
并且这三个容器的IP如下:
-
ctfd_ctfd_1:172.1.0.2
-
ctfd_frpc_1:172.1.0.3
-
frp-docker-for-ctfd-whale_frps_1:172.1.0.4
查看一下ctfd_frp网络
docker network inspect ctfd_frp
这个时候只有ctfd_ctfd_1这个容器是在ctfd_frp网络里的。
注意要指定IP:
docker network connect --ip 172.1.0.3 ctfd_frp ctfd_frpc_1
docker network connect --ip 172.1.0.4 ctfd_frp frp-docker-for-ctfd-whale_frps_1
然后重启一下这两个容器:
docker restart ctfd_frpc_1 frp-docker-for-ctfd-whale_frps_1
重启完成之后再查看一下ctfd_frp网络
docker network inspect ctfd_frp
可以看到,这个时候,ctfd_frpc_1,frp-docker-for-ctfd-whale_frps_1,ctfd_ctfd_1这三个容器已经加入到ctfd_frp网络中
查看ctfd_frpc_1容器日志:
docker logs ctfd_frpc_1
这样就算已经配置好了。
接下来就是ctfd-whale配置。
在浏览器中访问IP:8000
我这台机器就是http://192.168.2.151:8000
这一块就是ctfd的前置配置,按照自己的需求配置一下就好了
网站初步配置完成之后,开始配置ctfd-whale插件。
设置方面,就按照赵总的配置就好了,我这边参考error师傅的。
属性 | 配置 |
---|---|
Docker API URL | unix://var/run/docker.sock |
Frp API IP | frpc的ip配置 |
Frp API Port | frpc的端口配置 |
Frp Http Domain Suffix | Docker API URL to connect(可填None) |
Frp Http Port | 80 |
Frp Direct IP Address | 你的公网ip,本机即为127.0.0.1 |
Frp Direct Minimum Port | 与之前frps最小端口呼应 |
Frp Direct Minimum Port | 与之前frps最大端口呼应 |
Max Container Count | 不超过最大-最小 |
Max Renewal Times | 最大实例延时次数 |
Frp config template | 填入frps的配置,只需填[common] |
Docker Auto Connect Containers | ctfd_frpc_1 |
Docker Dns Setting | 可填机器内DNS,没有可填个外网DNS |
Docker Swarm Nodes | linux-1 与前面swarm集群呼应 |
Docker Multi-Container Network Subnet | 内网题大子网ip配置/CIDR |
Docker Multi-Container Network Subnet New Prefix | 每个内网题实例的CIDR |
Docker Container Timeout | 单位为秒 |
其中Frp config template配置内容如下:
[common]
token = randomme
server_addr = 172.1.0.4
server_port = 6490
pool_count = 200
tls_enable = true
admin_addr = 172.1.0.3
admin_port = 7400
其他的按照下面这张图片配置就好
注意:
Frp Direct IP Address这个一定要修改成自己的IP,如果是云服务器就输入公网IP,如果是虚拟机那就输入虚拟机的IP。
添加的题目如下:
其中Docker image里就输入题目的tag就好了
测试开启题目:
可以看到,已经正确分配IP了
第一次获取题目要等一会,因为要拉题目镜像,等一会后就可以访问题目了。
在Docker里也可以看到相应的题目容器。
报错:
如果日志像下方这样,那么就是网络没有配置好
解决方案:
仔细配置网络,网络配置的要求如下:
-
将ctfd_frpc_1,frp-docker-for-ctfd-whale_frps_1,ctfd_ctfd_1这三个容器加入到ctfd_frp网络中
-
这三个容器对应的IP如下:
-
ctfd_ctfd_1:172.1.0.2
-
ctfd_frpc_1:172.1.0.3
-
frp-docker-for-ctfd-whale_frps_1:172.1.0.4
-
活用docker的日志功能:
docker logs <容器ID或名称>
活用docker的网络配置功能:
查看网络
docker network ls
给容器分配指定IP
docker network connect --ip 172.1.0.4 <网络名称> <容器ID或名称>
报错:
解决方案:
其他Dockerfile在构建的时候可能会出现gevent构建不成功的问题,有以下几种解决办法:
(这篇文章的搭建方法,已经把坑都踩了,所以前面的教程是没有问题的)
报错:
解决方案:
将Dockerfile中的python和python-dev删掉,或者修改成python2或python3,python2-dev或python3-dev都可以。
报错:
解决方案:
将docker-entrypoint.sh第一行修改为:
#!/bin/bash
修改后,重新build即可
链接:https://pan.baidu.com/s/11FLyPOKHzpLNBUfuxwJmag 提取码:flag
链接如果挂了,可以到我的个人博客联系我:https://www.xiinnn.com
-
虚拟机用户:
-
用户名:ctf
-
密码:root
-
用户名:root
-
密码:root
-
-
CTFd后台管理员:
-
用户名:admin
-
密码:password
-
导入虚拟机后启动
选中ctf用户,输入密码root后登陆
打开终端,切换为root用户,密码为root
su root
配置自己的网络(这里看自己的情况)
进入CTFd文件夹
cd CTFd
启动docker
docker-compose up -d
进入frp-docker-for-ctfd-whale文件夹:
cd ../frp-docker-for-ctfd-whale/
启动docker
docker-compose up -d
查看自己的IP:
ifconfig
一般是ens33或者eth0网卡
访问ip:8000即可
- CTFd/CTFd: CTFs as you need them (github.com)
- CTFD支持动态靶机的搭建笔记(docker:ctfd+ctf-whale)2020.10.17 - 灰信网(软件开发博客聚合) (freesion.com)
- glzjin/CTFd-Whale: A plugin for CTFd which allow your users to deploy a standalone instance for challenges. (github.com)
- CTFD支持动态靶机的搭建笔记(docker:ctfd+ctf-whale) | Err0r
- 手把手教你如何建立一个支持ctf动态独立靶机的靶场(ctfd+ctfd-whale)_fjh1997的博客-CSDN博客
- ctfd使用ctfd-whale动态靶机插件搭建靶场指南 | VaalaCat