Add docker-compose example with HAProxy SNI router#462
Add docker-compose example with HAProxy SNI router#4629seconds merged 3 commits into9seconds:masterfrom
Conversation
Turnkey deployment: HAProxy on :443 peeks at the TLS SNI and routes Telegram clients to mtg while forwarding everything else (including DPI probes) to a real Caddy web server with automatic HTTPS. This is the setup recommended in BEST_PRACTICES.md, packaged so that operators can clone and run it with minimal configuration. Refs: 9seconds#458
Add an ACL that routes /.well-known/acme-challenge/ requests on :80 to Caddy instead of redirecting to HTTPS, so Let's Encrypt certificate issuance works out of the box. Also simplify Caddyfile to use Caddy's http_port/https_port directives.
|
I believe that in this scheme, you should use the PROXY protocol to pass the real client IP to MTG and the web server. MTG supports the PROXY protocol for both inbound and outbound connections, so please consider the configuration changes required to use the PROXY protocol. |
|
Nice one! But agree with @ivulit about PROXY protocol |
Without this, mtg and Caddy see HAProxy's container IP for every connection, which breaks meaningful logging, abuse handling, and any IP-based blocklist logic. HAProxy sends a PROXY protocol v2 header on its TCP backends; mtg enables proxy-protocol-listener, and Caddy wraps :8443 with a proxy_protocol listener before tls. The :80 path (ACME HTTP-01 passthrough) is unchanged — client IP there is not useful and HAProxy's http mode already adds X-Forwarded-For if anyone wants it. Requested in 9seconds#462 review.
|
Pushed 170346b wiring up PROXY protocol v2 end-to-end:
Verified on a test VPS: HAProxy emits a well-formed v2 header and Caddy's wrapper unwraps it — |
|
Thanks! |
Upstream commits included: - 0c1d001 Add docker-compose example with HAProxy SNI router - d0412b2 Fix ACME HTTP-01 passthrough in HAProxy config - 602f85d Document firehol_level1 RFC1918 gotcha in blocklist defaults - 68a4685 Fix description of blocklist rejection behavior - 170346b Pass real client IPs through with PROXY protocol v2 - 5953f93 Merge PR 9seconds#462 from dolonet/contrib/docker-sni-router - 9bf7222 Merge PR 9seconds#467 from dolonet/docs/blocklist-lan-gotcha Conflict resolution: README.md kept as fork version (mtg-multi has its own README describing multi-secret and per-user stats features). example.config.toml auto-merged cleanly.
|
This setup does not work for me when fronting domain is same as mtp server domain unless I pin container IPs in docker-compose and add the following section to mtg-config.toml: [domain-fronting]
ip = "CADDY_IP"
port = 8443
proxy-protocol = trueWithout this modification mtg tries to access the server with sni which haproxy routes to mtg and then the cycle repeats and it gets stuck in a loop. |
|
Also, after reading some issues and another PRs in this repo I started to suspect that @dolonet is an LLM or is using an LLM. |
I am a human :). Yes, I use AI tools, but do it cautiously. Especially in public repos. AI now is not able to produce high quality output architecturally on its own, even today's Opus 4.7 |
Summary
A turnkey
docker composesetup incontrib/sni-router/that deploysmtg behind an HAProxy SNI router alongside a real Caddy web server with
automatic HTTPS.
Motivation
The setup recommended in
BEST_PRACTICES.md— own domain, real webserver, SNI-based routing — requires piecing together several services.
This bundle packages it so operators can clone and run with minimal
configuration.
How it works:
:443peeks at the TLS ClientHello SNI.:80redirects to HTTPS.Active probes see a genuine website with a valid Let's Encrypt
certificate. Passive DPI sees consistent SNI/IP because the domain's DNS
points to this server.
Files
docker-compose.ymlhaproxy.cfgmtg-config.tomlCaddyfilewww/index.htmlREADME.mdTest plan
docker compose configvalidates the compose filecurl https://DOMAIN/returns the Caddy-served pageopenssl s_client -connect IP:443 -servername random.examplegets Caddy's certRefs: #458