Default router (404 error) TLS options

I'm running traefik 2 in my docker swarm setup. For this I have 3 entrypoints: 2 for internal access (80 and 443) and another one https_external on another port (9999?) that is exposed externally in the router.

Snip from compose file

   image: "traefik:v2.4.11"
    command:
      - --providers.docker=true
      - --providers.docker.swarmmode=true
      - --providers.docker.exposedbydefault=false
      - --providers.docker.network=traefik_default
      - --entrypoints.http.address=:80
      - --entrypoints.https.address=:443
      - --entrypoints.https_external.address=:9999
      - --providers.file.directory=/etc/traefik/dynamic
      - --entrypoints.https_external.http.tls.options=cfcert@file

As all the services exposed externally should be accessed only through Cloudflare, I've setup cfcert tls options to require cloudflare origin client certificate

tls:
  options:
    cfcert:
      clientAuth:
        caFiles:
          - /etc/traefik/dynamic/cf-DOMAIN-origin-pull-ca.pem
        clientAuthType: RequireAndVerifyClientCert

So far so good, given the flag - --entrypoints.https_external.http.tls.options=cfcert@file all services bound to https_external entrypoint default to cfcert and in case I want to have one that does not require proxying through cloudflare, I can override tls.options at the service level.

The (minor) issue is that any direct request to my external port that does not match an existing service will fall into the 404 router, ignoring the entrypoint tls options.

I've tried changing the default tls option instead to require the CF client cert but then it applies to all entrypoints (including the 80/443 internal ones).
I've tried to create a catch-all service but using HostRegexp ignores tls option.

TL;DR; Is there any way to configure default 404 router tls options just for an entrypoint? (instead of modifying the default tls options)

Thanks

Hi @skboy

Are you using strict SNI? That can stop unexpected domains at the TLS handshake.

Not sure how you are doing TLS certificates in your setup, given that a 404 is received it must be okay.
A catchall router using the https_external entrypoint can use a PathPrefix(`/`) rule AND the tls options cfcert@file

Hey @cakiwi thanks for the quick reply!

I've tried making a catch all router but using HostRegexp(.*) instead of the PathPrefix(/). It worked as catch all as every requested ended up there but it didn't enforce the requirement of client cert.

Switching to PathPrefix seems to yield the same result (though I reckon it should be a lighter match than a Regexp hehe)

I got the same warning as with HostRegexp:

time="2021-07-24T01:57:42Z" level=warning msg="No domain found in rule PathPrefix(`/`), the TLS options applied for this router will depend on the hostSNI of each request" entryPointName=https_external routerName=whoamitest2@docker

Then also added the tls.option as you suggested even though it was already the default option for that entrypoint.
But it still doesn't work. It catches all requests (any cname pointing to my IP), but does not require cfcert@file.

Here are my labels:

      labels:
        traefik.enable: "true"
        traefik.docker.network: traefik_default
        traefik.http.services.whoamitest.loadbalancer.server.port: 80
        traefik.http.routers.whoamitest.rule: "Host(`testit.mydomain.com`)"
        traefik.http.routers.whoamitest.entrypoints: https_external
        traefik.http.routers.whoamitest.tls.options: default_or_invalid
        traefik.http.routers.whoamitest.tls.certresolver: letsresolver
        traefik.http.routers.whoamitest1.rule: "Host(`testit-cf.mydomain.com`)"
        traefik.http.routers.whoamitest1.entrypoints: https_external
        traefik.http.routers.whoamitest2.rule: "PathPrefix(`/`)"
        traefik.http.routers.whoamitest2.entrypoints: https_external
        traefik.http.routers.whoamitest2.tls.options: cfcert@file

Visiting testit (with invalid tls.option so it falls back to global default) both through and without cloudflare works. as expected.
Visiting testit-cf (which uses cfcert@file as it doesn't any tls.option set: works through cloudflare, get locked skipping cloudflare. as expected
Visiting random-garbage (that resolves to same IP but is not bound to any service) does go this service (catchall) but works via CF or without. Not expected as endpoint has cfcert@file as tls.options and the service itself also has it explicity (as you suggested).

any more tips?