TCP & UDP Routing
TCP Routing
Traefik can route raw TCP traffic in addition to HTTP. This is useful for databases, message queues, gRPC, and any non-HTTP protocol.
TCP routers use HostSNI() matching based on the TLS Server Name Indication. If the connection is not TLS, a dedicated TCP router per entrypoint is typically used.
TCP vs HTTP
| Feature | HTTP Routers | TCP Routers |
|---|---|---|
| Protocol | HTTP/1.1, HTTP/2, HTTP/3 | Raw TCP |
| Matching | Host, Path, Headers, etc. | HostSNI only |
| Middleware | Full HTTP middleware | Limited (IP allow/deny) |
| TLS Termination | Yes | Yes (or passthrough) |
| Use Cases | Web apps, APIs | Databases, gRPC, custom protocols |
TCP Router Configuration
tcp:
routers:
postgres:
rule: "HostSNI(`*`)"
entryPoints:
- postgres
service: postgres-service
tls:
passthrough: true
services:
postgres-service:
loadBalancer:
servers:
- address: "10.0.0.1:5432"
- address: "10.0.0.2:5432"TCP EntryPoints
entryPoints:
postgres:
address: ":5432"
mongodb:
address: ":27017"
mysql:
address: ":3306"
redis:
address: ":6379"TCP with TLS Termination
tcp:
routers:
secure-postgres:
rule: "HostSNI(`db.example.com`)"
entryPoints:
- postgres
service: postgres-service
tls:
certResolver: letsencrypt
services:
postgres-service:
loadBalancer:
servers:
- address: "10.0.0.1:5432"TLS termination at Traefik means the database sees plain TCP (no TLS). This lets Traefik inspect the SNI for routing but requires the Traefik-to-database network to be trusted.
TCP with TLS Passthrough
tcp:
routers:
passthrough-db:
rule: "HostSNI(`db.example.com`)"
entryPoints:
- postgres
service: postgres-service
tls:
passthrough: trueWith TLS passthrough, Traefik only sees the SNI during the TLS handshake. It cannot inspect or modify the traffic. Use this when the backend must handle its own TLS.
HostSNI Matching Rules
# Match any SNI
rule: "HostSNI(`*`)"
# Match specific domain
rule: "HostSNI(`db.example.com`)"
# Match wildcard
rule: "HostSNI(`*.example.com`)"
# Match multiple
rule: "HostSNI(`db1.example.com`) || HostSNI(`db2.example.com`)"For non-TLS TCP connections, HostSNI(*) is the only option since there's no SNI to match. Each non-TLS TCP entrypoint typically has a single catch-all router.
TCP Services
tcp:
services:
redis-cluster:
loadBalancer:
servers:
- address: "10.0.0.1:6379"
- address: "10.0.0.2:6379"
- address: "10.0.0.3:6379"
strategy: wrr
terminationDelay: 5s
proxyProtocol:
version: 2Weighted TCP Services
tcp:
services:
db-v1:
loadBalancer:
servers:
- address: "10.0.0.1:5432"
db-v2:
loadBalancer:
servers:
- address: "10.0.0.2:5432"
db-weighted:
weighted:
services:
- name: db-v1
weight: 9
- name: db-v2
weight: 1UDP Routing
UDP routing supports connectionless protocols like DNS, syslog, and custom UDP services.
udp:
routers:
dns-server:
entryPoints:
- dns
service: dns-service
services:
dns-service:
loadBalancer:
servers:
- address: "10.0.0.1:53"
- address: "10.0.0.2:53"UDP EntryPoints
entryPoints:
dns:
address: ":53/udp"
syslog:
address: ":514/udp"
custom-udp:
address: ":1234/udp"UDP Limitations
- UDP is connectionless — there's no handshake or session
- No TLS, no HostSNI matching
- Load balancing is best-effort (round-robin)
- No health checks for UDP services
- No middleware support
gRPC Routing
gRPC uses HTTP/2 which Traefik handles natively:
http:
routers:
grpc:
rule: "Host(`grpc.example.com`) && Headers(`Content-Type`, `application/grpc`)"
entryPoints:
- websecure
service: grpc-service
tls: {}
services:
grpc-service:
loadBalancer:
servers:
- url: "h2c://10.0.0.1:50051" # h2c = HTTP/2 cleartextgRPC Notes
- Use
h2c://for gRPC backends without TLS (behind Traefik's TLS termination) - Use
https://for gRPC backends with their own TLS - gRPC-Web is also supported without special configuration
- Keepalive settings may need tuning for long-lived gRPC streams
WebSocket Support
WebSockets work automatically through HTTP routers:
http:
routers:
ws:
rule: "Host(`ws.example.com`) && PathPrefix(`/ws`)"
service: ws-service
services:
ws-service:
loadBalancer:
servers:
- url: "http://10.0.0.1:8080"WebSocket connections are upgraded automatically. No special configuration needed for the HTTP router. The connection upgrade is handled transparently.
HTTP/2 Support
Traefik supports HTTP/2 and HTTP/3:
entryPoints:
websecure:
address: ":443"
http3: {} # Enable HTTP/3 (QUIC)- HTTP/2 is enabled by default on HTTPS entrypoints
- HTTP/3 requires explicit
http3: {}on the entrypoint - HTTP/2 cleartext (h2c) is supported for backend connections
Example: Complete TCP/UDP Setup
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
postgres:
address: ":5432"
dns:
address: ":53/udp"
tcp:
routers:
postgres:
rule: "HostSNI(`*`)"
entryPoints:
- postgres
service: postgres-cluster
tls:
passthrough: true
services:
postgres-cluster:
loadBalancer:
servers:
- address: "10.0.0.1:5432"
- address: "10.0.0.2:5432"
udp:
routers:
dns:
entryPoints:
- dns
service: dns-cluster
services:
dns-cluster:
loadBalancer:
servers:
- address: "10.0.0.1:53"Next Chapter
Now dive deep into Security — hardening Traefik in production.