Proxying entire subdomain to external server: troubles with TLS

Hi all,

I'm trying to set-up Traefik so that it supports proxying an entire subdomain to another server (also runnning Traefik), while doing TLS with LetsEncrypt-provided certificates on the primary server. I'm running into an issue though, where my use of HostRegexp leads to Traefik not recognizing the domain, resulting in self-signed certificates being used.

The primary server is configured as follows (only relevant config shown):

services:
  traefik:
    image: "traefik:v2.8"
    command:
        - --providers.file=true
        - --providers.file.filename=/rules.yml
    
        - --entrypoints.https.address=:443
        - --certificatesResolvers.letsencrypt.acme.caServer=https://acme-v02.api.letsencrypt.org/directory
        - --certificatesResolvers.letsencrypt.acme.email=my.email@...
        - --certificatesResolvers.letsencrypt.acme.tlschallenge=true

rules.yml:

http:
  routers:
    otherserver:
      entryPoints:
        - "https"
      rule: "HostRegexp(`otherserver.mydomain.com`, `{subdomain:[a-z.]+}.otherserver.mydomain.com`)"
      service: otherserver
      tls:
        certresolver: letsencrypt
  services:
    otherserver:
      loadBalancer:
        servers:
          - url: "http://10.0.0.1:80"
        passHostHeader: true

The secondary server is running Traefik too, over HTTP only:

services:
  traefik:
    image: "traefik:v2.8"
    command:
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false

  whoami:
    image: containous/whoami:v1.3.0
    expose:
      - "80"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.otherserver.mydomain.net`)"

Proxying the subdomain like this works, but I'm getting the following warning in my logs:

level=warning
msg="No domain found in rule HostRegexp(`otherserver.mydomain.com`, `{subdomain:[a-z.]+}.otherserver.mydomain.com`), the TLS options applied for this router will depend on the SNI of each request"
routerName=otherserver@file
entryPointName=https

And the cert in use is the default self-signed one:

$ curl -v -k whoami.otherserver.mydomain.com
* Server certificate:
*  subject: CN=TRAEFIK DEFAULT CERT
*  start date: Aug  8 20:31:30 2022 GMT
*  expire date: Aug  8 20:31:30 2023 GMT
*  issuer: CN=TRAEFIK DEFAULT CERT
*  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.

Appreciate any help here :slight_smile: I couldn't get HostSNIRegexp to work (unsupported function: HostSNIRegexp), if that even applies here. I also came across another post suggesting tls: passthrough=true, but I'd prefer to keep the TLS set-up on the primary host only.

Hi @maleadt,

Thanks for your interest in Traefik,

When using HostRegexp matcher, Traefik cannot infer which domains you are requesting a certificate for. As described in the documentation, you should use the tls.domains configuration option for that purpose.

Something like the following should fix the issue:

http:
  routers:
    otherserver:
      entryPoints:
        - https
      rule: "HostRegexp(`otherserver.mydomain.com`, `{subdomain:[a-z.]+}.otherserver.mydomain.com`)"
      service: otherserver
      tls:
        certresolver: letsencrypt
        domains:
          - main: otherserver.mydomain.com
            sans:
              - *.otherserver.mydomain.com
# ...

Hope this helps!

1 Like

That helps, thanks! I did not realize this would require a wildcard certificate though -- I presumed the certificate would be requested after looking at the SNI header. In my case (using Let's Encrypt), that requires a DNS challenge which isn't trivial since I'm using Namecheap (requiring whitelisting a static IP address, which I don't have).

Is there an alternative approach possible, e.g., forwarding requests to the secondary server and handling TLS over there? I'd rather duplicate my ACME config than switch DNS providers over this :slight_smile:

Is there an alternative approach possible, e.g., forwarding requests to the secondary server and handling TLS over there? I'd rather duplicate my ACME config than switch DNS providers over this :slight_smile:

One solution I can think of is to do the TLS termination on the second Traefik by using a passthrough router which leverages a HostSNIRegexp rule. If I am not wrong, the TLS challenge should be forwarded and solved by the second Traefik (I never tested it).

Another working solution would be to modify the first Traefik router each time you add a subdomain to the second Traefik.

Yeah, that works. For completeness, on my primary server I now have:

tcp:
  routers:
    otherserver:
      entryPoints:
        - "https"
      rule: "HostSNIRegexp(`otherserver.mydomain.com`, `{subdomain:[a-z.]+}.otherserver.mydomain.com`)"
      service: otherserver
      tls:
        passthrough: true
  services:
    otherserver:
      loadBalancer:
        servers:
          - address: "10.0.0.1:443"

And on my other server I just have a plain Let's Encrypt configuration again. Not ideal, but it works without too much configuration :slight_smile: Thanks for the help!

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