diff --git a/.gitignore b/.gitignore index e906945ad..0feb820a1 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ *.log *.exe .DS_Store +/example/acme/acme.json diff --git a/examples/acme/Docker_Acme.md b/examples/acme/Docker_Acme.md new file mode 100644 index 000000000..f8c3e2b14 --- /dev/null +++ b/examples/acme/Docker_Acme.md @@ -0,0 +1,30 @@ +# ACME Testing environment + +## Objectives + +In our integration ACME tests, we use a simulated Let's Encrypt container based stack named boulder. + +The goal of this directory is to provide to developers a Traefik-boulder full stack environment. +This environment may be used in order to quickly test developments on ACME certificates management. + +The provided Boulder stack is based on the environment used during integration tests. + +## Directory content + +* **compose-acme.yml** : Docker-Compose file which contains the description of Traefik and all the boulder stack containers to get, +* **acme.toml** : Traefik configuration file used by the Traefik container described above, +* **manage_acme_docker_environment.sh** Shell script which does all needed checks and manages the docker-compose environment. + +## Shell script + +### Description + +To work fine, boulder needs a domain name, with a related IP and storage file. The shell script allows to check the environment before launching the Docker environment with the rights parameters and to managing this environment. + +### Use + +The script **manage_acme_docker_environment.sh** requires one argument. This argument can have 3 values : + +* **--start** : Check environment and launch a new Docker environment. +* **--stop** : Stop and delete the current Docker environment. +* **--restart--** : Concatenate **--stop** and **--start** actions. \ No newline at end of file diff --git a/examples/acme/acme.toml b/examples/acme/acme.toml new file mode 100644 index 000000000..78d6eadf8 --- /dev/null +++ b/examples/acme/acme.toml @@ -0,0 +1,33 @@ +logLevel = "DEBUG" + +defaultEntryPoints = ["http", "https"] + +[entryPoints] + [entryPoints.http] + address = ":80" + [entryPoints.http.redirect] + entryPoint = "https" + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + + +[acme] +email = "test@traefik.io" +storage = "/etc/traefik/conf/acme.json" +entryPoint = "https" +onDemand = false +OnHostRule = true +caServer = "http://traefik.localhost.com:4000/directory" + + +[web] + address = ":8080" + +[docker] +endpoint = "unix:///var/run/docker.sock" +domain = "traefik.localhost.com" +watch = true +exposedbydefault = false + + diff --git a/examples/acme/compose-acme.yml b/examples/acme/compose-acme.yml new file mode 100644 index 000000000..f9e9c32d0 --- /dev/null +++ b/examples/acme/compose-acme.yml @@ -0,0 +1,89 @@ +version: "2" + +# IP_HOST : Docker host IP (not 127.0.0.1) + +services : + boulder: + image: containous/boulder:release + environment: + FAKE_DNS: $IP_HOST + PKCS11_PROXY_SOCKET: tcp://boulder-hsm:5657 + extra_hosts: + - le.wtf:127.0.0.1 + - boulder:127.0.0.1 + ports: + - 4000:4000 # ACME + - 4002:4002 # OCSP + - 4003:4003 # OCSP + - 4500:4500 # ct-test-srv + - 8000:8000 # debug ports + - 8001:8001 + - 8002:8002 + - 8003:8003 + - 8004:8004 + - 8055:8055 # dns-test-srv updates + - 9380:9380 # mail-test-srv + - 9381:9381 # mail-test-srv + restart: unless-stopped + depends_on: + - bhsm + - bmysql + - brabbitmq + + bhsm: + image: letsencrypt/boulder-tools:2016-11-02 + hostname: boulder-hsm + networks: + default: + aliases: + - boulder-hsm + environment: + PKCS11_DAEMON_SOCKET: tcp://0.0.0.0:5657 + command: /usr/local/bin/pkcs11-daemon /usr/lib/softhsm/libsofthsm.so + expose: + - 5657 + bmysql: + image: mariadb:10.1 + hostname: boulder-mysql + networks: + default: + aliases: + - boulder-mysql + environment: + MYSQL_ALLOW_EMPTY_PASSWORD: "yes" + + brabbitmq: + image: rabbitmq:3-alpine + hostname: boulder-rabbitmq + networks: + default: + aliases: + - boulder-rabbitmq + environment: + RABBITMQ_NODE_IP_ADDRESS: "0.0.0.0" + + traefik: + build: + context: ../.. + image: containous/traefik:latest + command: --configFile=/etc/traefik/conf/acme.toml + restart: unless-stopped + extra_hosts: + - traefik.localhost.com:$IP_HOST + volumes: + - "./acme.toml:/etc/traefik/conf/acme.toml:ro" + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - "./acme.json:/etc/traefik/conf/acme.json:rw" + ports: + - "80:80" + - "443:443" + - "5001:443" # Needed for SNI challenge + expose: + - "8080" + labels: + - "traefik.port=8080" + - "traefik.backend=traefikception" + - "traefik.frontend.rule=Host:traefik.localhost.com" + - "traefik.enable=true" + depends_on: + - boulder \ No newline at end of file diff --git a/examples/acme/manage_acme_docker_environment.sh b/examples/acme/manage_acme_docker_environment.sh new file mode 100755 index 000000000..2ed97843c --- /dev/null +++ b/examples/acme/manage_acme_docker_environment.sh @@ -0,0 +1,101 @@ +#! /usr/bin/env bash + +# Initialize variables +readonly traefik_url="traefik.localhost.com" +readonly basedir=$(dirname $0) +readonly doc_file=$basedir"/compose-acme.yml" + +# Stop and remove Docker environment +down_environment() { + echo "STOP Docker environment" + ! docker-compose -f $doc_file down -v &>/dev/null && \ + echo "[ERROR] Impossible to stop the Docker environment" && exit 11 +} + +# Create and start Docker-compose environment or subpart of its services (if services are listed) +# $@ : List of services to start (optional) +up_environment() { + echo "START Docker environment" + ! docker-compose -f $doc_file up -d $@ &>/dev/null && \ + echo "[ERROR] Impossible to start Docker environment" && exit 21 +} + +# Init the environment : get IP address and create needed files +init_environment() { + for netw in $(ip addr show | grep -v "LOOPBACK" | grep -v docker | grep -oE "^[0-9]{1}: .*:" | cut -d ':' -f2); do + ip_addr=$(ip addr show $netw | grep -E "inet " | grep -Eo "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | head -n 1) + [[ ! -z $ip_addr ]] && break + done + + [[ -z $ip_addr ]] && \ + echo "[ERROR] Impossible to find an IP address for the Docker host" && exit 31 + + # The $traefik_url entry must exist into /etc/hosts file + # It has to refer to the $ip_addr IP address + [[ $(cat /etc/hosts | grep $traefik_url | grep -vE "^#" | grep -oE "([0-9]+(\.)?){4}") != $ip_addr ]] && \ + echo "[ERROR] Domain ${traefik_url} has to refer to ${ip_addr} into /etc/hosts file." && exit 32 + # Export IP_HOST to use it in the DOcker COmpose file + export IP_HOST=$ip_addr + + echo "CREATE empty acme.json file" + rm -f $basedir/acme.json && \ + touch $basedir/acme.json && \ + chmod 600 $basedir/acme.json # Needed for ACME +} + +# Start all the environement +start() { + init_environment + echo "Start boulder environment" + up_environment bmysql brabbitmq bhsm boulder + waiting_counter=12 + # Not start Traefik if boulder is not started + echo "WAIT for boulder..." + while [[ -z $(curl -s http://$traefik_url:4000/directory) ]]; do + sleep 5 + let waiting_counter-=1 + if [[ $waiting_counter -eq 0 ]]; then + echo "[ERROR] Impossible to start boulder container in the allowed time, the Docker environment will be stopped" + down_environment + exit 41 + fi + done + echo "START Traefik container" + up_environment traefik +} + +# Script usage +show_usage() { + echo + echo "USAGE : manage_acme_docker_environment.sh [--start|--stop|--restart]" + echo +} + +# Main method +# $@ All parameters given +main() { + + [[ $# -ne 1 ]] && show_usage && exit 1 + + case $1 in + "--start") + # Start boulder environment + start + echo "ENVIRONMENT SUCCESSFULLY STARTED" + ;; + "--stop") + ! down_environment + echo "ENVIRONMENT SUCCESSFULLY STOPPED" + ;; + "--restart") + down_environment + start + echo "ENVIRONMENT SUCCESSFULLY STARTED" + ;; + *) + show_usage && exit 2 + ;; + esac +} + +main $@ \ No newline at end of file