I am trying to get SSL Passthrough working, I have:
- a single IP address
- Domains are fronted by Cloudflare
- multiple domains i.e. www.domaina.com & www.999domainb.com
- I have 2 hosts both running the same version of Traefik 2.5, both on the same backend network
- I want Host A to deal with all requests from www.domaina.com & pass through www.999domainb.com to Host B
- Host B to deal with www.999domainb.com
- Docker config is not Swarm mode as Host B is not always available
Traefik definition for Host A & B
services:
############################# FRONTENDS
# Traefik 2 - Reverse Proxy
traefik:
container_name: traefik
hostname: traefik
image: traefik:v2.5.6 # traefik:livarot # picodon v2.3.x # chevrotin v2.2.x
# image: traefik:v2.4.7 # :picodon # chevrotin # the chevrotin tag refers to v2.2.x
restart: unless-stopped
command: # CLI arguments
- --global.checkNewVersion=false
- --global.sendAnonymousUsage=false
- --entryPoints.http.address=:80
- --entryPoints.https.address=:443
- --entrypoints.https.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22
- --entryPoints.traefik.address=:8080 # 8093
# - --entryPoints.ping.address=:8081
- --api=true
- --api.insecure=true
- --api.dashboard=true
#- --ping=true
- --pilot.token=$TRAEFIK_PILOT_TOKEN
# - --serversTransport.insecureSkipVerify=true
- --log=true
- --log.level=Debug # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
- --accessLog=true
- --accessLog.filePath=/logs/access.log
- --accessLog.bufferingSize=100 # Configuring a buffer of 100 lines
- --accessLog.filters.statusCodes=200,300-302,400-499
- --accesslog.format=json
- --accesslog.filters.retryattempts
- --accesslog.filters.minduration=10ms
- --accesslog.fields.defaultmode=keep
- --accesslog.fields.names.ClientUsername=drop
- --accesslog.fields.headers.defaultmode=keep
- --accesslog.fields.headers.names.User-Agent=redact
- --accesslog.fields.headers.names.Authorization=drop
- --accesslog.fields.headers.names.Content-Type=keep
- --providers.docker=true
- --providers.docker.endpoint=tcp://socket-proxy:2375
# Automatically set Host rule for services
- --providers.docker.exposedByDefault=false
# - --entrypoints.https.http.middlewares=chain-oauth@file
- --entrypoints.https.http.tls.options=tls-opts@file
# Add dns-cloudflare as default certresolver for all services. Also enables TLS and no need to specify on individual services
- --entrypoints.https.http.tls.certresolver=dns-cloudflare
- --entrypoints.https.http.tls.domains[0].main=$DOMAINNAME0
- --entrypoints.https.http.tls.domains[0].sans=*.$DOMAINNAME0
# - --entrypoints.https.http.tls.domains[1].main=$DOMAINNAME1 # Pulls main cert for second domain
# - --entrypoints.https.http.tls.domains[1].sans=*.$DOMAINNAME1 # Pulls wildcard cert for second domain
- --providers.docker.network=t2_proxy
- --providers.docker.swarmMode=false
- --providers.file.directory=/rules # Load dynamic configuration from one or more .toml or .yml files in a directory
# - --providers.file.filename=/path/to/file # Load dynamic configuration from a file
- --providers.file.watch=true # Only works on top level files in the rules folder
# Acme settings
# - --certificatesResolvers.dns-cloudflare.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory # LetsEncrypt Staging Server - uncomment when testing
# ## ACME info
- --certificatesResolvers.dns-cloudflare.acme.email=$CLOUDFLARE_EMAIL
- --certificatesResolvers.dns-cloudflare.acme.storage=/acme.json
# ## DNS Challenge
- --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.provider=cloudflare
- --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.resolvers=1.1.1.1:53,1.0.0.1:53
- --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.delayBeforeCheck=90 # To delay DNS check and reduce LE hitrate
networks:
t2_proxy:
# ipv4_address: xxx.xxx.xxx.xxx # You can specify a static IP
socket_proxy:
# ipv4_address: xxx.xxx.xxx.xxx
security_opt:
- no-new-privileges:true
#healthcheck:
# test: ["CMD", "traefik", "healthcheck", "--ping"]
# interval: 5s
# retries: 3
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
- target: 8080
published: 8080
protocol: tcp
mode: host
#- target: 8081
# published: 8082
# protocol: tcp
# mode: host
volumes:
- $DOCKERDIR/traefik2/rules:/rules # file provider directory
- $DOCKERDIR/traefik2/acme/acme.json:/acme/acme.json # cert location - you must touch this file and change permissions to 600
- $DOCKERDIR/traefik2/traefik.log:/logs/traefik.log # for fail2ban - make sure to touch file before starting container
- $DOCKERDIR/traefik2/access.log:/logs/access.log
- $DOCKERDIR/shared:/shared
environment:
- CF_API_EMAIL_FILE=/run/secrets/cloudflare_email
- CF_API_KEY_FILE=/run/secrets/cloudflare_api_key
secrets:
- cloudflare_email
- cloudflare_api_key
labels:
#- "autoheal=true"
- "traefik.enable=true"
# HTTP-to-HTTPS Redirect
- "traefik.http.routers.http-catchall.entrypoints=http"
- "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
# HTTP Routers
- "traefik.http.routers.traefik-rtr.entrypoints=https"
- "traefik.http.routers.traefik-rtr.rule=Host(`traefik.$DOMAINNAME0`)"
## Services - API
- "traefik.http.routers.traefik-rtr.service=api@internal"
## Healthcheck/ping
#- "traefik.http.routers.ping.rule=HostHeader(`traefik.$DOMAINNAME0`) && Path(`/ping`)"
#- "traefik.http.routers.ping.tls=true"
#- "traefik.http.routers.ping.service=ping@internal"
## Middlewares
# - "traefik.http.routers.traefik-rtr.middlewares=chain-oauth@file"
- "traefik.http.routers.traefik-rtr.middlewares=chain-authelia@file"
# portainer labels
- system=true
- systemservices=true
Domain passthrough yaml config
tcp:
routers:
development-rtr:
entryPoints:
- "https"
rule: "HostSNI(`*.999domainb.com.`,`app1.999domainb.com`,`app2.999domainb.com`,`www.999domainb.com`)"
service: development-svc
tls:
passthrough: true
services:
development-svc:
loadBalancer:
servers:
- address: "xxx.xxx.xxx.hostb:80" # or whatever your external host's IP:port is
- address: "xxx.xxx.xxx.hostb:443"
Image of what I am trying to achieve (sorry it's not perfect)
When I have tried to set this up I do not see errors in logs but Cloudflare says the host is unavailable.