nginx.conf takes the client address from X-Forwarded-For when the request comes from any private-range address (set_real_ip_from 10/8, 172.16/12, 192.168/16). A client that reaches nginx from such an address, or through Docker's userland proxy (which makes every client appear as the gateway, for example 172.17.0.1), can write a new X-Forwarded-For on each request and so get a fresh rate-limit allowance each time (#20 keys the limit on that address). Found during the review of #63; it comes from #19 and #52.
Definition of done
The addresses nginx trusts for X-Forwarded-For come from an environment variable rendered into the nginx template (the template step of #26), with a default that trusts no forwarded header, so an operator names the proxy in front of the container.
The backend keeps trusting only nginx on loopback for the address nginx passes it.
Verified by running the image: with the default, a forged X-Forwarded-For does not change the address the rate limit sees; with the proxy's address set, the address the proxy appends is used.
The README (and the upaas section of #59, if it has landed) names the variable.
Root make check and script/cibuild pass; TODO.md updated in the same commit; commit title ends (closes #N).
Model: opus-5-5
`nginx.conf` takes the client address from `X-Forwarded-For` when the request comes from any private-range address (`set_real_ip_from` 10/8, 172.16/12, 192.168/16). A client that reaches nginx from such an address, or through Docker's userland proxy (which makes every client appear as the gateway, for example `172.17.0.1`), can write a new `X-Forwarded-For` on each request and so get a fresh rate-limit allowance each time (https://git.eeqj.de/sneak/netwatch/issues/20 keys the limit on that address). Found during the review of https://git.eeqj.de/sneak/netwatch/pulls/63; it comes from https://git.eeqj.de/sneak/netwatch/issues/19 and https://git.eeqj.de/sneak/netwatch/issues/52.
## Definition of done
- The addresses nginx trusts for `X-Forwarded-For` come from an environment variable rendered into the nginx template (the template step of https://git.eeqj.de/sneak/netwatch/issues/26), with a default that trusts no forwarded header, so an operator names the proxy in front of the container.
- The backend keeps trusting only nginx on loopback for the address nginx passes it.
- Verified by running the image: with the default, a forged `X-Forwarded-For` does not change the address the rate limit sees; with the proxy's address set, the address the proxy appends is used.
- The README (and the upaas section of https://git.eeqj.de/sneak/netwatch/issues/59, if it has landed) names the variable.
- Root `make check` and `script/cibuild` pass; `TODO.md` updated in the same commit; commit title ends ` (closes #N)`.
Model: opus-5-5
clawbot
self-assigned this 2026-09-29 03:39:25 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
nginx.conftakes the client address fromX-Forwarded-Forwhen the request comes from any private-range address (set_real_ip_from10/8, 172.16/12, 192.168/16). A client that reaches nginx from such an address, or through Docker's userland proxy (which makes every client appear as the gateway, for example172.17.0.1), can write a newX-Forwarded-Foron each request and so get a fresh rate-limit allowance each time (#20 keys the limit on that address). Found during the review of #63; it comes from #19 and #52.Definition of done
X-Forwarded-Forcome from an environment variable rendered into the nginx template (the template step of #26), with a default that trusts no forwarded header, so an operator names the proxy in front of the container.X-Forwarded-Fordoes not change the address the rate limit sees; with the proxy's address set, the address the proxy appends is used.make checkandscript/cibuildpass;TODO.mdupdated in the same commit; commit title ends(closes #N).Model: opus-5-5