This post is a simplified and focused follow-up to Dockerized Traefik Host Using ACME DNS-01 Challenge.

Simplify

Today, 19-May-2020, I’m going to take a shot at simplifying my testing on dgdocker3.grinnell.edu by removing unnecessary things and consolidating as much as possible to reduce clutter in the logs and get right to the point. I’m also going to have a look to see if there are additional logs that can tell give me more detail. Everything used here, and everything that takes place here, will be found in a new directory, /opt/containers/test on DGDocker3.

Key Files

The key files involved in these tests are presented in subsections here.

./test/docker-compose.yml

version: '3'

services:
  traefik:
    image: traefik:2.2.1
    container_name: traefik
    hostname: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json
    labels:
      - "traefik.enable=true"
      # next 4 lines...universal http --> https redirect per https://community.containo.us/t/a-global-http-https-redirection/864/3
      - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:[a-z-.]+}`)"
      - "traefik.http.routers.http-catchall.entrypoints=http"
      - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      # now the Traefik-specific dashboard stuff
      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$2y$$05$$pJEzHJBzfoYYS7/hGAedcOP8XdsqNXE7j.LHFBVjueASOqOvvjGOy"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.rule=Host(`${HOST}`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=http"
      - "traefik.http.routers.traefik-secure.service=api@internal"

  landing:
    image: mcfatem/dgdocker3-landing:latest
    container_name: landing-page
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - proxy
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data:/data
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.landing-secure.entrypoints=https"
      - "traefik.http.routers.landing-secure.rule=Host(`${HOST}`)"
      - "traefik.http.routers.landing-secure.tls=true"
      - "traefik.http.routers.landing-secure.tls.certresolver=http"
      - "traefik.http.routers.landing-secure.service=landing-test"
      - "com.centurylinklabs.watchtower.enable=true"

networks:
  proxy:
    external: true

./test/destroy.sh

#!/bin/bash
#
rm -f /opt/containers/test/data/acme.json
#
docker stop $(docker ps -q);
docker rm -v $(docker ps -qa);
# docker image rm $(docker image ls -q)
docker system prune --force
#
touch /opt/containers/test/data/acme.json
chmod 600 /opt/containers/test/data/acme.json

./test/restart.sh

#!/bin/bash
#
docker network create proxy
cd /opt/containers/test
docker-compose up -d; docker-compose logs
#
echo "Dumping traefik.log..."
docker exec -it traefik cat /var/log/traefik.log

./test/data/traefik.yml (obfuscated)

api:
  dashboard: true

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

### for HTTP-01 challenge
#certificatesResolvers:
#  http:
#    acme:
#      # - Uncomment caServer line below to run on the staging let's encrypt server.  Leave comment to go to prod.
#      #caServer: https://acme-staging-v02.api.letsencrypt.org/directory
#      email: digital@grinnell.edu
#      storage: acme.json
#      httpChallenge:
#        entryPoint: http

## for DNS-01 challenge
certificatesResolvers:
  http:
    acme:
      # - Uncomment caServer line below to run on the staging Let's Encrypt server.  Leave comment to go to prod.
      caServer: https://acme-staging-v02.api.letsencrypt.org/directory
      email: digital@grinnell.edu
      storage: acme.json
      dnsChallenge:
        provider: azure
        delayBeforeCheck: 0

environment:
  AZURE_CLIENT_ID: "c537...d99"
  AZURE_CLIENT_SECRET: "6a2...154"
  AZURE_SUBSCRIPTION_ID: "a55...c4f"
  AZURE_TENANT_ID: "524...807"
  AZURE_DNS_ZONE: "lev...nfo"
  AZURE_RESOURCE_GROUP: "Net...ces"
  #
  #AZURE_CLIENT_ID: "${AZURE_CLIENT_ID}"
  #AZURE_CLIENT_SECRET: "${AZURE_CLIENT_SECRET}"
  #AZURE_SUBSCRIPTION_ID: "${AZURE_SUBSCRIPTION_ID}"
  #AZURE_TENANT_ID: "${AZURE_TENANT_ID}"
  #AZURE_DNS_ZONE: "${AZURE_DNS_ZONE}"
  #AZURE_RESOURCE_GROUP: "${AZURE_RESOURCE_GROUP}"

log:
  level: DEBUG
  filePath: "/var/log/traefik.log"

./test/data/config.yml

http:
  middlewares:
    https-redirect:
      redirectScheme:
        scheme: https

Initial Test - Failed

My initial test was a simplified repeat of Test 7. The result was much like I documented in that previous test, with no certs, and no indication of problems other than the mysterious “TLS handshake error” that I reported before. So, time to make some changes and see what happens.

Changing the Name of the CertResolver

In all my previous tests there are lots of instances of “http”, and most notably, it’s the name given to the certresolver regardless if this is an HTTP-01 or DNS-01 challenge. Since my simplified tests all focus on DNS-01 I’m changing that certresolver name to “dns”.

This change was made in ./test/docker-compose.yml lines 22 and 43, and line 30 of ./test/data/traefik.yml. No other files or lines were modified.

Test S1

The “S” in “S1” distinguishes this as a “Simplified” test. To run this test I executed the following, as root, on dgdocker3.grinnell.edu:

cd /opt/containers/test
./destroy.sh
./restart.sh
grep Certificates data/acme.json

The outcome is the same as before, both the Traefik dashboard (https://dgdocker3.grinnell.edu/dashboard/) and landing page (https://dgdocker3.grinnell.edu/) are working, but without valid certs so browser security exceptions are required. The output from this test can be found in this gist.

And that’s a good place to break, but I’ll be baaaaak. 😄