{"id":16890390,"url":"https://github.com/jedevc/ctf-infra","last_synced_at":"2025-04-12T02:36:07.637Z","repository":{"id":95489111,"uuid":"274750282","full_name":"jedevc/ctf-infra","owner":"jedevc","description":"Template infrastructure for CTFs :monkey:","archived":false,"fork":false,"pushed_at":"2021-04-09T10:32:23.000Z","size":102,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-12T02:35:35.729Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jedevc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-24T19:15:43.000Z","updated_at":"2022-02-05T11:57:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"83d229cc-09cb-4004-8e5e-0ab1709a5ab7","html_url":"https://github.com/jedevc/ctf-infra","commit_stats":{"total_commits":47,"total_committers":2,"mean_commits":23.5,"dds":0.06382978723404253,"last_synced_commit":"029d6234f65fcbf29cd1da7b1fd056823239b1d7"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedevc%2Fctf-infra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedevc%2Fctf-infra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedevc%2Fctf-infra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedevc%2Fctf-infra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jedevc","download_url":"https://codeload.github.com/jedevc/ctf-infra/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248506974,"owners_count":21115516,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T17:02:50.970Z","updated_at":"2025-04-12T02:36:07.631Z","avatar_url":"https://github.com/jedevc.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CTF Infrastructure\n\nThis is my template infrastructure for Capture the Flag competitions.\n\n## Challenges\n\nThe challenges are managed using [ctftool](https://github.com/jedevc/mini-ctf-tool/),\na home-grown tool for managing challenge metadata and information. See the\nGitHub page for more documentation on the exact formats allowed.\n\nEssentially, all challenges are placed into the `challenges/` directory, and\nshould contain either a `challenge.yaml` or `challenge.json` file.\n\nUseful ctftool commands used in development include:\n\n- Listing:\n  ```\n  $ ./ctftool.py list\n  ```\n- Validation:\n  ```\n  $ ./ctftool.py validate\n  ```\n\n## Deployment\n\nDeploying the CTF should be fairly simple once setup, but can be a little involved.\n\nThere are three options:\n\n- Docker (not recommended)\n- Docker Compose\n- Kubernetes\n\nFor all of them, you'll need to point your DNS records in the right place.\nIt's recommended that if your challenges ues HTTP servers, you should access\nyour challenges over a different domain name than the CTFd instance -\notherwise, browsers will try and be \"clever\" and upgrade you to HTTPS for\nyour challenges\n\n### Docker\n\nThe docker build steps contain basic primitives for building challenge images\nand containers. They probably shouldn't be used on their own, and are\nintended to be used in conjunction with either docker-compose or kubernetes.\n\nBuild the challenge images:\n\n    $ ./deploy/build.py\n\nBuild and push challenge images to a private registry:\n\n    $ export IMAGE_REPO=...\n    $ ./deploy/build.py --push\n\nThe next steps assume that you have configured your machines to automatically\npull from this private registry.\n\n### Docker Compose\n\nDeploying using docker-compose is a more lightweight alternative to building\nand maintaining an entire cluster. However, it will definitely be less\nflexible, so keep that in mind when making a decision.\n\nSet `PYTHONPATH` to the directory containing `ctftool.py` so you can import\nit in other scripts:\n\n    $ export PYTHONPATH=$PWD\n\nCopy the infrastructure code to a build directory:\n\n    $ mkdir -p build\n    $ cp -R deploy/docker-compose/ build/\n\nBuild the build step for the infrastructure:\n\n    $ ./build/docker-compose/generate.sh\n\nLaunch it!\n\n    $ cd build/docker-compose\n    $ docker-compose up\n\n### Kubernetes\n\nTo deploy using Kubernetes, you first need a cluster. Then, once you've\ninstalled the dependencies (listed below), you can install the entire infra.\n\nExport required environment variables (see `.env.sample` for more info):\n\n    $ export DOMAIN=ctfd.example.com\n    $ export CTFD_MYSQL_DB=ctfd\n    $ export CTFD_MYSQL_USER=ctfd\n    $ export CTFD_MYSQL_PASSWORD=password\n    $ export CTFD_REDIS_PASSWORD=password\n    $ export CTFD_SECRET=ctfd\n\n#### Install dependencies\n\n##### Ingress\n\nYou need to install [Nginx Ingress](https://kubernetes.github.io/ingress-nginx/).\n\nThe following installs it *without* a LoadBalancer service, for lower costs.\n\n    $ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx\n    $ helm repo update\n    $ kubectl create namespace ingress-nginx\n    $ helm install ingress ingress-nginx/ingress-nginx \\\n        --namespace ingress-nginx \\\n        --set controller.hostNetwork=true \\\n        --set controller.kind=DaemonSet \\\n        --set controller.hostPort.enabled=true \\\n        --set controller.service.enabled=false \\\n        --set controller.publishService.enabled=false\n\n##### Cert Manager\n\nTo handle TLS certificates, we use [Cert Manager](https://cert-manager.io).\n\n**NOTE**: Make sure that your DNS records are pointing to the right place!\n\nFirst we install it:\n\n    $ helm repo add jetstack https://charts.jetstack.io\n    $ helm repo update\n    $ kubectl create namespace cert-manager\n    $ helm install cert-manager jetstack/cert-manager \\\n        --namespace cert-manager \\\n        --version v1.0.3 \\\n        --set installCRDs=true\n\nThen we need to setup a couple LetsEncrypt issuers (one for staging, one for\nproduction):\n\n```yaml\napiVersion: cert-manager.io/v1\nkind: ClusterIssuer\nmetadata:\n  name: letsencrypt-staging\nspec:\n  acme:\n    server: https://acme-staging-v02.api.letsencrypt.org/directory\n    email: letsencrypt@example.com\n    privateKeySecretRef:\n      name: letsencrypt-staging\n    solvers:\n    - http01:\n        ingress:\n          class: nginx\n---\napiVersion: cert-manager.io/v1alpha2\nkind: ClusterIssuer\nmetadata:\n  name: letsencrypt-prod\nspec:\n  acme:\n    server: https://acme-v02.api.letsencrypt.org/directory\n    email: letsencrypt@example.com\n    privateKeySecretRef:\n      name: letsencrypt-prod\n    solvers:\n    - http01:\n        ingress:\n          class: nginx\n```\n\nWhen you setup the ClusterIssuers, the CTFd instance should automatically be\ngiven a TLS certificate.\n\n#### Build\n\nCopy the infrastructure code to a build directory:\n\n    $ mkdir -p build\n    $ cp -R deploy/kube/ build/\n\nBuild the build step for the infrastructure:\n\n    $ ./build/kube/generate.sh\n\nApply the infrastructure to the cluster:\n  \n    $ kubectl apply -k build/kube/\n\n#### Notes\n\n- The kubernetes infra uses NodePort to expose services ports to the\n  internet. By default this range is 30000-32767, but it's often nice to\n  expose ports lower than that.\n\n  You can modify this range by modifying `apiserver.service-port-range`. For\n  kubeadm, edit `/etc/kubernetes/manifests/kube-apiserver.yaml` and add\n  `--service-node-port-range=\u003clower\u003e-\u003cupper\u003e` to `spec.containers.command`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjedevc%2Fctf-infra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjedevc%2Fctf-infra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjedevc%2Fctf-infra/lists"}