Pārlūkot izejas kodu

Pass real client IPs through with PROXY protocol v2

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 https://github.com/9seconds/mtg/pull/462 review.
pull/462/head
dolonet 3 nedēļas atpakaļ
vecāks
revīzija
170346bb74

+ 19
- 0
contrib/sni-router/Caddyfile Parādīt failu

@@ -3,6 +3,25 @@
3 3
 	# ACME HTTP-01 challenges arrive on :80 via HAProxy's acl passthrough.
4 4
 	http_port 80
5 5
 	https_port 8443
6
+
7
+	# HAProxy forwards connections to :8443 with a PROXY protocol v2
8
+	# header (see haproxy.cfg `send-proxy-v2`).  The proxy_protocol
9
+	# listener wrapper strips the header and exposes the real client IP
10
+	# to Caddy's access log.  The `tls` wrapper must follow so that TLS
11
+	# is terminated on the unwrapped connection.
12
+	#
13
+	# `allow` lists the networks permitted to send PROXY headers.  These
14
+	# ranges cover docker compose's default bridge networks; tighten
15
+	# them if you pin a specific subnet in docker-compose.yml.
16
+	servers :8443 {
17
+		listener_wrappers {
18
+			proxy_protocol {
19
+				timeout 5s
20
+				allow 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
21
+			}
22
+			tls
23
+		}
24
+	}
6 25
 }
7 26
 
8 27
 {$DOMAIN} {

+ 13
- 0
contrib/sni-router/README.md Parādīt failu

@@ -43,6 +43,19 @@ docker compose up -d
43 43
 docker compose exec mtg mtg access /config/config.toml
44 44
 ```
45 45
 
46
+## Real client IPs (PROXY protocol)
47
+
48
+HAProxy forwards TCP connections to mtg and Caddy with a PROXY protocol
49
+v2 header so both backends see the real client IP instead of HAProxy's
50
+container address.  The three pieces must stay in sync:
51
+
52
+- `haproxy.cfg` — `send-proxy-v2` on the `mtg` and `web` backend `server` lines
53
+- `mtg-config.toml` — `proxy-protocol-listener = true`
54
+- `Caddyfile` — `listener_wrappers { proxy_protocol { ... } tls }` on `:8443`
55
+
56
+If you disable one, disable all three, otherwise the backend will fail
57
+to parse the connection.
58
+
46 59
 ## ACME (Let's Encrypt) notes
47 60
 
48 61
 HAProxy passes `/.well-known/acme-challenge/` requests on `:80` to

+ 8
- 2
contrib/sni-router/haproxy.cfg Parādīt failu

@@ -46,10 +46,16 @@ frontend tls
46 46
     default_backend web
47 47
 
48 48
 backend mtg
49
-    server mtg mtg:3128
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 mtg:3128 send-proxy-v2
50 53
 
51 54
 backend web
52
-    server web web:8443
55
+    # send-proxy-v2 prepends a PROXY protocol v2 header so Caddy logs the
56
+    # real client IP instead of HAProxy's.  Caddy must enable the
57
+    # proxy_protocol listener wrapper on :8443 (see Caddyfile).
58
+    server web web:8443 send-proxy-v2
53 59
 
54 60
 backend web_acme
55 61
     mode http

+ 4
- 0
contrib/sni-router/mtg-config.toml Parādīt failu

@@ -7,6 +7,10 @@
7 7
 secret = "PASTE_YOUR_SECRET_HERE"
8 8
 bind-to = "0.0.0.0:3128"
9 9
 
10
+# HAProxy in front sends PROXY protocol v2 headers so mtg can see the
11
+# real client IP.  Keep this in sync with haproxy.cfg (`send-proxy-v2`).
12
+proxy-protocol-listener = true
13
+
10 14
 [defense.anti-replay]
11 15
 enabled = true
12 16
 max-size = "1mib"

Notiek ielāde…
Atcelt
Saglabāt