DanielRamosAcosta opened a new issue, #6052:
URL: https://github.com/apache/couchdb/issues/6052

   ### Provide a brief overview of what the new feature is all about
   
   The authentication lockout added in 3.4 (`[chttpd_auth_lockout]`) keys its 
rate-limit on a `{peer IP, username, salt}` tuple. The peer IP comes from 
`mochiweb_request:get(peer, …)`. When CouchDB runs behind a reverse proxy or 
CDN, that function returns the **last** entry of `X-Forwarded-For` — the 
nearest proxy, not the real client — and there is no way to configure this. 
This request asks for a configurable way to determine the client IP (which 
header, and/or how many trusted hops) so the lockout counts per real client IP.
   
   ### Tell us how the new feature should work. Be specific
   
   Add configuration (e.g. under `[chttpd]`) to control how the client IP is 
derived from forwarded headers, mirroring the existing `x_forwarded_host` / 
`x_forwarded_proto` / `x_forwarded_ssl` options — which already handle 
host/scheme behind a proxy but **not** the client IP. For example, any of:
   
   - a setting to choose the source header (e.g. `X-Forwarded-For`, 
`X-Real-IP`, or a CDN-specific header);
   - a "trusted hops" count to skip N rightmost entries of `X-Forwarded-For` 
(like nginx `real_ip_recursive` or Traefik `ipStrategy.depth`);
   - a list of trusted proxy CIDRs whose addresses are stripped, taking the 
rightmost *untrusted* address (like nginx `set_real_ip_from`).
   
   The resolved IP would be used both for the lockout key and for request 
logging. Default behaviour unchanged for backwards compatibility.
   
   Illustrative example (documentation IPs): with `X-Forwarded-For: 
203.0.113.10, 198.51.100.7` (real client, then one proxy), the lockout today 
uses `198.51.100.7` (the proxy). With `trusted_hops = 1` it should use 
`203.0.113.10` (the client).
   
   ### Not required. Suggest how to implement the addition or change
   
   Root cause is in `mochiweb_request:get(peer, …)` (mochiweb v3.4.0): for 
sockets in private ranges it returns 
`string:strip(lists:last(string:tokens(XFF, ",")))` — the **last** XFF entry, 
with no knob to configure it.
   
   Rather than changing mochiweb (legacy, shared by many consumers), CouchDB 
could resolve the client IP in its own layer: read the configured forwarded 
header(s), apply the trusted-hops / trusted-proxy logic, and pass the result to 
the lockout. The lockout's `peer/1` in `couch_auth_lockout.erl` currently 
delegates straight to `mochiweb_request:get(peer, …)`; it could instead use the 
CouchDB-resolved IP, paralleling how CouchDB already consumes `x_forwarded_*` 
for host/proto/ssl.
   
   ### Additional Context
   
   Behind a CDN/reverse proxy the lockout is effectively neutralised: the 
rightmost `X-Forwarded-For` entry is a shared proxy egress address, so (a) 
brute-force attempts spread across many proxy IPs rarely reach the per-`(IP, 
user)` threshold, and (b) legitimate clients sharing a proxy egress IP can 
trigger cross-lockouts / a self-DoS of a known username. Reverse proxies 
already expose this control (nginx, Traefik, HAProxy), but CouchDB has no 
equivalent — even though running behind a proxy is a documented, common 
deployment.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to