TCP catch-all router issue

I'm struggling to configure a catch-all TCP router with TLS passthrough. My router is configured in from a file provider:

tcp:
  routers: 
    to-traefik1-https:
      rule: "HostSNI(`*`)"
      entrypoints:
        - "websecure"
      service: service1-https
      tls:
        passthrough: true
  services:
    service1-https:
      loadBalancer:
        servers:
          - address: "service1:443"

But this doesn't work. If I specify a specific hostname instead of * this matches, and passes the requests successfully to my service which terminates TLS itself.

Everything I've read suggests * will match any hostname, but when I try this Traefik terminates the TLS with the default self-signed certificate and returns a 404.

Any ideas?

Hi @jjg23,
Thanks for your interest in Traefik.

I didn't manage to reproduce your issue with your simple configuration.
Probably I would need more information about your configuration and how your components are interacting with each others.

Could you provide your Traefik configuration, Traefik version, and Traefik logs (in DEBUG) if possible?
Also, is there more services and routers defined?

I am working on cleaning up that info so that it can be posted publicly. In the interim, I'm testing with version 2.6. Do you have a minimal configuration that you can share where this is working as expected?

Thanks!

Hey, yes sure.

docker-compose.yml

version: '3.9'

services:
  traefik:
    image: traefik:v2.7
    command:
      - --providers.docker
      - --providers.file.directory=/traefik
      - --log.level=DEBUG
      - --api.insecure=true
      - --entrypoints.websecure.address=:443
    ports:
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik:/traefik
    tty: true

  whoami:
    image: traefik/whoami:latest
    command:
      - --name=whoami
      - --port=443
      - --cert=/certs/server.crt
      - --key=/certs/server.key
    volumes:
      - ./certs:/certs

traefik/traefik.yml

tcp:
  routers: 
    my-router:
      rule: "HostSNI(`*`)"
      entrypoints:
        - "websecure"
      service: whoami-https
      tls:
        passthrough: true
  services:
    whoami-https:
      loadBalancer:
        servers:
          - address: "whoami:443"

Thanks for this, I got it working! I think it was ultimately a race condition caused by the backend service not being up when the TCP service was created. Since the hostname didn't resolve, there were no servers in the load balancer pool. I've fixed this by adding a check to my entrypoint script to make sure the backend is responding prior to executing traefik.

It turns out what I'm doing may not be possible or I may be doing it wrong though. I'd essentially like any HTTPS request that doesn't match a router Host rule to be passed through as an unmodified HTTPS request. With the HostSNI(*) rule, ALL HTTPS requests get passed through, even if a service defined an HTTP router since TCP take precedence over HTTP routers. I have a defined HTTP catch-all router, but HTTP routers don't support TLS passthrough, so I was looking at the TCP version.

Any suggestions?

Hi @jjg23,
Thanks for your feedback.

I better understand your use case. On which version did you test?
Unfortunately, I posted an example with v2.7, but we have a regression on this version on TCP/HTTP routing. We are fixing it here. Could you try with v2.6?

I was testing on 2.7. Are you suggesting that what I'm trying to do should be possible?

I've just deployed on version 2.6.6. It seems like TLS passthrough via the TCP catchall router works as long as I have no HTTPS services deployed (HTTP seems to work fine). As soon as I deploy an HTTPS service, the TCP-TLS starts returning the default self-signed cert, and a 404 error.

For reference, here's the HTTPS service I'm testing with that's causing the TCP-TLS passthrough to stop working:

version: "3"

services:
    client:
        image: nginx
        environment:
                - PORT=80
        volumes:
            - ./src:/usr/share/nginx/html
        networks:
           - traefik-net
        deploy:
                labels:
                        - traefik.enable=true
                        - traefik.http.routers.nginx3.entrypoints=web
                        - traefik.http.routers.nginx3.rule=Host(`hostname.example.com`)
                        - traefik.http.services.nginx3-svc.loadbalancer.server.port=80

                        - traefik.http.routers.nginx3.middlewares=https-redirect
                        - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
                        - traefik.http.middlewares.https-redirect.redirectscheme.permanent=true

                        - traefik.http.routers.nginx3-secure.tls=true
                        - traefik.http.routers.nginx3-secure.tls.certresolver=incommon
                        - traefik.http.routers.nginx3-secure.entrypoints=websecure
                        - traefik.http.routers.nginx3-secure.rule=Host(`hostname.example.com`)
networks:
   traefik-net:
       external: true