GZCTF平台Docker搭建详细教程

一、GZCTF平台简介

GZCTF 是一个基于 ASP.NET Core 的开源 CTF(Capture The Flag)平台,主要面向网络安全竞赛和技能提升。以下是关于 GZCTF 的详细介绍:

(一)核心功能

  • 题目类型:支持多种题目类型,包括静态附件、动态附件、静态容器和动态容器。静态附件是共享的,而动态附件则根据队伍数量进行分发.
  • 动态分值:题目分值可以根据解决次数动态调整,支持三血奖励机制.
  • 实时监控:基于 SignalR 实现实时比赛通知、比赛事件和 flag 提交监控.
  • 权限管理:提供三级用户权限管理,包括管理员、参赛者等.
  • Writeup 收集:支持 Writeup 的收集、查阅和批量下载.
  • 流量代理:题目流量可以通过 TCP over WebSocket 代理转发,并支持流量捕获.

(二)部署方式

  • K8s 集群部署:适用于大型比赛和长期比赛,利用 Kubernetes 的优势进行部署.
  • Docker 和 K8s 分离部署:适用于小型比赛和校赛,部署过程相对简单.
  • Docker 单机部署:适用于单机测试和最小化部署,不适用于生产环境.

(三)开源协议

GZCTF 基于 AGPLv3 协议开源,使用和修改均需遵守该协议.

(四)适用场景

  • 网络安全初学者:通过解决实际题目来入门和提高技能.
  • 教育机构:可用于教学和实践环节,帮助学生掌握网络安全知识.
  • 企业培训:作为内部安全意识培训工具,增强员工的安全防护能力.
  • 社区活动:举办线上或线下的 CTF 比赛,促进技术交流与切磋.

二、环境准备

1. 换源

Centos操作系统请参考:[Centos换源]
Ubuntu操作系统请参考:[Ubuntu换源]

2. Docker安装

你需要安装docker以及docker-compose请参考:[Docker安装]

好啦,到此结束,基本工作已经结束,开始开心部署吧【可能会有各种各样的问题,不要着急,最后部署完毕你会开心的】!

三、GZCTF正式部署

本篇讲述的主要是Docker方式部署

如果你是K8s方式部署,可以参考这篇文章[GZCTF平台仅k8s搭建]
如果你是Docker+K8s混合方式部署,可以参考这篇文章[GZCTF平台Docker+K8s搭建]

(一)创建根文件夹GZCTF

1、创建根文件夹

1
mkdir GZCTF

2、进入根文件夹

1
cd GZCTF

(二)准备信息

根据官方的文档,在配置appsttings.jsondocker-compose.yaml这两个配置文件之前,我们需要准备几个关键的参数信息

1
2
3
4
GZCTF_ADMIN_PASSWORD: Admin123..(GZCTF管理员密码)
POSTGRES_PASSWORD: gzctf123.. (数据库密码)
XOR_KEY: thisXorKey (加密比赛的随机字符串)
PUBLIC_ENTRY: 192.168.237.140 (虚拟机ip)

  • GZCTF_ADMIN_PASSWORD:初始管理员密码,在数据库未初始化时生效,需要在第一次启动时进行设置,配置在 docker-compose.yml 中。
  • POSTGRES_PASSWORD: 数据库密码,需要配置在 docker-compose.yml 中及 appsettings.json 中。
  • XOR_KEY: 用于加密比赛私钥的随机字符串,需要配置在 appsettings.json 中。
  • PUBLIC_ENTRY: 外部访问地址,可以是 IP 或域名,需要配置在 appsettings.json 中,用于提供给选手访问题目容器的地址。

(三)配置文件

  1. appsettings.json
  • (1)在GZCTF目录中创建 appsettings.json 文件
    1
    touch appsettings.json
  • (2)编写并配置 appsettings.json 文件内容
    1
    vim appsettings.json

将以下内容复制并粘贴进入 appsettings.json 文件,并根据你的信息进行修改

“Database”:这条中的Password,需要替换成你的数据库密码
“Xorkey”:这条中的XorKey,需要替换成你的XorKey,用于进行flag加密
“PublicEntry”:这条中的PublicEntry,需要替换成你的PublicEntry,用于提供给选手访问的IP地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
{
"AllowedHosts": "*",
"ConnectionStrings": {
"Database": "Host=db:5432;Database=gzctf;Username=postgres;Password=<Your DataBase Passsword>" // database password
},
"EmailConfig": {
"SenderAddress": "",
"SenderName": "",
"UserName": "",
"Password": "",
"Smtp": {
"Host": "localhost",
"Port": 587
}
},
"XorKey": "thisXorKey", // XOR key
"ContainerProvider": {
"Type": "Docker", // or "Kubernetes"
"PortMappingType": "Default", // or "PlatformProxy"
"EnableTrafficCapture": false,
"PublicEntry": "虚拟IP地址", // or "xxx.xxx.xxx.xxx" PublicEntry
// optional
"DockerConfig": {
"SwarmMode": false,
"Uri": "unix:///var/run/docker.sock"
}
},
"RequestLogging": false,
"DisableRateLimit": true,
"RegistryConfig": {
"UserName": "",
"Password": "",
"ServerAddress": ""
},
"CaptchaConfig": {
"Provider": "None", // or "CloudflareTurnstile" or "GoogleRecaptcha"
"SiteKey": "<Your SITE_KEY>",
"SecretKey": "<Your SECRET_KEY>",
// optional
"GoogleRecaptcha": {
"VerifyAPIAddress": "https://www.recaptcha.net/recaptcha/api/siteverify",
"RecaptchaThreshold": "0.5"
}
},
"ForwardedOptions": {
"ForwardedHeaders": 7,
"ForwardLimit": 1,
"TrustedNetworks": ["192.168.12.0/8"]
}
}
  1. docker-compose.yaml
  • (1)在GZCTF目录中创建 docker-compose.yaml 文件
    1
    touch docker-compose.yaml
  • (2)编写并配置 docker-compose.yaml 文件内容
    1
    vim docker-compose.yaml

将以下内容复制并粘贴进入 docker-compose.yaml 文件,并根据你的信息进行修改

‘GZCTF_ADMIN_PASSWORD’:这条中的Admin Password,需要替换成你的GZCTF管理员密码
‘POSTGRES_PASSWORD’:这条中的Database Password,需要替换成你的数据库密码
‘LC_ALL’:替换为你的语言,比如 LC_ALL=zh_CN.UTF-8(中文),LC_ALL=en_US.UTF-8(英文)
‘ports’: 如果运行在本地环境,需要将端口号替换成你的本地端口号,比如 80:8080(本地端口:远程端口)

如果本地端口发生冲突,需要更改本地端口,同时需要在防火墙放行相应的端口出站

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
services:
gzctf:
image: registry.cn-shanghai.aliyuncs.com/gztime/gzctf:develop
restart: always
environment:
- "GZCTF_ADMIN_PASSWORD=<Admin Password>" # GZCTF admin password
# choose your backend language `en_US` / `zh_CN` / `ja_JP`
- "LC_ALL=zh_CN.UTF-8"
ports:
- "80:8080"
volumes:
- "./data/files:/app/files"
- "./appsettings.json:/app/appsettings.json:ro"
# - "./kube-config.yaml:/app/kube-config.yaml:ro" # this is required for k8s deployment
- "/var/run/docker.sock:/var/run/docker.sock" # this is required for docker deployment
depends_on:
- db

db:
image: postgres:alpine
restart: always
environment:
- "POSTGRES_PASSWORD=<Your Database Password>" # database password
volumes:
- "./data/db:/var/lib/postgresql/data"

(四)启动项目

  1. 进入GZCTF目录

    1
    cd GZCTF
  2. 查看GZCTF目录下的文件
    按照以上内容进行操作的话,我们创建并配置了两个文件:appsettings.jsondocker-compose.yaml,现在可以启动GZCTF了

    1
    ls
  3. 启动GZCTF

    1
    docker-compose -f docker-compose.yml up -d

正常的情况,会有一下内容显示【镜像的拉取】,镜像拉取成功后并运行镜像
GZCTF镜像拉取

如果出现异常的情况,可能:

  • 网络问题:没有换源,或者是换源失效,导致的镜像拉取超时或者拉取失败
  • 端口占用:镜像拉取成功后,因为端口占用无法正常启动,导致无法访问

如果出现了异常问题,请参考这篇文章[GZCTF平台搭建问题合集]

恭喜啦~!我们已经部署完成啦,接下来我们可以开心的玩耍了,祝你好运!

  1. 访问GZCTF
    本地浏览器输入:127.0.0.1:本地端口
    外部访问: 虚拟IP地址:远程端口

GZCTF界面

  1. 登录管理员账户
    登录管理员账号可以创建比赛、发布题目、进行详细的配置等
    GZCTF管理员登录