Hi,
I have a docker file, with the following configuration (only relevant parts reported)
For traefik:
version: '3.5'
services:
shared-traefik:
image: traefik:v2.6.3
container_name: shared-traefik
ports:
- "80:80"
- "443:443"
- "6432:6432"
command:
...
- --entrypoints.pgbouncer.address=:6432
#- --entrypoints.pgbouncer.http.tls=true
#- --entrypoints.pgbouncer.http.tls.certresolver=myresolver
networks:
.aaa_shared_network:
For pgbouncer:
pgbouncer:
image: bitnami/pgbouncer:1.16.1-debian-10-r117
container_name: shared-pgbouncer
...
networks:
.aaa_shared_network:
labels:
- "traefik.enable=true"
- "traefik.tcp.services.shared-pgbouncer.loadbalancer.server.port=6432"
- "traefik.tcp.routers.shared-pgbouncer.entrypoints=pgbouncer"
- "traefik.tcp.routers.shared-pgbouncer.service=shared-pgbouncer"
- "traefik.tcp.routers.shared-pgbouncer.tls=false"
- "traefik.tcp.routers.shared-pgbouncer.tls.certresolver=myresolver"
- "traefik.tcp.routers.shared-pgbouncer.tls.domains[0].main=my.domain.com"
- "traefik.tcp.routers.shared-pgbouncer.rule=HostSNI(`*`)"
This works fine: no tls, I can connect a client (e.g. pgadmin) to pgbouncer.
The issue is that I am unable to switch to TLS, for example, if I change the line:
- "traefik.tcp.routers.shared-pgbouncer.tls=false"
With:
- "traefik.tcp.routers.shared-pgbouncer.tls=true"
I am no more able to connect: I always go in "timeout".
I also tried to change:
- "traefik.tcp.routers.shared-pgbouncer.rule=HostSNI(`*`)"
With:
- "traefik.tcp.routers.shared-pgbouncer.rule=HostSNI(`my.domain.com`)"
But with no luck.
Can someone help please?
Regards.
I had the same troubles and this is how I solved it
create only 1 resolver at the central traefik level
use it to generate domain.tld + *.domain.tld certs
have your services use this endpoint
traefik:
image: traefik:latest
container_name: "traefik"
command:
- --log.level=DEBUG
- --api.dashboard=true
- --api.insecure=true
# Do not expose all Docker services by default
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- -- "--providers.docker.endpoint=unix:///var/run/docker.sock"
#- --providers.docker.endpoint=tcp://proxy:2375
- --providers.docker.network=traefik-proxy
# DNS Challenge (domain.tld and *.domain.tld DNS zones are defined there) : hetzner
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- --certificatesresolvers.myresolver.acme.email=postmaster@${SERVER_HOSTNAME}
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.myresolver.acme.dnschallenge=true
- --certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=0
- --certificatesresolvers.myresolver.acme.dnschallenge.provider=hetzner
- --certificatesresolvers.myresolver.acme.dnschallenge.resolvers=helium.ns.hetzner.de,hydrogen.ns.hetzner.com,oxygen.ns.hetzner.com
# HTTPS : port 443, with letsencrypt certificates provided by myresolver
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls=true
- --entrypoints.websecure.http.tls.certResolver=myresolver
- --entrypoints.websecure.http.tls.domains[0].main=${CERT_DOMAIN}
- --entrypoints.websecure.http.tls.domains[0].sans=*.${CERT_DOMAIN}
# Redirect HTTP (web) to HTTPS (websecure)
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
and for a random service in another docker-compose.yml
file
version: "3.6"
networks:
database: {}
node: {}
frontend:
external:
name: traefik-proxy
services:
whoami:
image: "traefik/whoami"
container_name: "whoami"
networks:
- frontend
- node
- database
ports:
- 90:80
labels:
- traefik.enable=true
- traefik.docker.network=traefik-proxy
- traefik.http.routers.whoami.rule=Host(`whoami.${CERT_DOMAIN}`)
- traefik.http.routers.whoami.entrypoints=websecure
- traefik.http.services.whoami.loadbalancer.server.port=80
Note that I am using hetzner DNS challenge, but it should work with any other provider !
hope it helps !
Hi,
thank you for the help.
Actually, my issue is somehow different (and sorry, I did not state it clearly).
Exposing HTTP/HTTPS endpoints works fine for me, also over non default ports (i.e. no 80/443).
My issue is in exposing TCP/TCP+TLS endpoints.
The strange thing is that if I use Mosquitto, I am able to proxy 1883 (TCP/MQTT) and 8883 (TCP+TLS/MQTTS). Traefik:
services:
shared-traefik:
...
ports:
- "80:80"
- "443:443"
- "1883:1883"
- "8883:8883"
command:
- --log.level=INFO
- --api=true
- --api.insecure=true
- --api.dashboard=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.web.http.redirections.entryPoint.priority=1
- --entrypoints.web.http.redirections.entryPoint.permanent=true
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls=true
- --entrypoints.websecure.http.tls.certresolver=myresolver
- --entrypoints.mqtt.address=:1883
- --entrypoints.mqtt.http.tls=false
- --entrypoints.mqtts.address=:8883
- --entrypoints.mqtts.http.tls=true
- --entrypoints.mqtts.http.tls.certresolver=myresolver
- --certificatesresolvers.myresolver.acme.httpchallenge=true
- --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
#- --certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
- --certificatesresolvers.myresolver.acme.email=my@email.it
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
- --providers.file.directory=/traefik-config
- --providers.file.watch=true
- --serverstransport.insecureskipverify=true
networks:
.aaa_shared_network:
...
And mosquitto:
shared-mosquitto:
...
networks:
.aaa_shared_network:
labels:
- "traefik.enable=true"
- "traefik.tcp.services.shared-mosquitto.loadbalancer.server.port=1883"
- "traefik.tcp.routers.shared-mosquitto.entrypoints=mqtts"
- "traefik.tcp.routers.shared-mosquitto.tls=true"
- "traefik.tcp.routers.shared-mosquitto.tls.certresolver=myresolver"
- "traefik.tcp.routers.shared-mosquitto.rule=HostSNI(`my.domain.it`)"
- "traefik.tcp.routers.shared-mosquitto-mqtt.entrypoints=mqtt"
- "traefik.tcp.routers.shared-mosquitto-mqtt.rule=HostSNI(`*`)"
- "traefik.tcp.routers.shared-mosquitto-mqtt.tls=false"
So I was expecting to be able to proxy pgbouncer with a similar config.
And actually, for the plain TCP case pgbouncer works fine.
So I am unable to understand why with TCP+TLS it does not works...
Every connection I try goes in timeout. So I tried a lot of tweaks in the hope to make it work, but with no luck. Maybe is it an incompatibility with pgbouncer? Or someting I do wrong in the connection? Or something else?
Regards
Hi,
after more research, I ended up with this answer in a similar post:
Hi @gprime44 , thanks for your interest!
Does the databases work if you disable TLS on their TCP routers?
E.g. removing the 2 following lines:
- traefik.tcp.routers.mssql.tls=true
(...)
- traefik.tcp.routers.postgres.tls=true
The reasoning behind is the following: enabling TLS termination (or even TLS passthrough) on Traefik TCP routers require the application protocol served to support "SNI" (Server Name Indication) during a standard TLS handshake.
Alas some protocols as Pos…
So I suppose it is not possible. It would have been nice, since traefik exposes valid certificates...
Regards.
cakiwi
April 12, 2022, 6:31pm
5
The problem is the way that postgres does tls.
Postgres starts tls after connecting, it is done within postgres frontend/backend protocol. PostgreSQL: Documentation: 14: 53.2. Message Flow
Traefik is expecting a TLS handshake at the start and uses the servername from the SNI extensions to match a router.