|
1 | | -schema reference |
| 1 | +# `challenge.yaml` Reference |
| 2 | + |
| 3 | +[[toc]] |
| 4 | + |
| 5 | +## `name` |
| 6 | + |
| 7 | +The name of the challenge, as shown to players in the frontend UI. |
| 8 | + |
| 9 | +```yaml |
| 10 | +name: notsh |
| 11 | + |
| 12 | +# can have spaces: |
| 13 | +name: Revenge of the FIPS |
| 14 | +``` |
| 15 | +
|
| 16 | +## `author` |
| 17 | + |
| 18 | +Author or authors of the challenge, as shown to players in the frontend UI. If there are multiple authors, specify them as one string. |
| 19 | + |
| 20 | +```yaml |
| 21 | +author: John Author |
| 22 | +
|
| 23 | +# multiple authors: |
| 24 | +author: Alice, Bob, and others |
| 25 | +``` |
| 26 | + |
| 27 | +## `description` |
| 28 | + |
| 29 | +Description and flavortext for the challenge, as shown to players in the frontend UI. Supports templating to include information about the challenge, such as the link or command to connect. |
| 30 | + |
| 31 | +| Available fields | Description | |
| 32 | +| ---------------- | -------------------------------------------------------------------------------------------------------------- | |
| 33 | +| `domain` | The domain/hostname the challenge is listening on <br> (`<subdomain>.chals.example.ctf`) | |
| 34 | +| `port` | The port that the challenge is listening on | |
| 35 | +| `nc` | The `nc` command to connect to TCP challenges, with Markdown backticks <br> (`` `nc {{domain}} {{port}}` ``) | |
| 36 | +| `url` | The URL to the exposed web domain for web challenges, plus port if needed <br> (`https://{{domain}}:{{port}}`) | |
| 37 | +| `link` | Create a Markdown link to `url` | |
| 38 | +| `challenge` | The full challenge.yaml config object for this challenge, with subfields | |
| 39 | + |
| 40 | +```yaml |
| 41 | +description: | |
| 42 | + Some example challenge. Blah blah blah flavor text. |
| 43 | +
|
| 44 | + In case you missed it, this was written by {{ challenge.author }} |
| 45 | + and is called {{ challenge.name }}. |
| 46 | +
|
| 47 | + {{ link }} # -becomes-> [https://somechal.chals.example.ctf](https://somechal.chals.example.ctf) |
| 48 | + {{ nc }} # -becomes-> `nc somechal.chals.example.ctf 12345` |
| 49 | +``` |
| 50 | + |
| 51 | +## `category` |
| 52 | + |
| 53 | +The category for the challenge. |
| 54 | + |
| 55 | +::: warning |
| 56 | +Automatically set! This is set from the expected directory structure of `<category>/<challenge>/challenge.yaml` and overwrites whatever is set in the file. |
| 57 | +::: |
| 58 | + |
| 59 | +## `difficulty` |
| 60 | + |
| 61 | +::: info |
| 62 | +Not implemented yet, does nothing |
| 63 | +::: |
| 64 | + |
| 65 | +The difficulty from the challenge, used to set point values. Values correspond to entries in the [rcds.yaml difficulty settings](/for-sysadmins/config#difficulty). |
| 66 | + |
| 67 | +```yaml |
| 68 | +difficulty: 1 # the current default |
| 69 | +``` |
| 70 | +
|
| 71 | +## `flag` |
| 72 | + |
| 73 | +Where to find the flag for the challenge. The flag can be in a file, a regex, or a direct string. |
| 74 | + |
| 75 | +```yaml |
| 76 | +# directly set (equivalent) |
| 77 | +flag: ctf{example-flag} |
| 78 | +flag: |
| 79 | + string: ctf{example-flag} |
| 80 | +
|
| 81 | +# from a file in in the challenge directory |
| 82 | +flag: |
| 83 | + file: flag |
| 84 | +
|
| 85 | +# regex |
| 86 | +flag: |
| 87 | + regex: /ctf\{(foo|bar|baz+)\}/ |
| 88 | +``` |
| 89 | + |
| 90 | +::: info |
| 91 | +Regex flags are not implemented yet and setting one does nothing |
| 92 | +::: |
| 93 | + |
| 94 | +## `provide` |
| 95 | + |
| 96 | +List of files to provide to the players on the frontend UI. These files can be from the challenge directory or from a container image built for a [challenge pod](#pods), and uploaded individually or zipped together. |
| 97 | + |
| 98 | +If there are no files to upload for this challenge, this can be omitted or set to an empty array. |
| 99 | + |
| 100 | +```yaml |
| 101 | +provide: |
| 102 | + # files from the challenge folder in the repo |
| 103 | + - somefile.txt |
| 104 | + - otherfile.txt |
| 105 | +
|
| 106 | + # rename a really long name as something shorter during upload |
| 107 | + - as: short.h |
| 108 | + include: some_really_long_name.h |
| 109 | +
|
| 110 | + # multiple files from src/ in the challenge folder, zipped as together.zip |
| 111 | + - as: together.zip |
| 112 | + include: |
| 113 | + - src/file1 |
| 114 | + - src/file2 |
| 115 | + - src/file3 |
| 116 | +
|
| 117 | + # multiple files pulled from the container image for the `main` pod, |
| 118 | + # uploaded individually as `notsh` and `libc.so.6` |
| 119 | + - from: main |
| 120 | + include: |
| 121 | + - /chal/notsh |
| 122 | + - /lib/x86_64-linux-gnu/libc.so.6 |
| 123 | + |
| 124 | + # single file pulled from the main container and renamed |
| 125 | + - from: main |
| 126 | + as: libc.so |
| 127 | + include: /lib/x86_64-linux-gnu/libc.so.6 |
| 128 | + |
| 129 | + # multiple files pulled from the main container and zipped together |
| 130 | + - from: main |
| 131 | + as: notsh.zip |
| 132 | + include: |
| 133 | + - /chal/notsh |
| 134 | + - /lib/x86_64-linux-gnu/libc.so.6 |
| 135 | + |
| 136 | + |
| 137 | +# if no files need to be provided: |
| 138 | +provide: [] |
| 139 | +# or omit entirely |
| 140 | +``` |
| 141 | + |
| 142 | +### `.include` |
| 143 | + |
| 144 | +File or list of files to upload individually, or include in a zip if `as` is set. |
| 145 | + |
| 146 | +When uploading, only the basename is used and the path to the file is discarded. |
| 147 | + |
| 148 | +### `.as` |
| 149 | + |
| 150 | +If `include` is a single file, rename to the given name while uploading. |
| 151 | +If multiple files, zip them together into the given zip file. |
| 152 | + |
| 153 | +### `.from` |
| 154 | + |
| 155 | +Fetch these files from the corresponding [challenge pod](#pods) image. |
| 156 | + |
| 157 | +## `pods` |
| 158 | + |
| 159 | +Defines how to build and deploy any services needed for the challenge. |
| 160 | + |
| 161 | +Challenge pods can be built from a local Dockerfile in the challenge folder or use an upstream image directly. |
| 162 | + |
| 163 | +If there are no pods or images needed for this challenge, this can be omitted or set to an empty array. |
| 164 | + |
| 165 | +```yaml |
| 166 | +pods: |
| 167 | + - name: main |
| 168 | + build: . |
| 169 | + ports: |
| 170 | + - internal: 1337 # expose a container listening on port 1337 ... |
| 171 | + expose: |
| 172 | + http: examplechal # as a web chal at https://examplechal.<chals_domain> |
| 173 | + |
| 174 | + - name: db |
| 175 | + image: postgres:alpine |
| 176 | + architecture: arm64 |
| 177 | + env: |
| 178 | + POSTGRES_USER: someuser |
| 179 | + POSTGRES_PASSWORD: notsecure |
| 180 | + |
| 181 | +# if no containers or pods need to be deployed: |
| 182 | +pods: [] |
| 183 | +# or omit entirely |
| 184 | +``` |
| 185 | + |
| 186 | +### `.name` |
| 187 | + |
| 188 | +Name of the pod, used to refer to this container as [a source for `provide` files](#provide) and for generated resource names. |
| 189 | + |
| 190 | +Cannot contain spaces or punctuation, only alphanumeric and `-`. |
| 191 | + |
| 192 | +### `.build` |
| 193 | + |
| 194 | +Build the container image for this pod from a local `Dockerfile`. Supports a subset of the [docker-compose build spec](https://docs.docker.com/reference/compose-file/build/#illustrative-example) (`dockerfile`, `context`, `args`). |
| 195 | + |
| 196 | +Conflicts with [`image`](#image). |
| 197 | + |
| 198 | +```yaml |
| 199 | + # build a container from a Dockerfile in the challenge folder |
| 200 | + build: . |
| 201 | + |
| 202 | + # equivalent to the above but with explicit build context and Dockerfile name |
| 203 | + build: |
| 204 | + context: . |
| 205 | + dockerfile: Dockerfile |
| 206 | + |
| 207 | + # build from a subfolder with a custom Dockerfile and some build args |
| 208 | + build: |
| 209 | + context: src/ |
| 210 | + dockerfile: Containerfile.remote |
| 211 | + args: |
| 212 | + CC_OPTS: "-Osize" |
| 213 | +``` |
| 214 | +
|
| 215 | +### `.image` |
| 216 | + |
| 217 | +Use an available container image for the pod instead of building one from source. |
| 218 | + |
| 219 | +Conflicts with [`build`](#build). |
| 220 | + |
| 221 | +### `.env` |
| 222 | + |
| 223 | +Any environment variables to set for the running pod. Specify as `name: value`. |
| 224 | + |
| 225 | +```yaml |
| 226 | + env: |
| 227 | + SOME_ENVVAR: foo bar |
| 228 | +``` |
| 229 | + |
| 230 | +### `.architecture` |
| 231 | + |
| 232 | +Set the desired CPU architecture to run this pod on. |
| 233 | + |
| 234 | +```yaml |
| 235 | + architecture: amd64 # AKA x86_64; the default |
| 236 | + architecture: arm64 # for ARM |
| 237 | +``` |
| 238 | + |
| 239 | +### `.resources` |
| 240 | + |
| 241 | +The resource usage request and limits for the pod. Kubernetes will make sure the requested resources will be available for this pod to use, and will also restart the pod if it goes over these limits. |
| 242 | + |
| 243 | +If not set, the default set in [`rcds.yaml`](config#rcds.yaml) is used. |
| 244 | + |
| 245 | +### `.replicas` |
| 246 | + |
| 247 | +How many instances of the pod to run. Traffic is load-balanced between instances. |
| 248 | + |
| 249 | +Default is 2 and this is probably fine unless the challenge is very resource intensive. |
| 250 | + |
| 251 | +```yaml |
| 252 | + replicas: 2 # the default |
| 253 | +``` |
| 254 | + |
| 255 | +### `.ports` |
| 256 | + |
| 257 | +### `.volume` |
0 commit comments