소스 검색

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 달 전
부모
커밋
170346bb74
4개의 변경된 파일44개의 추가작업 그리고 2개의 파일을 삭제
  1. 19
    0
      contrib/sni-router/Caddyfile
  2. 13
    0
      contrib/sni-router/README.md
  3. 8
    2
      contrib/sni-router/haproxy.cfg
  4. 4
    0
      contrib/sni-router/mtg-config.toml

+ 19
- 0
contrib/sni-router/Caddyfile 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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"

Loading…
취소
저장