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>",
    // external storage (minio s3, aws s3, azure blob) is optional, aws s3 for example
    // "Storage": "minio.s3://keyId=<YOUR_KEY_ID>;key=<YOUR_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,
      "Port": 3000,
      "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
      "SwarmMode": false,
      "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,
  "RegistryConfig": {
    "UserName": "",
    "Password": "",
    "ServerAddress": ""
  },
  "CaptchaConfig": {
    "Provider": "None",
    "SiteKey": "...",
    "SecretKey": "...",
    // optional
    "GoogleRecaptcha": {
      "VerifyAPIAddress": "https://www.recaptcha.net/recaptcha/api/siteverify",
      "RecaptchaThreshold": "0.5"
    },
    // 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
    "TrustedNetworks": ["10.0.0.0/8"],
    "TrustedProxies": ["10.0.0.1"]
  },
  "Kestrel": {
    "Endpoints": {
      "Web": {
        "Url": "http://*:8080"
      },
      "Prometheus": {
        "Url": "http://*:3000"
      }
    },
    "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 をバックエンドデータベースおよびデータ永続化に使用します。

INFO

GZCTF はデータベースとして PostgreSQL のみをサポートしており、MySQL などの他のデータベースはサポートしていません。設定ファイルに正しいデータベース接続文字列を記入してください。

RedisCache

このフィールドはオプションです。

GZCTFはRedis をキャッシュおよびメッセージキューとして使用します。単一インスタンスのデプロイでは Redis は必須ではなく、GZCTF のメモリキャッシュを直接使用できます。複数インスタンスのデプロイでは、Redis は必須であり、共有キャッシュおよび SignalR の Scale-Out ブロードキャストとして使用されます。

v1.0以降、GZCTFはガーネットをキャッシュサービスとして使用することをサポートしています。

Storage

このフィールドはオプションです。

GZCTFはAWS S3やAzure Blob Storageなどの外部ストレージサービスをサポートしています。ファイルやその他のデータを保存するためにストレージサービスを構成できます。

  • MinIO S3

    minio.s3://keyId=...;key=...;bucket=...;region=...;serviceUrl=...

    • keyId: 任意。Access Key ID
    • key: 任意。Secret Access Key
    • bucket: Bucket 名
    • region: リージョン(例:us-east-1
    • serviceUrl:MinIO サーバーの URL。
  • AWS S3

    aws.s3://keyId=...;key=...;bucket=...;region=...

    • keyId: 任意。Access Key ID
    • key: 任意。Secret Access Key
    • bucket: Bucket 名
    • region: リージョン(例:us-east-1
    • serviceUrl: 任意。ストレージプロバイダーのURL(例:DigitalOcean用)。
  • Azure Blob

    azure.file://account=...;key=...

    詳細については、クイックスタート: .NET 用 Azure Blob Storage クライアント ライブラリを参照してください。

詳細については、以下のリンクを参照してください:

より多くのFluentStorageプロバイダを使いたい場合は、issueを開いてください。

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: 有効にするかどうか。
    • Port: 任意。Prometheus の /metrics エンドポイントがリッスンするポート。これが設定されている場合、サーバーが指定されたポートを正常にリッスンするようにするには、Kestrel.Endpoints を手動で追加設定する必要があります。
    • TotalNameSuffixForCounters: 任意。カウンタに _total サフィックスを含めるかどうか。
  • OpenTelemetry: メトリクスとトレーシングデータを OpenTelemetry にエクスポートします。

    • Enable: 有効にするかどうか。
    • Protocol: Grpc または HttpProtobuf
    • EndpointUri: テレメトリーデーターがプッシュされる OpenTelemetry エンドポイント URI。
  • AzureMonitor: メトリクスとトレーシングデータを ApplicationInsights にエクスポートします。

    • Enable: 有効にするかどうか。
    • ConnectionString: 接続文字列。
  • Console: トレーシングデータをコンソールにエクスポートします。

    • Enable: 有効にするかどうか。

EmailConfig

ここではメール送信に関する情報を設定します。メールでの登録やその他のメール機能を使用する場合、この項目は必須です。

  • SenderAddress: 送信者のメールアドレス
  • SenderName: 送信者の名前
  • UserName: SMTP サーバーのユーザー名
  • Password: SMTP サーバーのパスワード
  • Smtp: SMTP サーバーのアドレスとポート
  • BypassCertVerify: 証明書の検証をバイパスするかどうか
INFO

一部のクラウドサービスプロバイダの制限により、465 ポートを使用してメールを送信できない場合があります。その場合は、587 ポートを試してみてください。

XorKey

ここでは暗号化キーを設定します。これは、データベース内のゲームの秘密鍵情報を暗号化するために使用されます。任意の長さの任意の文字列を使用できます。

ContainerProvider

ここではコンテナバックエンドを設定します。これは、ゲームで動的にコンテナを作成するための必須項目です。

  • Type: コンテナバックエンドのタイプ。DockerまたはKubernetesを選択できます。
  • PublicEntry: コンテナバックエンドの公開アドレス。これは、ゲームのアクセスアドレスを生成し、参加チームに表示するために使用されます。
  • PortMappingType: ポートマッピングのタイプ。DefaultまたはPlatformProxyを選択できます。
  • EnableTrafficCapture: トラフィックキャプチャを有効にするかどうか。PortMappingTypePlatformProxyに設定されている場合のみ使用できます。有効にすると、/app/files/captureディレクトリにトラフィックが記録されます。

Docker

  • SwarmMode: Swarm モードかどうか。Swarm モードの場合、Swarm API を使用して管理します。
WARNING

Docker Swarm はもはや活発なプロジェクトではなく、k8s と比較してセキュリティ機能に大きな差があるため、使用は推奨されません。

  • Uri: Docker API Server のアドレス

    • ローカルの docker を使用する場合は、Uri を空にし、/var/run/docker.sockをコンテナの対応する位置にマウントします。
    • 外部の docker を使用する場合は、Uri を対応する docker API Server に指定します。外部 API の認証はまだ実装されていませんので、このデプロイ方法は推奨されません。
  • ChallengeNetwork: チャレンジコンテナが所属するネットワークを指定します。指定しない場合は、デフォルトのネットワークを使用します。

  • 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

ネットワークポリシーを満たすために、GZCTF はチャレンジの Namespace にgzctf-policyという名前の NetworkPolicy を作成してアクセスを制限します。GZCTF はこの NetworkPolicy が既に存在するかどうかを自動的に検出し、存在する場合は再作成しません。そのため、ネットワークポリシーをカスタマイズするには、この NetworkPolicy を作成または編集してください。

RequestLogging

ここでは、リクエストログの記録を有効にするかどうかを設定します。有効にすると、ログに各リクエストの詳細情報が出力されます。この出力には静的ファイルのリクエストは含まれません。

DisableRateLimit

ここでは、リクエストの頻度制限を有効にするかどうかを設定します。有効にすると、事前に設定したルールに基づいて、各 IP と API のリクエスト頻度が制限されます。

RegistryConfig

ここでは Docker Registry のユーザー名とパスワードを設定します。これは、ゲームで動的にコンテナを作成する際にイメージをプルするための認証で、オプションです。

  • UserName: Docker Registry のユーザー名
  • Password: Docker Registry のパスワード
  • ServerAddress: Docker Registry のアドレス。https://のプレフィックスは含めないでください。
INFO

パスワードに特殊文字(":@など、ただし_は使用可能)が含まれていないことを確認してください。そうでないと、テンプレートインジェクションの問題が発生し、Secret の作成に失敗する可能性があります。

CaptchaConfig

ここでは、キャプチャ関連の情報を設定します。これは、登録、アカウントの回復、ログイン時のキャプチャの検証に使用されます。オプションです。

  • Provider: キャプチャのプロバイダ。NoneHashPowGoogleRecaptcha、またはCloudflareTurnstileを選択できます。
  • SiteKey: キャプチャの Sitekey
  • SecretKey: キャプチャの Secretkey

HashPow

HashPow キャプチャの関連情報を設定します。オプションです。

INFO

安全なコンテキスト用: この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

  • Difficulty: HashPow キャプチャの難易度。ハッシュビットの先頭にあるゼロの数を指定するために使用されます。利用可能な範囲は 8 から 48 です。

GoogleRecaptcha

Google Recaptcha v3 の関連情報を設定します。オプションです。

  • VerifyAPIAddress: Google Recaptcha の検証 API アドレス
  • RecaptchaThreshold: Google Recaptcha の閾値。キャプチャが有効かどうかを判断するために使用します。

ForwardedOptions

ここでは、リバースプロキシの関連情報を設定します。これは、実際の IP アドレスを取得するために使用されます。オプションです。

  • ForwardedHeaders: リバースプロキシが転送するヘッダーの列挙型。デフォルトは7を使用してください。詳細は ForwardedHeaders 列挙型を参照してください。
  • ForwardLimit: リバースプロキシの層数制限
  • ForwardedForHeaderName: リバースプロキシの IP アドレスヘッダー名
  • TrustedNetworks: リバースプロキシが信頼するネットワークのリスト。CIDR で表現します。
  • TrustedProxies: リバースプロキシが信頼するプロキシのリスト。IP アドレスまたはドメイン名で表現します。
INFO

リバースプロキシの信頼リストを無視し、任意の IP アドレスからのアクセスを許可したい場合は、Linux および非 IIS のリバース プロキシのスキームを転送するを参照し、環境変数ASPNETCORE_FORWARDEDHEADERS_ENABLEDtrueに設定してください。

他のフィールドについては、公式ドキュメントの説明を参照してください:プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成するおよびForwardedHeadersOptions クラス

Kestrel

Kestrel は GZCTF が内蔵して使用している Web サーバーです。この設定を利用すると、HTTP プロトコルを指定したり、リクエストのサイズ上限を変更したりと、Kestrel の動作を自由に制御することができます。