I have a TLS passthrough service up and running, and it works great. However, it is the catchall, and so uses HostSNI(*) to catch all domains. I have another service that is a website (let's call it example.company.com), which also needs to server over HTTPS. Is there a way to configure the TCP router to route https://example.company.com to my website service, and all other domains to the catch all HostSNI(*) service?
Basically need the priority functionality from HTTP routers to be available with TCP routers that are using SNI.
Hi @piurafunk , if you specify HostSNI(*), then it means that you expect any incoming request on the associated entrypoint(s) of this router to be intercepted.
Is there something forbidding you to bind the TCP router only to the entrypoint corresponding to your TCP protocol, and your HTTP router(s) only on the entrypoints for hte 80 and 443 ports?
Oh, good. Then, since HTTP+TLS are supporting SNI and doing proper handshake, then you can specify the expected Host to your HostSNI() rule instead of *. Let us know if there is anything preventing you to specify this domain?
Yes, if I knew the expected host it would be easy. Unfortunately, my catchall is just that: an HTTPS catchall. Any hosts can go through it. There are just a few hosts that I do not want to go through it, as they have their own services (also HTTPS).
I believe I could get this to work if HostSNI had a RegExp version of it, like Host as its counterpart HostRegExp, but I don't believe that rule exists.
Hi @piurafunk, after checking with other maintainers, your initial case should work, as they told me that HostSNI(*) should behave as a fallback in this case.
Could you share your configuration so we can check and reproduce?
This is my docker-compose.yml, I trimmed out unhelpful bits (like source volume mounts and what not).
version: "3.7"
services:
traefik:
# The official v2.0 Traefik docker image
image: traefik:v2.0
# Enables the web UI and tells Traefik to listen to docker
command: [
"--api.insecure=true",
"--providers.docker",
"--entryPoints.websecure.address=:443",
"--entryPoints.web.address=:80",
"--certificatesResolvers.api.acme.email=<REDACTED>",
"--certificatesResolvers.api.acme.storage=acme.json",
"--certificatesResolvers.api.acme.httpChallenge.entryPoint=web"
]
ports:
# The HTTP port
- "80:80"
# The HTTPS port
- "443:443"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock:ro
sni:
image: lancachenet/sniproxy
expose:
- 443
labels:
- "traefik.tcp.routers.cache-sni.tls.passthrough=true"
- "traefik.tcp.routers.cache-sni.entryPoints=websecure"
- "traefik.tcp.routers.cache-sni.rule=HostSNI(`*`)"
environment:
- "UPSTREAM_DNS=1.1.1.1 1.0.0.1"
api:
image: php:7.3-apache
labels:
- "traefik.http.routers.api-https.rule=Host(`example.company.com`)"
- "traefik.http.routers.api-https.tls"
- "traefik.http.routers.api-https.tls.certResolver=api"
- "traefik.http.routers.api-http.rule=Host(`example.company.com`)"
- "traefik.http.routers.api-https.priority=2"
- "traefik.http.routers.api-http.priority=2"
- "traefik.entryPoints.web.address=:80"
- "traefik.entryPoints.web-secure.address=:443"
I have tried it in this manner, but the catchall HTTPS rule grabs the inbound request before Traefik can terminate TLS for the API container (note: API is TLS terminated, SNI is TLS passthrough). Using HTTPie, I can make a request and watch it show up in the SNI container:
I tried to configure a priority (Link) for an ingressRouteTCP router within kubernetes. The CRD defines the priority field, however, when trying to define it, I recieve an error:
error validating data: ValidationError(IngressRouteTCP.spec.routes[0]): unknown field "priority" in us.containo.traefik.v1alpha1.IngressRouteTCP.spec.routes; if you choose to ignore these errors, turn validation off with --validate=false
I used traefik version 2.8.3 and 2.9-rc3 for my test. This is the configuration I used: