• 简体中文
  • 快速上手

    GZCTF 通过 Docker 镜像的方式提供,你可以通过 docker-compose 的方式快速部署一个功能完善的 CTF 平台。请注意,这并不是唯一的部署方式,我们更推荐使用 Kubernetes 的方式部署。

    Warning

    GZCTF 的安全性和前端功能(如操作剪贴板)依赖于 HTTPS,此部分所描述的部署方式并不提供 HTTPS 支持,因此不适合用于生产环境。仅供本地测试使用。

    本文档不涉及如何配置 HTTPS,关于 nginx、traefik 等软件的配置使用方法请自行查询,请注意 GZCTF 的 websocket 功能可能也需要进行独立配置,如遇到比赛通知无法推送等问题请先排查反向代理是否配置正确。

    安装配置

    Info

    你需要安装 Docker 和 docker-compose 以便于快速开始使用 GZCTF,你可以在 Docker 官网 找到相关的安装说明。

    1. 为了后续的配置,请准备好如下的初始化参数:

      • GZCTF_ADMIN_PASSWORD:初始管理员密码,在数据库未初始化时生效,需要在第一次启动时进行设置,配置在 compose.yml 中。
      • POSTGRES_PASSWORD: 数据库密码,需要配置在 compose.yml 中及 appsettings.json 中。
      • XOR_KEY: 用于加密比赛私钥的随机字符串,需要配置在 appsettings.json 中。
      • PUBLIC_ENTRY: 外部访问地址,可以是 IP 或域名,需要配置在 appsettings.json 中,用于提供给选手访问题目容器的地址。
    2. 将以下内容保存为 appsettings.json 文件,并替换为你的初始化参数,具体配置说明请参考 appsettings.json 配置

      {
        "AllowedHosts": "*",
        "ConnectionStrings": {
          "Database": "Host=db:5432;Database=gzctf;Username=postgres;Password=<Your POSTGRES_PASSWORD>"
        },
        "EmailConfig": {
          "SenderAddress": "",
          "SenderName": "",
          "UserName": "",
          "Password": "",
          "Smtp": {
            "Host": "localhost",
            "Port": 587
          }
        },
        "XorKey": "<Your XOR_KEY>",
        "ContainerProvider": {
          "Type": "Docker", // or "Kubernetes"
          "PortMappingType": "Default", // or "PlatformProxy"
          "EnableTrafficCapture": false,
          "PublicEntry": "<Your PUBLIC_ENTRY>", // or "xxx.xxx.xxx.xxx"
          // optional
          "DockerConfig": {
            "Uri": "unix:///var/run/docker.sock"
          }
        },
        "CaptchaConfig": {
          "Provider": "None", // or "CloudflareTurnstile" or "HashPow"
          "SiteKey": "<Your SITE_KEY>",
          "SecretKey": "<Your SECRET_KEY>"
        },
        "ForwardedOptions": {
          "ForwardedHeaders": 7,
          "ForwardLimit": 1,
          "KnownIPNetworks": ["192.168.12.0/8"]
        }
      }
    3. 将以下内容保存为 compose.yml 文件,并替换为你的初始化参数。其中,可选后端语言有:en-US, zh-CN, zh-TW, ja-JP, id-ID, ko-KR, ru-RU, de-DE, fr-FR, es-ES, vi-VN

      services:
        gzctf:
          image: registry.cn-shanghai.aliyuncs.com/gztime/gzctf:develop
          restart: always
          environment:
            - "GZCTF_ADMIN_PASSWORD=<Your 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 POSTGRES_PASSWORD>"
          volumes:
            - "./data/db:/var/lib/postgresql"
    Info

    你有可能遇到网段冲突的情况,请参考相关更改 compose.yml 中的子网配置或 /etc/docker/daemon.json 中的网段配置。

    networks:
      default:
        driver: bridge
        ipam:
          config:
            - subnet: 192.168.12.0/24
    1. 运行 docker compose up -d 来启动 GZCTF,之后你可以通过浏览器访问 GZCTF 了。

    初始管理员

    生产环境中默认不存在管理员权限用户,需要在首次启动时设置 GZCTF_ADMIN_PASSWORD 环境变量来设置初始管理员密码,并通过 Admin 账号登录。

    你也可以通过手动更改数据库条目来将当前已注册的用户设置为管理员。当管理员注册完成并成功登录后,进入所选数据库表后执行:

    UPDATE "AspNetUsers" SET "Role"=3 WHERE "UserName"='your_admin_user_name';

    你可能会用到如下的命令:

    docker compose exec db psql -U postgres
    psql (15.2)
    Type "help" for help.
    
    postgres=# \c gzctf
    You are now connected to database "gzctf" as user "postgres".
    gzctf=# #do your sql query

    使用 Garnet/Redis 作为缓存

    如果你想使用 Garnet/Redis 作为缓存,获得更无缝的版本切换、服务端重启体验,可以在上述到配置中添加如下内容:

    1. compose.yml 文件

      services:
        gzctf:
          # ...
          depends_on:
            - db
            - cache
      
        cache:
          # It is recommended to use garnet, you can also use redis:alpine
          image: ghcr.io/microsoft/garnet-alpine:latest
          command: ["--bind", "0.0.0.0"]
          restart: always
      
        db:
          # ...
    2. appsettings.json 文件

      {
        "AllowedHosts": "*",
        "ConnectionStrings": {
          // ...
          "RedisCache": "cache:6379,abortConnect=false"
        }
        // ...
      }

    之后重新使用 docker compose up -d 启动 GZCTF 即可。

    容器镜像

    GZCTF 已经预先构建并打包为统一的 Docker 镜像,你可以在 Docker Hub 上找到相关的镜像。

    请使用如下容器注册表获取镜像:

    gztime/gzctf:latest
    ghcr.io/gztimewalker/gzctf/gzctf:latest
    Info

    建议国内用户使用阿里云注册表(仅适用于 2024 年 6 月 20 日之后的版本):

    registry.cn-shanghai.aliyuncs.com/gztime/gzctf:latest

    测试版本和开发版本请使用 develop 镜像标签。

    题目配置

    题目配置和题目示例请见 GZCTF-Challenges 仓库。

    也可以参考和借鉴 W4terCTF 2023 的公开题目仓库,此内的题目均在题目正常工作的情况下尽量保证 Docker Image 的体积足够小,以便于在比赛中快速部署。

    建议使用 GZCTF Challenge Base 镜像作为题目容器的基础镜像,我们尽可能最小化了这些基础镜像,并定期更新;利用他们可以确保题目容器最大限度共享镜像层,减少存储空间占用和镜像拉取时间。

    GZCTF 通过将 GZCTF_FLAG 环境变量注入到容器中来实现动态 flag 的分发,因此请确保题目的容器初始化脚本中将这个环境变量中的文本放入到合适的位置。请注意,这一环境变量的初始化是在容器启动时进行的,而非容器镜像构建时。