Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

haproxy.cfg 2.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. # HAProxy SNI router — Layer 4 (TCP mode)
  2. #
  3. # Inspects the SNI in the TLS ClientHello and routes traffic:
  4. # - SNI matching the mtg secret domain -> mtg (FakeTLS / MTProto)
  5. # - Everything else -> real web backend (Caddy)
  6. #
  7. # Because routing happens before TLS termination, each backend sees the
  8. # raw ClientHello and handles TLS itself. The real web backend therefore
  9. # presents a genuine certificate to any probe or browser.
  10. global
  11. log stdout format raw local0 info
  12. maxconn 4096
  13. defaults
  14. log global
  15. mode tcp
  16. option tcplog
  17. timeout connect 5s
  18. timeout client 60s
  19. timeout server 60s
  20. # --- HTTP :80 — ACME challenges + redirect -----------------------------------
  21. frontend http
  22. # Explicit v4 + v6 binds so IPv6 clients are accepted regardless of the
  23. # host's net.ipv6.bindv6only sysctl. `v6only` on the v6 bind prevents it
  24. # from also accepting v4-mapped connections, which would otherwise
  25. # conflict with the explicit v4 bind on the same port.
  26. bind 0.0.0.0:80
  27. bind [::]:80 v6only
  28. mode http
  29. # Let Caddy answer ACME HTTP-01 challenges for Let's Encrypt.
  30. acl is_acme path_beg /.well-known/acme-challenge/
  31. use_backend web_acme if is_acme
  32. http-request redirect scheme https code 301
  33. # --- TLS :443 — SNI-based routing -------------------------------------------
  34. frontend tls
  35. bind 0.0.0.0:443
  36. bind [::]:443 v6only
  37. tcp-request inspect-delay 5s
  38. tcp-request content accept if { req_ssl_hello_type 1 }
  39. # Route Telegram clients to mtg. The domain is read from the $DOMAIN
  40. # environment variable (forwarded by docker-compose), so it stays in
  41. # sync with Caddy and there is no per-deploy edit to this file.
  42. use_backend mtg if { req_ssl_sni -i "${DOMAIN}" }
  43. default_backend web
  44. # Backends reach mtg and web on host loopback — they publish to 127.0.0.1
  45. # (see docker-compose.yml), and HAProxy runs in the host netns
  46. # (network_mode: host). PROXY v2 still carries the real client address
  47. # (v4 or v6) end-to-end, independent of the loopback transport.
  48. backend mtg
  49. # send-proxy-v2 prepends a PROXY protocol v2 header so mtg sees the
  50. # real client IP instead of HAProxy's. mtg must have
  51. # `proxy-protocol-listener = true` in its config.
  52. server mtg 127.0.0.1:3128 send-proxy-v2
  53. backend web
  54. # send-proxy-v2 prepends a PROXY protocol v2 header so Caddy logs the
  55. # real client IP instead of HAProxy's. Caddy must enable the
  56. # proxy_protocol listener wrapper on :8443 (see Caddyfile).
  57. server web 127.0.0.1:8443 send-proxy-v2
  58. backend web_acme
  59. mode http
  60. server web 127.0.0.1:8080