I'm trying to expose coturn TCP over Traefik (latest version 3.7.5). Yet I've hit a wall where Traefik will only forwards TLS traffic.
Naturally I've set up a TCP router (with TLS passthrough since coturn runs TCP/TLS and raw TCP on the same port) and service on the container with the following labels:
traefik.enable=true
traefik.tcp.routers.coturn.entrypoints=stun
traefik.tcp.routers.coturn.rule=HostSNI(`*`)
traefik.tcp.routers.coturn.service=coturn
traefik.tcp.routers.coturn.priority=1
traefik.tcp.routers.coturn.tls.passthrough=true
traefik.tcp.routers.coturns.entrypoints=stunsecure
traefik.tcp.routers.coturns.rule=HostSNI(`*`)
traefik.tcp.routers.coturns.service=coturn
traefik.tcp.routers.coturns.priority=1
traefik.tcp.routers.coturns.tls.passthrough=true
traefik.tcp.services.coturn.loadbalancer.server.port=5555
traefik.tcp.services.coturn.loadbalancer.serversTransport=ppv2@file
I've double and triple checked this and am like 99.99% sure there isn't a configuration issue here. (I've turned TLS on and off, changes priority, switched fron HostSNI to ClientIP disabled one of the two entrypoints, etc. and it didn't change)
The ppv2 is defined like this:
tcp:
serversTransports:
ppv2:
proxyProtocol:
version: 2
And my static config looks like this:
entryPoints:
web:
address: ":80"
http:
redirections:
entrypoint:
to: "websecure"
scheme: "https"
websecure:
address: ":443"
allowACMEByPass: true
http3:
advertisedPort: '443'
http:
tls:
certResolver: letsencrypt
encodedCharacters:
allowEncodedSlash: false
allowEncodedBackSlash: false
allowEncodedNullCharacter: false
allowEncodedSemicolon: false
allowEncodedPercent: false
allowEncodedQuestionMark: false
allowEncodedHash: false
transport:
respondingTimeouts:
readTimeout: 0
writeTimeout: 0
idleTimeout: 0
forwardedHeaders:
trustedIPs:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
admin:
address: ":8000"
stun:
address: ":3478/tcp"
stunsecure:
address: ":5349/tcp"
log:
format: common
level: TRACE
accessLog:
format: json
filePath: "/var/log/traefik/access.log"
api:
dashboard: true
providers:
docker:
exposedByDefault: false
watch: true
file:
filename: "/etc/traefik/dynamic.yml"
certificatesResolvers:
letsencrypt:
acme:
email: mail@expunged.internal
tlsChallenge: {}
serversTransports:
forwardingTimeouts:
responseHeaderTimeout: "0s"
idleConnTimeout: "0s"
There are HTTP routers running (that are working) but I've verified through dashboard and API that none of them are using the stun and stunsecure entrypoints.
In all cases the logs show that the TCP router and passthrough are being created. Also the access logs show a connection being made and Traefik respond yet crucially it does so with no router selected and so it responds with a HTTP 404.
Now, this happens ONLY when doing a bare connection (i.e. testing via Telnet or HTTP). When doing a HTTPS connection (so TLS) the logs say that a TCP connection was created, I get no 404 but rather a browser timeout (as I should since it's not HTTP) and the Coturn logs show a successfull (well, as successfull as HTTPS to a stun server can be) connection.
I've tried pretty much everything and can't find my mistake. How the hell can Traefik route successfully with TLS but not without it? I know HostSNI can't handle specific domains without TLS but this here is a catchall. Also the same error occured when using ClientIP(`0.0.0.0/0`) so it's not HostSNI that's wrong here.
What am I missing? Is this a bug? WTH?