mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 11:04:02 +03:00
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.
This commit is contained in:
@@ -3,6 +3,25 @@
|
|||||||
# ACME HTTP-01 challenges arrive on :80 via HAProxy's acl passthrough.
|
# ACME HTTP-01 challenges arrive on :80 via HAProxy's acl passthrough.
|
||||||
http_port 80
|
http_port 80
|
||||||
https_port 8443
|
https_port 8443
|
||||||
|
|
||||||
|
# HAProxy forwards connections to :8443 with a PROXY protocol v2
|
||||||
|
# header (see haproxy.cfg `send-proxy-v2`). The proxy_protocol
|
||||||
|
# listener wrapper strips the header and exposes the real client IP
|
||||||
|
# to Caddy's access log. The `tls` wrapper must follow so that TLS
|
||||||
|
# is terminated on the unwrapped connection.
|
||||||
|
#
|
||||||
|
# `allow` lists the networks permitted to send PROXY headers. These
|
||||||
|
# ranges cover docker compose's default bridge networks; tighten
|
||||||
|
# them if you pin a specific subnet in docker-compose.yml.
|
||||||
|
servers :8443 {
|
||||||
|
listener_wrappers {
|
||||||
|
proxy_protocol {
|
||||||
|
timeout 5s
|
||||||
|
allow 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
|
||||||
|
}
|
||||||
|
tls
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{$DOMAIN} {
|
{$DOMAIN} {
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ docker compose up -d
|
|||||||
docker compose exec mtg mtg access /config/config.toml
|
docker compose exec mtg mtg access /config/config.toml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Real client IPs (PROXY protocol)
|
||||||
|
|
||||||
|
HAProxy forwards TCP connections to mtg and Caddy with a PROXY protocol
|
||||||
|
v2 header so both backends see the real client IP instead of HAProxy's
|
||||||
|
container address. The three pieces must stay in sync:
|
||||||
|
|
||||||
|
- `haproxy.cfg` — `send-proxy-v2` on the `mtg` and `web` backend `server` lines
|
||||||
|
- `mtg-config.toml` — `proxy-protocol-listener = true`
|
||||||
|
- `Caddyfile` — `listener_wrappers { proxy_protocol { ... } tls }` on `:8443`
|
||||||
|
|
||||||
|
If you disable one, disable all three, otherwise the backend will fail
|
||||||
|
to parse the connection.
|
||||||
|
|
||||||
## ACME (Let's Encrypt) notes
|
## ACME (Let's Encrypt) notes
|
||||||
|
|
||||||
HAProxy passes `/.well-known/acme-challenge/` requests on `:80` to
|
HAProxy passes `/.well-known/acme-challenge/` requests on `:80` to
|
||||||
|
|||||||
@@ -46,10 +46,16 @@ frontend tls
|
|||||||
default_backend web
|
default_backend web
|
||||||
|
|
||||||
backend mtg
|
backend mtg
|
||||||
server mtg mtg:3128
|
# send-proxy-v2 prepends a PROXY protocol v2 header so mtg sees the
|
||||||
|
# real client IP instead of HAProxy's. mtg must have
|
||||||
|
# `proxy-protocol-listener = true` in its config.
|
||||||
|
server mtg mtg:3128 send-proxy-v2
|
||||||
|
|
||||||
backend web
|
backend web
|
||||||
server web web:8443
|
# send-proxy-v2 prepends a PROXY protocol v2 header so Caddy logs the
|
||||||
|
# real client IP instead of HAProxy's. Caddy must enable the
|
||||||
|
# proxy_protocol listener wrapper on :8443 (see Caddyfile).
|
||||||
|
server web web:8443 send-proxy-v2
|
||||||
|
|
||||||
backend web_acme
|
backend web_acme
|
||||||
mode http
|
mode http
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
secret = "PASTE_YOUR_SECRET_HERE"
|
secret = "PASTE_YOUR_SECRET_HERE"
|
||||||
bind-to = "0.0.0.0:3128"
|
bind-to = "0.0.0.0:3128"
|
||||||
|
|
||||||
|
# HAProxy in front sends PROXY protocol v2 headers so mtg can see the
|
||||||
|
# real client IP. Keep this in sync with haproxy.cfg (`send-proxy-v2`).
|
||||||
|
proxy-protocol-listener = true
|
||||||
|
|
||||||
[defense.anti-replay]
|
[defense.anti-replay]
|
||||||
enabled = true
|
enabled = true
|
||||||
max-size = "1mib"
|
max-size = "1mib"
|
||||||
|
|||||||
Reference in New Issue
Block a user