Count an IPv4-mapped login client by its IPv4 address (closes #66)
check / check (push) Successful in 2m33s

A proxy on a dual-stack listener forwards an IPv4 client as ::ffff:a.b.c.d,
whose /64 is the same for every IPv4 client, so one client's failed logins
refused everyone's. The rate limit key now unmaps the address first.

README.md now says that with the default trusted_proxies a client with a
private address can choose its counted address through X-Forwarded-For, and
that setting trusted_proxies to the proxy's own address closes this.

Model: opus-5-5
This commit is contained in:
2026-09-28 22:49:07 +00:00
parent 39051ee4a3
commit 194c0ded63
3 changed files with 26 additions and 10 deletions
+7 -2
View File
@@ -105,7 +105,11 @@ address, counting an IPv6 client by its /64; an attempt over the limit is
refused with 429 and a `Retry-After` header. Behind a reverse proxy the client
address comes from `X-Forwarded-For` only when the proxy's address is in
`trusted_proxies`; otherwise all users behind the proxy are counted as one
client.
client. With the default `trusted_proxies` (the RFC 1918 ranges), a client
with a private address can choose the address it is counted by through its own
`X-Forwarded-For`, whether it connects directly or through the proxy, because
its own address is trusted too. Setting `trusted_proxies` to the proxy's own
address closes this.
### Source Hosts
@@ -212,7 +216,8 @@ Key settings in more detail:
inside one of these ranges; the logged and login-recorded client
address is then the rightmost forwarded entry that is not itself a
trusted proxy. Otherwise the direct peer address is used and the header
is ignored, so a client connecting directly cannot spoof its address.
is ignored, so a client connecting directly from an address outside
these ranges cannot spoof its address.
An omitted key defaults to the RFC 1918 private ranges (`10.0.0.0/8`,
`172.16.0.0/12`, `192.168.0.0/16`), since pixa is deployed behind a
proxy on a private network; an explicitly empty list (`[]`) trusts no