|
|
@@ -56,6 +56,50 @@ container address. The three pieces must stay in sync:
|
|
56
|
56
|
If you disable one, disable all three, otherwise the backend will fail
|
|
57
|
57
|
to parse the connection.
|
|
58
|
58
|
|
|
|
59
|
+## Fronting loop (why `[domain-fronting]` is set explicitly)
|
|
|
60
|
+
|
|
|
61
|
+When mtg sees TLS traffic that isn't valid Telegram (a probe or a
|
|
|
62
|
+browser hitting your domain on `:443`), it forwards that connection to
|
|
|
63
|
+a real web server — "domain fronting". By default mtg uses the
|
|
|
64
|
+secret's hostname as the fronting target and resolves it via DNS.
|
|
|
65
|
+
|
|
|
66
|
+In this setup that hostname resolves back to **this** server, so mtg's
|
|
|
67
|
+fronting dial would hit HAProxy on `:443`, HAProxy would see the SNI
|
|
|
68
|
+matching the secret and route the connection back to mtg → loop.
|
|
|
69
|
+
|
|
|
70
|
+The trigger is DNS, not name equality: the loop reproduces whenever
|
|
|
71
|
+the secret's hostname resolves to this host, regardless of how it
|
|
|
72
|
+relates to the domain Caddy serves (same name, subdomain, parent, or
|
|
|
73
|
+unrelated). In an SNI-router deployment the secret's hostname has to
|
|
|
74
|
+point here for clients to reach mtg in the first place, so the loop
|
|
|
75
|
+is the default state unless mtg is steered away from HAProxy.
|
|
|
76
|
+
|
|
|
77
|
+To break the loop, `mtg-config.toml` pins the fronting target to
|
|
|
78
|
+Caddy's container address directly:
|
|
|
79
|
+
|
|
|
80
|
+```toml
|
|
|
81
|
+[domain-fronting]
|
|
|
82
|
+ip = "172.28.0.10"
|
|
|
83
|
+port = 8443
|
|
|
84
|
+proxy-protocol = true
|
|
|
85
|
+```
|
|
|
86
|
+
|
|
|
87
|
+The IP matches `services.web.networks.sni.ipv4_address` in
|
|
|
88
|
+`docker-compose.yml` (mtg's `domain-fronting.ip` only accepts a literal
|
|
|
89
|
+IP, not a hostname, hence the static `sni` network). `proxy-protocol =
|
|
|
90
|
+true` matches Caddy's `:8443` listener wrapper so the real client IP
|
|
|
91
|
+still propagates to Caddy's logs.
|
|
|
92
|
+
|
|
|
93
|
+If you change Caddy's pinned IP, update both files together. If
|
|
|
94
|
+`172.28.0.0/24` collides with another network on this host, change the
|
|
|
95
|
+subnet in `docker-compose.yml` and the IP in `mtg-config.toml` to match.
|
|
|
96
|
+
|
|
|
97
|
+> Caveat for IPv6 clients: when an IPv6 probe is fronted, mtg's
|
|
|
98
|
+> outbound PROXY v2 header has an IPv6 source but an IPv4 destination
|
|
|
99
|
+> (Caddy's pinned address). Caddy may refuse the mixed-family header
|
|
|
100
|
+> and log the docker-network address instead of the real client IP for
|
|
|
101
|
+> that connection. Telegram traffic is unaffected.
|
|
|
102
|
+
|
|
59
|
103
|
## ACME (Let's Encrypt) notes
|
|
60
|
104
|
|
|
61
|
105
|
HAProxy passes `/.well-known/acme-challenge/` requests on `:80` to
|