With the upcoming 2018 CTF and Coding challenges. We’ll be needing a tool to manage teams, scoring, and challenges. Enter FB-CTF.
What is FBCTF?
The Facebook CTF is a platform to host Jeopardy and “King of the Hill” style Capture the Flag competitions.
How do I use FBCTF?
- Organize a competition. This can be done with as few as two participants, all the way up to several hundred. The participants can be physically present, active online, or a combination of the two.
- Follow setup instructions below to spin up platform infrastructure.
- Enter challenges into admin page
- Have participants register as teams
Community Grid Dashboard (portainer)
After logging in to communitygrid.dallasmakerspace.org. Onew would navigate to stacks then fill out the web editor with the following docker-compose.yml
Include the following environment variables.
Config ENV
MYSQL_ROOT_PASSWORD | (string) random string from 14-24 characters long |
MYSQL_PASSWORD | (string) random string from 14-24 characters long |
docker-compose.yml
---
version: "3.6"
services:
autoscale:
image: gianarb/orbiter:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
DOCKER_HOST: unix:///var/run/docker.sock
ports:
- target: 8000
protocol: "tcp"
mode: "ingress"
deploy:
restart_policy:
condition: on-failure
mode: replicated
replicas: 1
labels:
com.centurylinklabs.watchtower.enable: "true"
orbiter: "false"
traefik.enable: "true"
traefik.port: 8000
traefik.network: public
traefik.frontend.priority: 10
traefik.frontend.rule: 'Host:scaler.local'
traefik.backend: "scaler"
placement:
constraints: [node.role == manager]
networks:
- public
watchtower:
image: 'v2tec/watchtower:latest'
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --label-enable --interval 30 --cleanup
deploy:
restart_policy:
condition: on-failure
mode: replicated
replicas: 1
labels:
com.centurylinklabs.watchtower.enable: "true"
traefik.enable: "false"
placement:
constraints: [node.role == manager]
traefik:
image: traefik:1.5
command: --web --docker --docker.swarmmode --docker.watch --docker.domain=local --logLevel=DEBUG --api
deploy:
placement:
constraints: [node.role==manager]
restart_policy:
condition: on-failure
labels:
traefik.port: "8080"
traefik.docker.network: "public"
traefik.frontend.rule: "Host:traefik.local"
traefik.entryPoints.http.redirect: "https"
ports:
- target: 443
published: 443
protocol: "tcp"
mode: "ingress"
- target: 80
published: 80
protocol: "tcp"
mode: "ingress"
- target: 8080
published: 8080
protocol: "tcp"
mode: "host"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /dev/null:/traefik.toml
networks:
public:
aliases:
- gateway
portainer:
ports:
- target: 9000
protocol: "tcp"
mode: "ingress"
image: portainer/portainer:latest
networks:
- public
- default
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
deploy:
restart_policy:
condition: on-failure
mode: replicated
replicas: 1
placement:
constraints: [node.role == manager]
labels:
com.centurylinklabs.watchtower.enable: "true"
traefik.frontend.rule: "HostRegexp:{catchall:.*}"
traefik.frontend.priority: "1"
traefik.backend: "dashboard"
traefik.docker.network: "public"
traefik.port: "9000"
traefik.enable: "true"
traefik.default.protocol: "http"
agent:
image: portainer/agent:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- target: 9001
published: 9001
protocol: tcp
mode: host
environment:
AGENT_CLUSTER_ADDR: tasks.agent
networks:
- default
deploy:
mode: global
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
labels:
com.centurylinklabs.watchtower.enable: "true"
orbiter: "false"
traefik.enable: "false"
mysql:
ports:
- target: 3306
protocol: tcp
mode: "ingress"
image: mysql:5.7
environment:
- MYSQL_DATABASE=ctf2018
- MYSQL_USER=ctf2018
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
networks:
default:
aliases:
- mysql
deploy:
restart_policy:
condition: on-failure
replicas: 1
mode: replicated
labels:
com.centurylinklabs.watchtower.enable: "true"
orbiter: "false"
traefik.enable: "false"
adminer:
image: adminer
ports:
- target: 8080
protocol: tcp
mode: "ingress"
hostname: "db.local"
networks:
- public
- default
depends_on:
- mysql
deploy:
restart_policy:
condition: on-failure
mode: replicated
replicas: 1
labels:
com.centurylinklabs.watchtower.enable: "true"
orbiter: "true"
orbiter.up: 3
orbiter.down: 1
traefik.enable: "true"
traefik.port: 8080
traefik.docker.network: "public"
traefik.backend.loadbalancer.stickiness: "true"
traefik.backend.loadbalancer.swarm: "true"
traefik.frontend.rule: "Host:db.local"
traefik.frontend.proto: "http"
traefik.frontend.entrypoints: "http"
traefik.frontend.priority: 10
memcached:
ports:
- target: 11211
protocol: tcp
mode: "ingress"
image: memcached:latest
deploy:
restart_policy:
condition: on-failure
replicas: 1
mode: replicated
labels:
com.centurylinklabs.watchtower.enable: "true"
orbiter: "false"
traefik.enable: "false"
networks:
default:
aliases:
- memcached
fbctf:
image: alexgaspar/fbctf:latest
ports:
- target: 80
protocol: tcp
mode: "ingress"
- target: 443
protocol: tcp
mode: "ingress"
environment:
- MYSQL_HOST=mysql
- MYSQL_PORT=3306
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=ctf2018
- MYSQL_USER=ctf2018
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MEMCACHED_PORT=11211
- SSL_SELF_SIGNED=true
- CTF_URL=app.local
- SSL_COUNTRY=US
- SSL_CITY=Dallas
hostname: "app.local"
networks:
- public
- default
depends_on:
- memcached
- mysql
deploy:
restart_policy:
condition: on-failure
mode: replicated
replicas: 1
labels:
com.centurylinklabs.watchtower.enable: "true"
orbiter: "true"
orbiter.up: 3
orbiter.down: 1
traefik.enable: "true"
traefik.port: 80
traefik.docker.network: "public"
traefik.backend: "app"
traefik.backend.loadbalancer.stickiness: "true"
traefik.backend.loadbalancer.swarm: "true"
traefik.frontend.rule: "Host:app.local,www.app.local"
traefik.frontend.proto: "http"
traefik.frontend.entrypoints: "http, https"
traefik.frontend.priority: 10
traefik.frontend.passTLSCert: "false"
traefik.frontend.passHostHeader: "true"
traefik.frontend.headers.SSLProxyHeaders: "X-Forwarded-For:https"
traefik.frontend.headers.forceSTSHeader: "true"
traefik.frontend.headers.STSSeconds: "315360000"
traefik.frontend.headers.STSIncludeSubdomains: "true"
traefik.frontend.headers.STSPreload: "true"
traefik.frontend.headers.browserXSSFilter: "true"
traefik.frontend.headers.contentTypeNosniff: "true"
traefik.frontend.headers.customrequestheaders: "X-Forwarded-Ssl:on"
volumes:
portainer_data: {}
networks:
public:
external: true
name: "public"
default:
driver: "overlay"
...
# vim: set sts=2 sw=2 ts=2 et ai:
Summary
Further details on the Community Grid can be found on talk, chat, and the wiki.