Https redirection without breaking letsencrypt http challenge

Hi. This topic has been brought up before but that thread points to a GitHub issue which seems like a dead-end to me.

The issue is easy to understand. I have set up a permanent https redirection but this breaks the letsencrypt challenge and traefik is unable to provision certificates.

I see errors like this (hostnames redacted):

Unable to obtain ACME certificate for domains \"example.com\": unable to generate a certificate for the domains [example.com]: error: one or more domains had a problem:\n[example.com] acme: error: 400 :: urn:ietf:params:acme:error:connection :: Fetching http://example.com/.well-known/acme-challenge/LHOYCcMVxI0WN7_Zy5JF3MoNA5pysmQKP6y3eE_9Wrg: Connection refused\n" rule="Host(example.com)" providerName=letsencrypt.acme routerName=portainer-secure@docker

The error is obvious. As there's a https redirection then the acme challenge on port 80 won't work.

What is the suggested approach to handling this scenario? Is it possible to exclude certain paths from the https redirect? Is that the suggested approach, or should traefik someone accommodate this internally?

Here's my traefik config that demonstrates the issue:

version: '3.8'

services:
  traefik:
    image: traefik:latest
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - traefik_etc:/etc/traefik
      - /letsencrypt/acme.json:/letsencrypt/acme.json
    healthcheck:
      test: ['CMD', 'traefik', 'healthcheck', '--ping']
    command:
      - '--api.insecure=true'
      - '--providers.docker.swarmMode=true'
      - '--entrypoints.web.address=:80'
      - '--entrypoints.websecure.address=:443'
      - '--certificatesresolvers.letsencrypt.acme.email=email@example.com'
      - '--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json'
      - '--certificatesresolvers.letsencrypt.acme.httpChallenge.entryPoint=web'
      # - '--certificatesresolvers.letsencrypt.acme.tlschallenge=true'
      - '--ping'
    networks:
      - traefik-public
    deploy:
      replicas: 2
      labels:
        - 'traefik.docker.network=traefik-public'
        # - 'traefik.http.middlewares.traefik-redirectscheme.redirectscheme.permanent=true'
        # - 'traefik.http.middlewares.traefik-redirectscheme.redirectscheme.scheme=https'
        - 'traefik.http.routers.traefik-secure.entrypoints=websecure'
        - 'traefik.http.routers.traefik-secure.rule=Host(`traefik.example.com`)'
        - 'traefik.http.routers.traefik-secure.tls.certresolver=letsencrypt'
        - 'traefik.http.routers.traefik.entrypoints=web'
        # - 'traefik.http.routers.traefik.middlewares=traefik-redirectscheme'
        - 'traefik.http.routers.traefik.rule=Host(`traefik.example.com`)'
        - 'traefik.http.services.traefik-service.loadbalancer.server.port=8080'
volumes:
  traefik_etc:

networks:
  traefik-public:
    external: true

I've attempted to exclude ".well-known/acme-challenge/.*" from the redirect regex but as go does not support negative lookbehind I can't seem to construct a regex to exclude a certain path.

Related issue: Feature request: support for an 'exclude' option on redirection (a.k.a negated regex) · Issue #1373 · traefik/traefik · GitHub

Still looking for some pointers. Will keep investigating a workaround. (Also surprised not a lot of others are having this issue.)

I discovered that traefik adds a router for the acme challenge, but my redirection was taking precedence. So I adjusted the priority to "1" and this seems to have fixed it!

Here's my full docker-compose file:

version: '3.8'

services:
  traefik:
    image: traefik:latest
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - traefik_etc:/etc/traefik
      - /letsencrypt/acme.json:/letsencrypt/acme.json
    healthcheck:
      test: ['CMD', 'traefik', 'healthcheck', '--ping']
    command:
      - '--api.insecure=true'
      - '--providers.docker.swarmMode=true'
      - '--entrypoints.web.address=:80'
      - '--entrypoints.websecure.address=:443'
      - '--certificatesresolvers.letsencrypt.acme.email=email@example.com'
      - '--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json'
      - '--certificatesresolvers.letsencrypt.acme.httpChallenge.entryPoint=web'
      - '--ping'
    networks:
      - traefik-public
    deploy:
      replicas: 1
      labels:
        - 'traefik.docker.network=traefik-public'
        - 'traefik.http.middlewares.traefik-redirectscheme.redirectscheme.permanent=true'
        - 'traefik.http.middlewares.traefik-redirectscheme.redirectscheme.scheme=https'
        - 'traefik.http.routers.traefik-secure.entrypoints=websecure'
        - 'traefik.http.routers.traefik-secure.rule=Host(`traefik.example.com`)'
        - 'traefik.http.routers.traefik-secure.tls.certresolver=letsencrypt'
        - 'traefik.http.routers.traefik.entrypoints=web'
        - 'traefik.http.routers.traefik.middlewares=traefik-redirectscheme'
        - 'traefik.http.routers.traefik.priority=1' # allow the "/.well-known/acme-challenge/" router to take precedence
        - 'traefik.http.routers.traefik.rule=Host(`traefik.example.com`)'
        - 'traefik.http.services.traefik-service.loadbalancer.server.port=8080'
volumes:
  traefik_etc:

networks:
  traefik-public:
    external: true

Actually, I think the source of this problem was due to using replicas: 2. Moving that back to replicas: 1 seems to have solved this problem.

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.