• 简体中文
  • appsettings.json 配置

    appsettings.json 文件是 GZCTF 的核心配置文件,通过挂载入容器内的方式进行配置。本篇将介绍配置文件的各个字段的含义。

    Info

    appsettings.json 的每次更新都需要重启 GZCTF 服务才能生效。

    配置文件结构

    此处给出一个完整的配置文件示例:

    {
      "AllowedHosts": "*",
      "ConnectionStrings": {
        "Database": "Host=db:5432;Database=gzctf;Username=postgres;Password=<Database Password>"
        // redis is optional
        // "RedisCache": "cache:6379,password=<Redis Password>",
        // local disk storage (default) or s3-compatible storage (optional)
        // "Storage": "disk://path=./files" or "s3://accessKey=<YOUR_ACCESS_KEY>;secretKey=<YOUR_SECRET_KEY>;bucket=<YOUR_BUCKET>;region=<YOUR_REGION>"
      },
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        },
        "Loki": {
          "Enable": true,
          "EndpointUri": "http://loki:3100",
          "Labels": [
            {
              "Key": "app",
              "Value": "gzctf"
            }
          ],
          "PropertiesAsLabels": ["app"],
          "Credentials": {
            "Login": "login",
            "Password": "password"
          },
          "Tenant": "my-tenant",
          "MinimumLevel": "Trace"
        }
      },
      "Telemetry": {
        "Prometheus": {
          "Enable": false,
          "TotalNameSuffixForCounters": false
        },
        "OpenTelemetry": {
          "Enable": false,
          "Protocol": "Grpc",
          "EndpointUri": "http://jaeger-collector:4317"
        },
        "AzureMonitor": {
          "Enable": false,
          "ConnectionString": "InstrumentationKey=12345678-abcd-abcd-abcd-12345678..."
        },
        "Console": {
          "Enable": false
        }
      },
      "EmailConfig": {
        "SenderAddress": "",
        "SenderName": "",
        "UserName": "",
        "Password": "",
        "Smtp": {
          "Host": "localhost",
          "Port": 587,
          "BypassCertVerify": false
        }
      },
      "XorKey": "<Random Key Str>",
      "ContainerProvider": {
        "Type": "Docker", // or "Kubernetes"
        "PortMappingType": "Default",
        "EnableTrafficCapture": false,
        "PublicEntry": "ctf.example.com", // or "xxx.xxx.xxx.xxx"
        "DockerConfig": {
          // optional
          "ChallengeNetwork": "",
          "Uri": "unix:///var/run/docker.sock",
          "UserName": "",
          "Password": ""
        },
        "KubernetesConfig": {
          // optional
          "Namespace": "gzctf-challenges",
          "ConfigPath": "kube-config.yaml",
          "AllowCIDR": [
            // allow the cluster CIDR for LB
            "10.0.0.0/8"
          ],
          "DNS": [
            // custom DNS to avoid cluster DNS
            "8.8.8.8",
            "223.5.5.5"
          ]
        }
      },
      "RequestLogging": false,
      "DisableRateLimit": false,
      "Registries": {
        "ghcr.io": {
          "UserName": "...",
          "Password": "ghp_..."
        }
      },
      "CaptchaConfig": {
        "Provider": "None",
        "SiteKey": "...",
        "SecretKey": "...",
        // optional
        "HashPow": {
          "Difficulty": 18
        }
      },
      "ForwardedOptions": {
        "ForwardedHeaders": 7, // a flag enum, see following link
        "ForwardLimit": 1,
        "ForwardedForHeaderName": "X-Forwarded-For",
        // use the following options to allow proxy
        "KnownIPNetworks": ["10.0.0.0/8"],
        "KnownProxies": ["10.0.0.1"]
      },
      "Kestrel": {
        "Limits": {
          "MaxResponseBufferSize": 2048,
          "MaxRequestBufferSize": 1048576,
          "MaxRequestLineSize": 8192,
          "MaxRequestHeadersTotalSize": 32768,
          "MaxRequestHeaderCount": 100,
          "MaxRequestBodySize": 27262946,
          "KeepAliveTimeout": "0.0:5:0",
          "RequestHeadersTimeout": "0.0:5:0",
          "MaxConcurrentConnections": null,
          "MaxConcurrentUpgradedConnections": null
        },
        "AddServerHeader": true,
        "AllowResponseHeaderCompression": true,
        "AllowSynchronousIO": false,
        "AllowAlternateSchemes": false,
        "DisableStringReuse": false,
        "ConfigurationLoader": null
      }
    }

    配置字段

    ConnectionStrings

    此处配置连接字符串

    Database

    必填参数。

    GZCTF 使用 PostgreSQL 作为后端数据库和数据持久化。

    此连接字符串的一般格式为:

    Host=db:5432;Database=gzctf;Username=postgres;Password=<Database Password>

    请将 <Database Password> 替换为你的 PostgreSQL 数据库密码 (通常是通过 POSTGRES_PASSWORD 环境变量设置)

    更多参数可以参考 Npgsql 连接字符串参数文档

    Warning

    PostgreSQL 要求初始密码需要有一定复杂度并且在初始化后不支持再通过环境变量修改密码

    Info

    GZCTF 仅支持 PostgreSQL 作为数据库,不支持 MySQL 等其他数据库。请在配置文件中填写正确的数据库连接字符串。

    RedisCache

    可选参数。

    GZCTF 使用 Redis 作为缓存和消息队列。单实例部署的情况下 Redis 不是必须的,可以直接采用 GZCTF 的内存缓存;多实例部署的情况下,Redis 是必须的,用作共享缓存和 SignalR 的 Scale-Out 广播。

    在 v1.0 后支持使用 Garnet 作为缓存服务。

    Storage

    可选参数。

    GZCTF 支持两种类型的存储提供商:

    • 本地磁盘存储(默认)

      disk://path=./files

      • path:可选。本地文件存储路径(默认值:./files
    • S3 兼容存储 (AWS S3、MinIO、DigitalOcean Spaces 等)

      s3://accessKey=...;secretKey=...;bucket=...;region=...

      或使用特定的协议头以方便使用:

      • aws.s3://... (等同于 s3://...)
      • minio.s3://... (等同于 s3://...)

      参数:

      • accessKey:可选。Access Key ID
      • secretKey:可选。Secret Access Key
      • bucket:Bucket 名称
      • region:区域 (例如 us-east-1)
      • endpoint:可选。自定义端点 URL(用于 MinIO 或其他 S3 兼容服务)
      • useHttp:可选。是否使用 HTTP 而不是 HTTPS(默认值:false)
      • forcePathStyle:可选。是否使用路径风格 URL 而不是虚拟托管风格(默认值:false)

    更多详细内容,请查阅:

    Logging

    此处可以配置日志级别和范围,此外,GZCTF 还支持将日志发送到 Loki 服务器。

    • LogLevel:每个命名空间的最小日志级别。
    • Loki:Loki 服务器的配置。
      • Enable:是否启用。
      • EndpointUri:Loki 服务器的 URI。
      • Labels:可选。全局日志事件标签。
      • PropertiesAsLabels:可选。应映射为 Loki 标签的属性列表。
      • Credentials:可选。将用于基本身份验证的凭据。
      • Tenant:可选。用于向 Loki 服务器发送日志的租户 ID。
      • MinimumLevel:可选。最小日志级别。

    可用的日志级别:Trace, Debug, Information, Warning, Error, Critical, None。

    Telemetry

    GZCTF 支持测量和分布式追踪。您可以配置您想要使用的提供商。

    • Prometheus: Prometheus 支持。

      • Enable: 是否启用。
      • TotalNameSuffixForCounters: 可选。是否在计数器中包含 _total 后缀。
    • OpenTelemetry:将测量和追踪数据导出到 OpenTelemetry。

      • Enable:是否启用。
      • ProtocolGrpcHttpProtobuf
      • EndpointUri:将数据推送到的 OpenTelemetry 地址。
    • AzureMonitor:将测量和追踪数据导出到 ApplicationInsights。

      • Enable:是否启用。
      • ConnectionString:连接字符串。
    • Console:将追踪数据导出到控制台。

      • Enable:是否启用。

    EmailConfig

    此处配置邮件发送相关信息,若采用邮箱注册和其他相关邮件功能,此处为必填项。

    • SenderAddress: 发件人邮箱地址
    • SenderName: 发件人名称
    • UserName: SMTP 服务器用户名
    • Password: SMTP 服务器密码
    • Smtp: SMTP 服务器地址和端口
    • BypassCertVerify: 是否跳过证书验证
    Info

    由于部分云服务厂家限制,可能无法采用 465 端口发送邮件。此时请尝试使用 587 端口。

    XorKey

    此处配置加密密钥,用于加密数据库中比赛的私钥信息,可为任意长度的任意字符串。

    ContainerProvider

    此处配置容器后端,为比赛动态创建容器的必填项。

    • Type: 容器后端类型,可选 DockerKubernetes
    • PublicEntry: 容器后端的公网地址,用于生成比赛的访问地址,展示给参赛队伍。
    • PortMappingType: 端口映射类型,可选 DefaultPlatformProxy
    • EnableTrafficCapture: 是否开启流量捕获,仅在 PortMappingType 设置为 PlatformProxy 时可用。若开启,将会记录流量于 /app/files/capture 目录下。

    Docker

    Warning

    自 v1.8.0 起,Docker Swarm 不再受支持。若需要编排能力,请使用 Kubernetes,以获得更好的安全性和可扩展性。

    • Uri: Docker API Server 地址

      • 如需使用本地 Docker,请将 Uri 置空,并将 /var/run/docker.sock 挂载入容器对应位置
      • 如需使用外部 Docker,请将 Uri 指向对应 Docker API Server,建议配置鉴权
    • ChallengeNetwork:

      v1.8.0 之前

      指定题目容器所在的网络,若不指定,将会使用默认 Docker 网络。

      v1.8.0 之后

      视为用于创建题目网络的网络前缀。GZCTF 会根据不同的网络模式自动创建两个网络:开放网络模式使用 <ChallengeNetwork>-open,隔离网络模式使用 <ChallengeNetwork>-isolated

      你也可以手动创建 <ChallengeNetwork>-custom 网络用于自定义网络模式,并根据需要自行配置。

    • UserName, Password: Docker API Basic Auth 用户名和密码,可选项。

    Kubernetes

    • Namespace: Kubernetes 命名空间,用于创建题目实例的命名空间,默认为 gzctf-challenges
    • ConfigPath: Kubernetes 配置文件路径,用于连接集群,默认为 kube-config.yaml
    • AllowCIDR: 允许访问 Pod 的 CIDR 白名单
    • DNS: 避免使用集群 DNS 的自定义 DNS 服务器列表

    默认行为请将集群连接配置放入 kube-config.yaml 文件中,并将其挂载到 /app 目录下。实验功能若非了解行为请勿更改。

    Info

    请注意更改 kube-config.yaml 文件中的 server 字段,将其指向集群的 API Server 地址。集群默认地址一般为 https://127.0.0.1:6443,需要更改为集群实际地址。

    Info

    v1.8.0 之前

    为了满足基础的网络隔离要求,GZCTF 会在题目的 Namespace 下创建名为 gzctf-policy 的 NetworkPolicy 以限制访问。GZCTF 会自动检测此 NetworkPolicy 是否已经存在,若存在则不会再次创建,因此你可以通过创建或编辑此 NetworkPolicy 来自定义网络策略。

    v1.8.0 之后

    GZCTF 会在题目的 Namespace 下创建名为 gzctf-network-opengzctf-network-isolated 的两个 NetworkPolicy,分别用于开放网络模式和隔离网络模式的访问控制。GZCTF 会自动维护这两个 NetworkPolicy,请不要手动修改或删除。

    你可以通过在同一 Namespace 下创建额外的 NetworkPolicy 来实现自定义网络策略。可以使用以下标签选择目标 Pod:

    • gzctf.gzti.me/TeamId:选择特定队伍
    • gzctf.gzti.me/UserId:选择特定用户
    • gzctf.gzti.me/ChallengeId:选择特定题目
    • gzctf.gzti.me/NetworkMode:选择特定网络模式(openisolatedcustom

    RequestLogging

    此处配置是否开启请求日志记录,若开启,将会在日志中输出每个请求的详细信息。此处输出不包括静态文件的请求。

    Warning

    此配置项会记录请求的具体信息,大幅影响 日志文件大小及平台并发性能,请仅在调试时开启。

    DisableRateLimit

    此处配置是否开启请求频率限制,若开启,将会根据预设规则限制每个 IP 和 API 的请求频率。

    Danger

    此配置为平台安全性基础,在非测试环境下关闭后果自负。

    在绝大多数正确配置的情况下,不存在用户能够达到速率限制的情况。若在正常使用过程中出现频繁触发速率限制、后端日志的 IP 信息异常(如大量来自同一 IP 的请求),请检查 反向代理中可信代理相关配置

    在此项配置启用的情况下,GZCTF 可以使用极少的资源防止数十倍于正常请求的恶意请求,保障平台的正常运行。

    RegistryConfig

    Warning

    此配置项即将被弃用,请使用 Registries 配置项进行配置。

    Registries

    此处配置 Docker Registry 的用户名和密码,用于比赛动态创建容器时拉取镜像的验证,可选项。

    "Registries": {
      "ghcr.io": {
        "UserName": "...",
        "Password": "ghp_..."
      },
      "docker.io": {
        "UserName": "...",
        "Password": "..."
      },
      "your.custom.registry": {
        "UserName": "...",
        "Password": "..."
      }
    }
    Info

    请确保密码中不包含特殊字符(如 ":@ 等,但是可以使用 _),否则可能导致模板注入问题,导致 Secret 创建失败。

    CaptchaConfig

    此处配置验证码相关信息,用于注册、找回账号和登录时的验证码验证,可选项。

    • Provider: 验证码提供商,可选 NoneHashPowCloudflareTurnstile
    • SiteKey: 验证码 Sitekey
    • SecretKey: 验证码 Secretkey
    Tip

    为确保安全性、避免平台被恶意注册、消耗邮件额度等问题,强烈建议开启验证码功能。

    建议首选 CloudflareTurnstile 验证码提供商,相关文档

    HashPow

    配置 HashPow 验证码的相关信息,可选项。

    Info

    安全上下文: 此项功能仅在一些支持的浏览器的安全上下文(HTTPS)中可用。

    • Difficulty: HashPow 验证码的难度,用于指定哈希二进制前导零位数,范围为 8 至 48。

    GoogleRecaptcha

    DEPRECATED

    由于上游依赖缺少维护,此功能已弃用,并将从 v1.2.2 开始删除。

    请使用 CloudflareTurnstile 作为验证码提供商。

    配置 Google Recaptcha v3 的相关信息,可选项。

    • VerifyAPIAddress: Google Recaptcha 验证 API 地址
    • RecaptchaThreshold: Google Recaptcha 阈值,用于判断验证码是否有效

    ForwardedOptions

    此处配置反向代理的相关信息,用于获取真实 IP 地址,可选项。

    • ForwardedHeaders: 反向代理转发的标头枚举,默认请使用 7,详情请见 ForwardedHeaders 枚举
    • ForwardLimit: 反向代理层数限制
    • ForwardedForHeaderName: 反向代理 IP 地址头名称
    • KnownIPNetworks: 反向代理信任的网络列表,使用 CIDR 表示
    • KnownProxies: 反向代理信任的代理列表,使用 IP 地址或域名表示
    Info

    若想要忽略反向代理的信任列表,允许任意 IP 地址访问,请参考转发 Linux 和非 IIS 反向代理的方案,设置环境变量 ASPNETCORE_FORWARDEDHEADERS_ENABLEDtrue

    其他字段请参考官方文档描述:配置 ASP.NET Core 以使用代理服务器和负载均衡器ForwardedHeadersOptions 类

    Kestrel

    在绝大多数情况下,你不需要修改此配置。

    Kestrel 为 GZCTF 自带并使用的 Web 服务器。

    利用此配置可以自行控制 Kestrel 的行为,例如指定 HTTP 协议、修改请求大小上限等等。

    可配置字段请参照官方文档中 KestrelServerOptions 类的属性:KestrelServerOptions 类