| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- # HAProxy SNI router — Layer 4 (TCP mode)
- #
- # Inspects the SNI in the TLS ClientHello and routes traffic:
- # - SNI matching the mtg secret domain -> mtg (FakeTLS / MTProto)
- # - Everything else -> real web backend (Caddy)
- #
- # Because routing happens before TLS termination, each backend sees the
- # raw ClientHello and handles TLS itself. The real web backend therefore
- # presents a genuine certificate to any probe or browser.
-
- global
- log stdout format raw local0 info
- maxconn 4096
-
- defaults
- log global
- mode tcp
- option tcplog
- timeout connect 5s
- timeout client 60s
- timeout server 60s
-
- # --- HTTP :80 — ACME challenges + redirect -----------------------------------
-
- frontend http
- # Explicit v4 + v6 binds so IPv6 clients are accepted regardless of
- # the host's net.ipv6.bindv6only sysctl.
- bind :80,[::]:80
- mode http
-
- # Let Caddy answer ACME HTTP-01 challenges for Let's Encrypt.
- acl is_acme path_beg /.well-known/acme-challenge/
- use_backend web_acme if is_acme
-
- http-request redirect scheme https code 301
-
- # --- TLS :443 — SNI-based routing -------------------------------------------
-
- frontend tls
- bind :443,[::]:443
- tcp-request inspect-delay 5s
- tcp-request content accept if { req_ssl_hello_type 1 }
-
- # Route Telegram clients to mtg. The domain is read from the $DOMAIN
- # environment variable (forwarded by docker-compose), so it stays in
- # sync with Caddy and there is no per-deploy edit to this file.
- use_backend mtg if { req_ssl_sni -i "${DOMAIN}" }
-
- default_backend web
-
- # Backends reach mtg and web on host loopback — they publish to 127.0.0.1
- # (see docker-compose.yml), and HAProxy runs in the host netns
- # (network_mode: host). PROXY v2 still carries the real client address
- # (v4 or v6) end-to-end, independent of the loopback transport.
-
- backend mtg
- # send-proxy-v2 prepends a PROXY protocol v2 header so mtg sees the
- # real client IP instead of HAProxy's. mtg must have
- # `proxy-protocol-listener = true` in its config.
- server mtg 127.0.0.1:3128 send-proxy-v2
-
- backend web
- # send-proxy-v2 prepends a PROXY protocol v2 header so Caddy logs the
- # real client IP instead of HAProxy's. Caddy must enable the
- # proxy_protocol listener wrapper on :8443 (see Caddyfile).
- server web 127.0.0.1:8443 send-proxy-v2
-
- backend web_acme
- mode http
- server web 127.0.0.1:8080
|