├── README.md ├── docker-compose-production.yml ├── dummycrt.sh ├── nginx.conf ├── run-tls.sh ├── run.sh ├── setupenv.sh └── ssl └── README.md /README.md: -------------------------------------------------------------------------------- 1 | # CTFd-docker-deploy 2 | Repository to deploy CTFd using docker. 3 | 4 | Brief instructions follow but you can also refer [to a blogpost](https://joshcgrossman.com/2018/03/15/setting-up-an-owasp-juice-shop-ctf/) about how I used this setup . 5 | 6 | ## How to use this repository to start a CTFd instance without TLS 7 | 8 | 1. Clone this repository by running `git clone https://github.com/tghosth/CTFd-docker-deploy.git`. 9 | 2. Go into the directory which the repository was cloned into (`CTFd-docker-deploy` by default) 10 | 3. Either: 11 | 1. Install `docker` based on the instructions [here](https://docs.docker.com/install/). 12 | 2. Install `docker-compose` based on the instructions [here](https://docs.docker.com/compose/install/#install-compose). 13 | 3. Copy the contents of the https://github.com/CTFd/CTFd repository into this `CTFd-docker-deploy` folder. 14 | 4. Or: 15 | 1. Run the `setupenv.sh` script from this folder. 16 | 5. Run `run.sh` or `docker-compose up`. 17 | 18 | ## How to use this repository to start a CTFd instance with TLS 19 | 20 | 1. Follow steps 1 to 4 from the previous section. 21 | 2. Setup your DNS records to point to the server where you are starting CTFd. 22 | 3. Get a TLS certificate and private key from a Certificate Authority and save them as `ctfd.crt` and `ctfd.key` respectively in the `ssl` directory in your cloned repository. 23 | 4. Edit the `hostname` line in the `docker-compose-production.yml` file to match the hostname you have defined to point to this server. 24 | 5. Run `run-tls.sh` or `docker-compose -f docker-compose.yml -f docker-compose-production.yml up`. 25 | -------------------------------------------------------------------------------- /docker-compose-production.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | nginx: 5 | image: nginx:1.17 6 | restart: always 7 | # Included NGINX config used hostname to determine what it's server_name will be 8 | # Either set NGINX_HOSTNAME to it's public DNS name, change this line, or the config 9 | hostname: localhost 10 | ports: 11 | - "443:8443" 12 | volumes: 13 | - ./ssl:/etc/ssl:ro # Change this to match where your certificates are. Look at and adjust names in nginx.conf 14 | - ./nginx.conf:/etc/nginx/nginx.conf:ro 15 | - .data/nginx/logs:/var/log/nginx 16 | networks: 17 | default: 18 | internal: 19 | depends_on: 20 | - ctfd 21 | -------------------------------------------------------------------------------- /dummycrt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | openssl req -new -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out ./ssl/ctfd.crt -keyout ./ssl/ctfd.key 3 | -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | user nobody nogroup; pid /tmp/nginx.pid; error_log /var/log/nginx/error.log; 2 | # Best set to 1 as long as CTFd is served up from the same host 3 | worker_processes 1; events { 4 | worker_connections 1024; # increase if you have lots of clients 5 | accept_mutex off; # set to 'on' if nginx worker_processes > 1 6 | use epoll; # a fast event mechanism for Linux 2.6+ 7 | } 8 | http { 9 | include mime.types; 10 | # fallback in case we can't determine a type 11 | default_type application/octet-stream; 12 | access_log /var/log/nginx/access.log combined; 13 | # Set up a generous ssl session cache to reduce overhead 14 | ssl_session_cache shared:SSL:10m; 15 | ssl_session_timeout 10m; 16 | # Disable delayed sending of small packets 17 | tcp_nodelay on; 18 | upstream ctfd_app { 19 | #fail_timeout=0 always retry ctfd even if it failed 20 | server ctfd:8000 fail_timeout=0; 21 | } 22 | server { 23 | # if no Host match, close the connection to prevent host spoofing 24 | listen 80 default_server; 25 | return 444; 26 | } 27 | server { 28 | listen 8443 ssl deferred; 29 | # You must either change this line or set the hostname of the server (e.g. through docker-compose.yml) for correct serving and ssl to be accepted 30 | server_name $hostname; 31 | # SSL settings: Ensure your certs have the correct host names 32 | ssl_certificate /etc/ssl/ctfd.crt; 33 | ssl_certificate_key /etc/ssl/ctfd.key; 34 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 35 | ssl_ciphers HIGH:!aNULL:!MD5; 36 | # Set connections to timout in 5 seconds 37 | keepalive_timeout 5; 38 | location / { 39 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 40 | proxy_set_header X-Forwarded-Proto https; 41 | proxy_set_header Host $http_host; 42 | proxy_redirect off; 43 | proxy_buffering off; 44 | proxy_pass http://ctfd_app; 45 | } 46 | } 47 | # Redirect clients from HTTP to HTTPS 48 | server { 49 | listen 80; 50 | server_name $hostname; 51 | return 301 https://$server_name$request_uri; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /run-tls.sh: -------------------------------------------------------------------------------- 1 | docker-compose -f docker-compose.yml -f docker-compose-production.yml up -d 2 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | docker-compose up -d 2 | -------------------------------------------------------------------------------- /setupenv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "" 3 | read -p "Before you run, check the latest compose version at: https://docs.docker.com/compose/install/" 4 | echo "First this will clone a pinned version of the CTFd repository" 5 | git clone --single-branch https://github.com/CTFd/CTFd.git CTFdTEMP 6 | mv ./CTFdTEMP/* ./ 7 | rm -rf ./CTFdTEMP 8 | sudo apt-get remove docker docker-engine docker.io containerd runc 9 | sudo apt-get update -y 10 | sudo apt-get install \ 11 | apt-transport-https \ 12 | ca-certificates \ 13 | curl \ 14 | gnupg-agent \ 15 | software-properties-common -y 16 | 17 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 18 | sudo apt-key fingerprint 0EBFCD88 19 | echo "" 20 | echo "The fingerprint above should match:" 21 | echo "pub rsa4096 2017-02-22 [SCEA]" 22 | echo " 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88" 23 | echo "uid [ unknown] Docker Release (CE deb) " 24 | echo "sub rsa4096 2017-02-22 [S]" 25 | echo "" 26 | read -p "" 27 | 28 | echo "" 29 | sudo add-apt-repository \ 30 | "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ 31 | $(lsb_release -cs) \ 32 | stable" 33 | sudo apt-get update -y 34 | sudo apt-get install docker-ce docker-ce-cli containerd.io -y 35 | sudo usermod -aG docker ubuntu 36 | sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 37 | sudo chmod +x /usr/local/bin/docker-compose 38 | docker-compose --version 39 | sudo apt-get update -y 40 | sudo apt-get install software-properties-common -y 41 | sudo add-apt-repository universe 42 | sudo add-apt-repository ppa:certbot/certbot 43 | sudo apt-get update -y 44 | sudo apt-get install certbot -y 45 | echo "" 46 | read -p "You should now logout and login again!" 47 | 48 | -------------------------------------------------------------------------------- /ssl/README.md: -------------------------------------------------------------------------------- 1 | You can put your SSL certificate and private key here in production mode 2 | --------------------------------------------------------------------------------