How to use LE certs produced by traffic.io ?
Hello
I am in a full docker environment. I am using traefik.io as a reverse proxy. It also produces LE certs using ACME using DNS challenge. So, I set up danielhuisman/traefik-certificate-extractor image to generate cert.pem, chain.pem, fullchain.pem and privacy.pem
I have a fully functional webmail and poste.io admin interface which is routed to HTTPS using traefik's LE certs. But SMTP and IMAP certs still stand on poste.io's self-signed ones. I tried to map /data/ssl/letsencrypt/mydomain.com to my *.pem folder. Still no luck...
Is it possible to use external LE certs whithout turning on poste.io LE certs request ? (I don't have access to traefik's .well-known folder...
Comments (15)
-
repo owner -
reporter Since I have no access to .well-known folderol proxy, I've chosen B option. I noticed 3 points :
-
Let'sencrypt is using acme v1 while proxy uses acme v2
-
Poste LE generated cert is marked as non valid because of "hostname mismatch" error. But server's hostname, poste's hostname and LE's hostname are strictly matching
-
Port 443 is used by reverse proxy for other apps SSL redirection. Poste's docker container is mapping 443 port to 50443. http://webmail.mydomain.com is correctly mapped to the poste instance by the reverse proxy on its 80 port, which redirects it to https://webmail.mydomain.com/webmail instead of the mapped port (50443). The LE's certificate is indeed the one generated by poste.
I'd like to have a valid LE cert and an access to the webmail
-
-
repo owner What gives you "hostname mismatch" error? browser?
You can simply disable all SSL at poste with
-e "HTTPS=OFF"
at container start and let the proxy handle SSL cert for https, but still it must not redirect .well-known folder and forward requests to this folder to poste. I am not familiar with traefik but if traefik simply redirects all traffic to https and custom routing can't be defined it might be impossible. -
reporter Thanks, I'll have a look as soon as possible. I'll have to be off for a few days. I'll tell you whether this solved the problem or not.
The hostname mismatch error is displayed by the browser (Safari 11.1.1) who doesn't fully trust the certs. Did not try with an other web browser.
Traefik should be able to handle the depicted case. Rules are defined either in a file or in the
docker-compose.yml
labels.Could you give me more infos on what does each parameters that could be available in docker-compose please ? I did not find it in a doc. For instance, I just understood with your message that
HTTPS=OFF
only impacts webmail and admin frontend redirection but not LE's certs generation -
reporter - changed status to resolved
Finaly everything works like a charm using poste.io an traefik.io I set up poste and traefik as suggested. Issue can be closed. Thanks !
-
repo owner Would you mind sharing example configuration? I am not using traefik but someone can find it usefull
-
Hi @vincowl
I'm using the same setup but can't get Poste running along with traefik. After starting the container with https=off, I only got an internal server error on the Web UI
From the logs everything seems to be OK - without the well-known issue
app.ERROR: Please check http://mail.my-tld.com/.well-known/acme-challenge/s1Ua05xw***********B6_xRQus - tokennot available [] []
[services.d] starting services Poste.io container should be running now at http://172.19.0.6 [services.d] done.
Neither the web ui works nor the login with a mail client :(
Before poste was behind a nginx reverse proxy which becomes less handy. But with ngnix the volume could be easily shared (re. mounted into the poste container) with Poste
@analogic Do you have any updates on this topic and how it was fixed?
Best regards and Thanks in advance Andreas
-
reporter Hi,
Sorry for this looong silence. I was a few weeks whithout internet access. Here is what I did.
I am using docker-compose to deploy these "services".
docker-compose.yml
version: '3' services: reverse-proxy: image: traefik # The official Traefik docker image command: --api --docker # Enables the web UI and tells Træfik to listen to docker container_name: traefik restart: always ports: - "80:80" # The HTTP port - "8080:8080" # The Web UI (enabled by --api) - "443:443" # The HTTPS port environment: OVH_ENDPOINT: ovh-eu OVH_APPLICATION_KEY: xxxxxxxx OVH_APPLICATION_SECRET: xxxxxxxx OVH_CONSUMER_KEY: xxxxxxxx volumes: - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events - "./containers/traefik:/etc/traefik" - "./containers/traefik/logs:/logs" labels: - "traefik.backend=traefik" - "traefik.frontend.rule=Host:reverseproxy.mydomain.com" - "traefik.port=8080" - "traefik.frontend.entryPoints=http,https" - "traefik.frontend.headers.SSLRedirect=true" posteio: image: analogic/poste.io container_name: poste.io hostname: mail.mydomain.com restart: always ports: - '25:25' # SMTP - mostly processing incoming mails - 'myHTTPport:80' # HTTP - redirect to https (see options) and authentication for Let's encrypt service - '110:110' # POP3 - standard protocol for accessing mailbox, STARTTLS is required before client auth - '143:143' # IMAP - standard protocol for accessing mailbox, STARTTLS is required before client auth - 'myHTTPSport:443' # HTTPS - access to administration or webmail client - '587:587' # MSA - SMTP port used primarily for email clients after STARTTLS and auth - '993:993' # IMAPS - alternative port for IMAP encrypted since connection - '995:995' # POP3S - encrypted POP3 since connections environment: - HOSTNAME=mail.mydomain.com - HTTPS=OFF #- DISABLE_CLAMAV=TRUE - LETSENCRYPT_EMAIL=postmaster@mydomain.com - LETSENCRYPT_HOST=mydomain.com - VIRTUAL_HOST=mail.mydomain.com volumes: - './containers/poste.io/data:/data' - '/etc/localtime:/etc/localtime:ro' labels: - "traefik.leposte.backend=leposte" - "traefik.leposte.frontend.rule=HostRegexp:mydomain.com,{subdomain:[a-z]*}.mydomain.com;PathPrefix:/.well-known/" - "traefik.leposte.port=80" - "traefik.leposte.protocol=http" - "traefik.leposte.frontend.entryPoints=http" - "traefik.webmail.backend=webmail" - "traefik.webmail.frontend.rule=Host:webmail.mydomain.com" - "traefik.webmail.port=80" - "traefik.webmail.frontend.headers.SSLRedirect=true" - "traefik.admin.backend=posteio" - "traefik.admin.frontend.rule=Host:posteio.mydomain.com" - "traefik.admin.frontend.redirect.regex=posteio.mydomain.com/webmail" - "traefik.admin.frontend.redirect.replacement=posteio.mydomain.com/admin/" - "traefik.admin.port=80" - "traefik.admin.frontend.headers.SSLRedirect=true" traefik-certificate-extractor: container_name: traefik-certs-extractor image: danielhuisman/traefik-certificate-extractor restart: always depends_on: - reverse-proxy volumes: - "./containers/traefik/acme:/app/data" - "./containers/letsencrypt/certs:/app/certs" labels: - "traefik.enable=false"
Set up your own HTTPS and HTTP port for poste.io container.
It needs to define DNS entries in your DNS table
$TTL 3600 @ 3600 IN A AA.BB.CC.DD mail 3600 IN CNAME mydomain.com posteio 3600 IN CNAME mydomain.com. reverseproxy 3600 IN CNAME mydomain.com. webmail 3600 IN CNAME mydomain.com.
webmail is for the webmail interface, posteio for poste.io admin interface, and reverseproxy for traefik.io
traefik.toml
# traefik.toml ################################################################ # Global configuration ################################################################ defaultEntryPoints = ["http", "https"] logLevel = "DEBUG" debug = true [entryPoints] [entryPoints.http] address = ":80" [entryPoints.https] address = ":443" [entryPoints.https.tls] [retry] [acme] email = "postmaster@mydomain.com" # Mail adress used for cert request storage = "/etc/traefik/acme/acme.json" # File path to the certs infos entryPoint = "https" # Required. HTTPS port must be set to 443 OnHostRule = true # The cert reauest will be done with the first app's HTTS request acmeLogging = true [[acme.domains]] main = "mydomain.com" # Main domain. ex : cab.re sans = ["mail.mydomain.com", "reverseproxy.mydomain.com", "webmail.mydomain.com", "imap.mydomain.com", "pop.mydomain.com", "posteio.mydomain.com", "smtp.mydomain.com", "webmail.mydomain.com"] # alt domains having same certs as cab.re [acme.httpChallenge] # EntryPoint to use for the HTTP-01 challenges. # Required entryPoint = "http" [acme.dnsChallenge] provider = "ovh" delayBeforeCheck = 0 [web] address = ":8080" # Traefik web interface [web.auth.basic] # Basic authentication users = ["pab:xxxxx"] # Backend utilisé : [docker] endpoint = "unix:///var/run/docker.sock" # Unix or TCP socket domain = "mydomain.com" # Default domain used. Containers will then have a `CONTAINER_NAME.cab.re` watch = true # Traefik will be notified as soon as there will be docker modifications # Traefik will manage every container. # In order to disable traefik management, just add the label "traefik.enable=false" to the container exposedbydefault = true [traefikLog] filePath = "/logs/traefik.log" format = "json" logLevel = "DEBUG" [accessLog] filePath = "/logs/access.log" format = "json"
My domain provider is OVH. Set up for authentication keys shall be done as follows :
- Go to https://eu.api.ovh.com/createApp/
- Fill the required parameters. Fill the account number with your OVH id and password
- You will get an
Application Key
and anApplication Secret
to write in thedocker-compose.yml
file - In a terminal, type
curl -XPOST -H“X-Ovh-Application: <Application Key>” -H “Content-type: application/json” https://eu.api.ovh.com/1.0/auth/credential -d '{“accessRules”: [{“method”: “GET”,“path”: “/*”},{“method”: “POST”,“path”: “/*”},{“method”: “PUT”,“path”: “/*”},{“method”: “DELETE”,“path”: “/*”}],“redirection”: “https://reverseproxy.mydomain.com/”}'
using the correctApplication Key
- This will give a
consumerKey
to set up in thedocker-compose.yml
file and a URL - Open this URL in your web browser and fill it as previously done. Set up validity to
Unlimited
- In the
docker-compose.yml
file,OVH_ENDPOINT
must be set up toovh-eu
Hope this will help !
-
Hi @vincowl
I'd like to thank you. I'll give your compose file a try later on. But from what I read so far it seems to be pretty smart. I was not aware of extracting the certs files from traefik to grant access.
many thanks, best regards Andreas
-
reporter It's important to let poste manage its own LE certs. Every other certs will be managed by traefik. Lines of the compose file containing "traefik.leposte" labels are the most important ones. Just set these and have a try, then add access to poste.io interface and webmail if needed.
-
@vincowl I had many problems to have the mail server running with poste.io, you explained very well and everything worked perfect thanks, now everything was so easy after several days failing.
-
Does anyone know how the labels would be configured in version 2 of traefik?
labels:
- "traefik.leposte.backend=leposte"
- "traefik.leposte.frontend.rule=HostRegexp:mydomain.com,{subdomain:[a-z]*}.mydomain.com;PathPrefix:/.well-known/"
- "traefik.leposte.port=80"
- "traefik.leposte.protocol=http"
- "traefik.leposte.frontend.entryPoints=http"
- "traefik.webmail.backend=webmail"
- "traefik.webmail.frontend.rule=Host:webmail.mydomain.com"
- "traefik.webmail.port=80"
- "traefik.webmail.frontend.headers.SSLRedirect=true"
- "traefik.admin.backend=posteio"
- "traefik.admin.frontend.rule=Host:posteio.mydomain.com"
- "traefik.admin.frontend.redirect.regex=posteio.mydomain.com/webmail"
- "traefik.admin.frontend.redirect.replacement=posteio.mydomain.com/admin/"
- "traefik.admin.port=80"
- "traefik.admin.frontend.headers.SSLRedirect=true"
-
reporter @Tomas Antonio Marquez Lezama I have set it up using traefik v2. I'll post what I've done tomorrow : I'm down, it's late here.
-
reporter Here is what I did using traefik v2.
I am using docker-compose to deploy these "services". I need to automatically route http to https and to expose a local service on a local machine (a nas Web-UI for instance).
docker-compose.yml
version: '3' services: reverse-proxy: image: traefik # The official Traefik docker image container_name: traefik restart: always ports: - "80:80" # The HTTP port - "443:443" # The HTTPS port environment: OVH_ENDPOINT: ovh-eu OVH_APPLICATION_KEY: xxxxxxxx OVH_APPLICATION_SECRET: xxxxxxxx OVH_CONSUMER_KEY: xxxxxxxx volumes: - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events - "./containers/traefik/traefik.toml:/etc/traefik/traefik.toml" - "./containers/traefik/config:/config" - "./containers/traefik/letsencrypt:/letsencrypt" - "./containers/traefik/logs:/logs" labels: - "traefik.http.routers.api.rule=Host(`reverseproxy.mydomain.com`)" - "traefik.http.routers.api.service=api@internal" - "traefik.http.routers.api.entrypoints=https" - "traefik.http.routers.api.tls.certresolver=mydnschallenge" - "traefik.http.routers.api.middlewares=auth" - "traefik.http.middlewares.auth.basicauth.users=admin:XXXXXXXXXXXXXX" # Using an .htpasswd generator - "traefik.http.routers.nas.entrypoints=https" - "traefik.http.routers.nas.rule=Host(`nas.mydomain.com`)" # local machine - "traefik.http.routers.nas.service=nas@file" - "traefik.http.routers.nas.tls.certresolver=mydnschallenge" posteio: image: analogic/poste.io container_name: poste.io hostname: mail.mydomain.com restart: always ports: - '25:25' # SMTP - mostly processing incoming mails - '5080:80' # HTTP - redirect to https (see options) and authentication for Let's encrypt service - '110:110' # POP3 - standard protocol for accessing mailbox, STARTTLS is required before client auth - '143:143' # IMAP - standard protocol for accessing mailbox, STARTTLS is required before client auth - '50443:443' # HTTPS - access to administration or webmail client - '587:587' # MSA - SMTP port used primarily for email clients after STARTTLS and auth - '993:993' # IMAPS - alternative port for IMAP encrypted since connection - '995:995' # POP3S - encrypted POP3 since connections environment: - HOSTNAME=mail.mydomain.com - HTTPS=OFF #- DISABLE_CLAMAV=TRUE - LETSENCRYPT_EMAIL=postmaster@mydomain.com - LETSENCRYPT_HOST=mydomain.com - VIRTUAL_HOST=mail.mydomain.com volumes: - './containers/poste.io/data:/data' - '/etc/localtime:/etc/localtime:ro' labels: - "traefik.http.routers.webmail.rule=Host(`webmail.mydomain.com`)" - "traefik.http.routers.webmail.entrypoints=https" - "traefik.http.routers.webmail.tls.certresolver=mydnschallenge" - "traefik.http.routers.webmail.service=webmail" - "traefik.http.services.webmail.loadbalancer.server.port=80" - "traefik.http.routers.posteio-admin.rule=Host(`posteio.mydomain.com`)" - "traefik.http.routers.posteio-admin.entrypoints=https" - "traefik.http.middlewares.posteio-admin-redirect.redirectregex.regex=posteio.mydomain.com/webmail" - "traefik.http.middlewares.posteio-admin-redirect.redirectregex.replacement=posteio.mydomain.com/admin" - "traefik.http.routers.posteio-admin.middlewares=posteio-admin-redirect@docker" - "traefik.http.routers.posteio-admin.tls.certresolver=mydnschallenge" - "traefik.http.routers.posteio-admin.service=posteio-admin" - "traefik.http.services.posteio-admin.loadbalancer.server.port=80" - "traefik.http.routers.posteio-letsencrypt.rule=HostRegexp(`mydomain.com`,`{subdomain:[a-z]*}.mydomain.com`) && PathPrefix(`/.well-known/`)" - "traefik.http.routers.posteio-letsencrypt.entrypoints=http" - "traefik.http.routers.posteio-letsencrypt.service=webmail" - "traefik.http.services.posteio-letsencrypt.loadbalancer.server.port=80" traefik-certificate-extractor: container_name: traefik-certs-extractor image: danielhuisman/traefik-certificate-extractor restart: always depends_on: - reverse-proxy volumes: - "./containers/traefik/letsencrypt:/app/data" - "./containers/letsencrypt/certs:/app/certs" labels: - "traefik.enable=false"
Set up your own HTTPS and HTTP port for poste.io container.
It needs to define DNS entries in your DNS table
$TTL 3600 @ 3600 IN A AA.BB.CC.DD mail 3600 IN CNAME mydomain.com posteio 3600 IN CNAME mydomain.com. reverseproxy 3600 IN CNAME mydomain.com. webmail 3600 IN CNAME mydomain.com.
webmail is for the webmail interface, posteio for poste.io admin interface, and reverseproxy for traefik.io
traefik.toml
# traefik.toml ################################################################ # Global configuration ################################################################ [entryPoints] [entryPoints.http] address = ":80" [entryPoints.https] address = ":443" [api] [providers] [providers.docker] endpoint = "unix:///var/run/docker.sock" watch = true [providers.file] directory= "/config" watch = true #filename = "/etc/traefik/services.toml" [certificatesResolvers.mydnschallenge.acme] email = "postmaster@mydomain.com" storage = "/letsencrypt/acme.json" [certificatesResolvers.mydnschallenge.acme.dnsChallenge] provider = "ovh" # Configuring a buffer of 100 lines [accessLog] filePath = "/logs/access.log" bufferingSize = 100 # Writing Logs to a File [log] filePath = "/logs/traefik.log" level="ERROR"
I added 2 configuration files : config/middlewares.toml and config/services.toml
config/middlewares.toml
[http.middlewares] [http.middlewares.redirect-https.redirectScheme] scheme = "https" [http.routers] [http.routers.redirs] rule = "HostRegexp(`{host:.+}`)" entrypoints = ["http"] middlewares = ["redirect-https"] service = "noop" [http.services] # noop service, the URL will be never called [http.services.noop.loadBalancer] [[http.services.noop.loadBalancer.servers]] url = "http://192.168.0.X" # My router
config/services.toml
[http] [http.services] [http.services.nas] [http.services.nas.loadBalancer] [[http.services.nas.loadBalancer.servers]] url = "http://192.168.0.X:Y/" # IP:Port of my local service (nas for example)
My domain provider is OVH. Set up for authentication keys shall be done as follows :
- Go to https://eu.api.ovh.com/createApp/
- Fill the required parameters. Fill the account number with your OVH id and password
- You will get an
Application Key
and anApplication Secret
to write in thedocker-compose.yml
file - In a terminal, type
curl -XPOST -H“X-Ovh-Application: <Application Key>” -H “Content-type: application/json” https://eu.api.ovh.com/1.0/auth/credential -d '{“accessRules”: [{“method”: “GET”,“path”: “/*”},{“method”: “POST”,“path”: “/*”},{“method”: “PUT”,“path”: “/*”},{“method”: “DELETE”,“path”: “/*”}],“redirection”: “https://reverseproxy.mydomain.com/”}'
using the correctApplication Key
- This will give a
consumerKey
to set up in thedocker-compose.yml
file and a URL - Open this URL in your web browser and fill it as previously done. Set up validity to
Unlimited
- In the
docker-compose.yml
file,OVH_ENDPOINT
must be set up toovh-eu
Hope this will help !
-
@vincowl thanks again bro
this labels working on perfect with traefik v2
- Log in to comment
For proper uninterupted function you need poste container to take care of its certs - with LE you can issue multiple certs on same domain, so it is not problem if proxy has different cert than poste
There are two options how to make it work A) share .well-known folder between proxy and mailserver like https://gist.github.com/analogic/51fbe91b580d7913b72320f89bf994cc#file-docker-compose-yml B) direct port 80 on reverse proxy to poste container without any redirect to https - it is required by ACME - .well-known folder must be accessible
Problem with sharing certificates directly is that dovecot and haraka needs to be reloaded on cert change. I have an idea to catch fs events with inotify or something like incrond but its far away from perfect solution...