HTTPS and subdomain in Traefik - docker

I have a Traefik and a few services in docker-containers. Here is docker-compose.yml file:
version: "3"
services:
main-app:
image: some-image
container_name: main_app
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`domain.com`)"
- "traefik.http.routers.app.entrypoints=https"
- "traefik.http.routers.app.tls.certresolver=cert
moodle:
image: some-moodle-image
container_name: moodle
labels:
- "traefik.enable=true"
- "traefik.http.routers.moodle.rule=Host(`moodle.domain.com`)"
- "traefik.http.routers.moodle.entrypoints=https"
- "traefik.http.routers.moodle.tls.certresolver=cert"
traefik:
image: "traefik"
container_name: traefik
command:
- "--api.insecure=true"
#Entrypoints settings
- "--entrypoints.http.address=:80"
- "--entrypoints.https.address=:443"
# Providers settings
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
# Acme challeges settings
- "--certificatesresolvers.cert.acme.httpchallenge=true"
- "--certificatesresolvers.cert.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.cert.acme.email=some-mail#help.me"
- "--certificatesresolvers.cert.acme.storage=/letsencrypt/acme.json"
labels:
#Redirect HTTP -> HTTPS
- "traefik.enable=true"
- "traefik.http.routers.https-redirect.entrypoints=http"
- "traefik.http.routers.https-redirect.rule=HostRegexp(`{any:.*}`)"
- "traefik.http.routers.https-redirect.middlewares=https-redirect"
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
As you can see the main app container is tied to the main domain (domain.com). And moodle container to the subdomain (moodle.domain.com).
Now to the heart of the matter. On the main domain, the certificate is issued and works HTTPS. But on the subdomain, I get the next error:
time="2020-05-01T13:12:54Z" level=error msg="Unable to obtain ACME certificate for domains \"moodle.domain.com\":
unable to generate a certificate for the domains [moodle.domain.com]:
error: one or more domains had a problem:[moodle.domain.com] acme: error: 403 ::
urn:ietf:params:acme:error:unauthorized ::
Invalid response from http://moodle.domain.com/.well-known/acme-challenge/(some private code)[(some ip address)]:
404, url: \n" providerName=cert.acme routerName=moodle#docker rule="Host(`moodle.domain.com`)"
How can this be caused and how can this problem be solved?

Related

Failing to get certificate with Traefik from Lets Encrypt

I am trying to get a certificate for my docker container but I keep getting errors, below is my docker-compose. This used to work before until i deleted the container to restart it again. I am using Traefik as the proxy and I am using it to request for certificates.
and I keep getting this error when i start my container to get the certitifcates.
Unable to obtain ACME certificate for domains "mydomain.com": unable to generate a certificate for the domains [mydomain.com]: error: one or more domains had a problem:\n[mydomain.com] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized ::
Cannot negotiate ALPN protocol "acme-tls/1" for tls-alpn-01 challenge\n",
"providerName": "myresolver.acme"
Please note i have replaced the actual domain with mydomain.com and other lines of images in the docker compose have been left out for brevity. Is there any rule i am not following properly?
services:
##Reverse Proxy
traefik:
image: library/traefik:v2.6.0
container_name: traefik
labels:
- traefik.enable=false
command:
- --api.insecure=false
- --providers.docker
#
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.websecure.address=:443
- --entryPoints.websecure.forwardedHeaders.insecure
- --entryPoints.web.forwardedHeaders.insecure
#
# ...
- --certificatesresolvers.myresolver.acme.email=email#email.com
- --certificatesresolvers.myresolver.acme.tlschallenge=true
- --certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
# used during the challenge
- --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
#logs
# Writing Logs to a File
- --log.level=DEBUG
- --log.filePath=/logs/traefik.log
- --log.format=json
## Access Logs
- --accesslog=true
networks:
- traefik
ports:
- "80:80"
- "443:443"
- "8080:8080"
restart: always
volumes:
- ./logs/traefik/:/logs/
- ./letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
portainer:
image: portainer/portainer:latest
container_name: portainer
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- traefik
ports:
- "9000:9000"
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./portainer-data:/data
labels:
- "traefik.http.routers.portainer.priority=1"
- "traefik.http.routers.portainer.rule=Host(`mydomain.com`)"
- "traefik.http.routers.portainer.tls=true"
- "traefik.http.routers.portainer.tls.certresolver=myresolver"
networks:
traefik:
name: traefik```

Traefik Docker SSL Configuration With Lets Encrypt

Hi everyone I am trying to enable SSL in my docker-compose.yml file for my backend service. All of my Traefik configuration is done in my docker-compose.yml file, so I may be missing a line. Running docker-compose on this configuration works without SSL and the site is displayed properly, but it does not work when using https. I have checked the Traefik documentation for the certResolvers and I am not sure what I am missing thanks.
version: "3"
networks:
NanoWall-Net:
services:
api:
build:
context: .
dockerfile: Dockerfile
labels:
- "traefik.docker.network=NanoWall-Net"
- "traefik.enable=true"
- "traefik.port=5000"
- "traefik.http.routers.http-catchall.rule=Host(`nanowalldocs.com`)"
- "traefik.http.routers.http-catchall.tls=true"
- "traefik.http.routers.http-catchall.tls.certresolver=le"
- "traefik.http.routers.http-catchall.tls.domains[0].sans=nanowalldocs.com"
- "traefik.http.routers.http-catchall.entrypoints=web"
ports:
- "5000:5000"
networks:
- NanoWall-Net
reverse-proxy:
image: traefik:v2.0
# Enables the web UI and tells Traefik to listen to docker
command:
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls.certResolver: le"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--api.insecure=true"
- "--api.debug=true"
- "--api=true"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
- "--providers.docker.exposedbydefault=false"
- "--accesslog=true"
- "--accesslog.filepath=/var/log/traefik-access.log"
- "--accesslog.bufferingsize=1000"
- "--log.filePath=/var/log/traefik.log"
- "--certificatesResolvers.le.acme.email=jamar.phillip99#gmail.com"
- "--certificatesResolvers.le.acme.storage=acme.json"
- "--certificatesResolvers.le.acme.httpChallenge=true"
- "--certificatesResolvers.le.acme.httpChallenge.entryPoint=web"
ports:
# The HTTP port
- "80:80"
- "443:443"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
networks:
- NanoWall-Net
volumes:
- /acme.json/etc/traefik/acme.json
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: always
It may not be the only issue, but you are missing a colon in your traefik volumes section. You have:
- /acme.json/etc/traefik/acme.json
I think it should be (assuming your host location is really /acme.json and not ./acme.json or in some other directory):
- /acme.json:/etc/traefik/acme.json
That said, I have also been having an issue where traefik always wants it in /acme.json, so I just put it there instead of in /etc/traefik/acme.json .

Unable to access Docker container behind Traefik

I am attempting to access the whoami container running on my remote server, but can only get as far as a "404 page not found" error. I get the same result when attempting to access the traefik dashboard.
My docker-compose.yml:
version: "3.7"
services:
traefik:
image: traefik:v2.3.0
container_name: traefik
restart: unless-stopped
command: # CLI arguments
## Globals
- "--global.checkNewVersion=false"
- "--global.sendAnonymousUsage=false"
## Entrypoint Settings - https://docs.traefik.io/routing/entrypoints/#configuration ##
- "--entrypoints.http.address=:80"
- "--entrypoints.http.http.redirections.entryPoint.to=https"
- "--entrypoints.http.http.redirections.entryPoint.scheme=https"
- "--entrypoints.https.address=:443"
## API Settings
- "--api=true"
- "--api.dashboard=true"
- "--log=true"
- "--log.level=DEBUG" # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
- "--providers.docker=true"
- "--providers.docker.watch=true"
- "--providers.docker.exposedByDefault=false"
## Certificate Settings (Let's Encrypt) - https://docs.traefik.io/https/acme/#configuration-examples ##
- "--certificatesresolvers.mytlschallenge.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory" # TBD - TESTING
networks:
- frontend
ports:
- "80:80"
- "443:443"
- "8080:8080"
security_opt:
- "no-new-privileges:true" # https://docs.docker.com/engine/reference/run/#security-configuration
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "$USERDIR/ctmp/acme/acme.json:/acme.json:rw" # cert location - you must touch this file and change permissions to 600
labels:
- "traefik.enable=true"
## HTTP Routers
- "traefik.http.routers.traefik-rtr.rule=HostHeader(`traefik.${DOMAIN}`)"
- "traefik.http.routers.traefik-rtr.entrypoints=https"
- "traefik.http.routers.traefik-rtr.service=api#internal"
whoami:
image: "traefik/whoami"
container_name: "simple-service"
networks:
- frontend
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=HostHeader(`whoami.${DOMAIN}`)"
- "traefik.http.routers.whoami.entrypoints=http"
networks:
frontend:
external: true
$USERDIR and $DOMAIN are defined in my .env file.
All of the traefik logs are info or debug level with no errors appearing.
I don't have the time right now but here is a quick code rewrite, but not tested.
It is just a slightly different method. But I think it leads to the same goal.
You must include your ENV file
traefik.http.routers.api.rule=HostHeader to =Host(`...). Whereby it is strange and should also work with HostHeader. Link
With this base you can now customize it. I use the HTTP chalange, but with the TLS chalange it should work.
version: "3.7"
services:
traefik:
image: traefik:v2.3.0
container_name: traefik
restart: unless-stopped
env_file:
- .env
command: # CLI arguments
## Globals
- "--global.checkNewVersion=false"
- "--global.sendAnonymousUsage=false"
## Entrypoint Settings - https://docs.traefik.io/routing/entrypoints/#configuration ##
- "--entrypoints.http.address=:80"
- "--entrypoints.https.address=:443"
## API Settings
- "--api=true"
- "--api.insecure=false"
- "--api.dashboard=true"
- "--log.level=DEBUG" # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
- "--providers.docker=true"
- "--providers.docker.exposedByDefault=false"
## Certificate Settings
- "--certificatesresolvers.myresolver.acme.httpchallenge=true"
- "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=http"
- "--certificatesresolvers.myresolver.acme.email=YOUR-EMAIL#your-domain.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
networks:
- frontend
ports:
- "80:80"
- "443:443"
- "8080:8080"
security_opt:
- "no-new-privileges:true" # https://docs.docker.com/engine/reference/run/#security-configuration
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./letsencrypt:/letsencrypt"
labels:
- "traefik.enable=true"
## HTTP Routers
- "traefik.http.routers.api.rule=Host(`traefik.${DOMAIN}`)"
- "traefik.http.routers.api.entrypoints=https"
- "traefik.http.routers.api.service=api#internal"
- "traefik.http.routers.api.tls.certresolver=myresolver"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.routers.redirect.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.redirect.middlewares=redirect-to-https"
whoami:
image: traefik/whoami
container_name: simple-service
networks:
- frontend
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.${DOMAIN}`)"
- "traefik.http.routers.whoami.entrypoints=https"
- "traefik.http.routers.whoami.tls.certresolver=myresolver"
networks:
frontend:
external: true

Traefik Default certificate is not trusted

The configuration below worked fine until I moved the location of the docker-compose.yml file.
Now I got the invalid certificate message in the browser "This CA Root certificate is not trusted because it is not in the Trusted Root Certification Authorities store." for the self-signed certificate.
Not sure what is causing the problem.
services:
traefik:
image: "traefik:v2.0.2"
container_name: "traefik"
command:
- "--entrypoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--api"
- "--providers.docker"
- "--certificatesResolvers.le-resolver.acme.email=test#nodomain.com"
- "--certificatesResolvers.le-resolver.acme.storage=acme.json"
- "--certificatesResolvers.le-resolver.acme.httpChallenge.entryPoint=web"
labels:
# global redirect to https
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
# middleware redirect
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./data/acme.json:/acme.json"

Using wildcard certificates in Traefik v2 on Docker Swarm

I am using the following Docker Compose file to deploy Traefik on a swarm cluster.
version: "3.7"
services:
traefik:
image: traefik:v2.1
command:
- "--api.dashboard=true"
- "--accesslog=true"
- "--log.level=INFO"
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=traefik-public"
- "--providers.file.watch=true"
- "--providers.file.filename=/file_provider.yml"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.dnsChallenge.provider=cloudflare"
- "--certificatesresolvers.letsencrypt.acme.dnsChallenge.delayBeforeCheck=15"
- "--certificatesresolvers.letsencrypt.acme.dnsChallenge.resolvers=1.1.1.1:53,1.0.0.1:53"
- "--certificatesresolvers.letsencrypt.acme.email=user#domain.tld"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- 80:80
- 443:443
volumes:
- traefik-certificates:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock
networks:
- traefik-public
environment:
- "CF_API_EMAIL=user#domain.tld"
- "CF_API_KEY=api-key"
deploy:
placement:
constraints:
- node.role == manager
labels:
- "traefik.enable=true"
- "traefik.docker.lbswarm=true"
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https#docker"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
- "traefik.http.routers.api.tls.domains[0].main=*.domain.tld"
- "traefik.http.routers.api.tls.domains[0].sans=domain.tld"
- "traefik.http.routers.api.rule=Host(`management.domain.tld`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
- "traefik.http.routers.api.service=api#internal"
- "traefik.http.services.api.loadbalancer.server.port=8080"
configs:
- file_provider.yml
volumes:
traefik-certificates:
configs:
file_provider.yml:
file: /home/access/docker/traefik-provider.yml
networks:
traefik-public:
external: true
At the moment, I have hit the rate limit on management.domain.tld and I instead want to use a wildcard certificate so there is less likelihood that I will run into a rate limit again. I have Traefik configured to generate the wildcard certificate which works, but there is still a rate-limiting error on management.domain.tld in the logs. Also, when I go to management.domain.tld in the browser, I get an invalid SSL/TLS error. How do I get Traefik to use the wildcard certificate instead of issuing a new certificate for every host rule?
Looks like you have done everything right. But there is a slight mistake in the config.
main is the Subject field for the certificate. Meaning the domain/sub-domain the certificate is being issued to.
sans is the Subject Alternate Names field for the certificate. Meaning alternative domain/sub-domain that the certificate is also valid for.
So, Instead of using:
version: "3.7"
services:
traefik:
image: traefik:v2.1
...
labels:
- "traefik.http.routers.api.tls.domains[0].main=*.domain.tld"
- "traefik.http.routers.api.tls.domains[0].sans=domain.tld"
...
You should use:
version: "3.7"
services:
traefik:
image: traefik:v2.1
...
labels:
- "traefik.http.routers.api.tls.domains[0].main=domain.tld"
- "traefik.http.routers.api.tls.domains[0].sans=*.domain.tld"
...

Resources