Ten wrong passwords from one address hold it off sign-in for a quarter hour (#409)
POST /api/login answered every wrong password 401 for as long as someone
kept trying. Now ipx counts them by the client's address: the tenth in a
window holds that address off until the window, which starts at its first
wrong password, ends, answered 429 with how long is left. Counted by
address and not name, since by name anyone could lock anyone out; a right
password does not reset the count, or a guesser with an account of their
own could clear it between guesses.
Behind Caddy every peer is Caddy, so the address is the last one in
X-Forwarded-For, taken only from trusted_proxies. Caddy now sets that to
{client_ip}: Cf-Connecting-IP for the tunnel's requests, believed only
from TUNNEL_PEER (servers trusted_proxies), and the peer for everyone
else, replacing whatever the client sent. Checked with Caddy against an
echo upstream: a forged XFF and Cf-Connecting-IP from elsewhere reach ipx
as the peer, the tunnel's Cf-Connecting-IP as itself.
The sign-in load test sends each attempt from its own address, so it
still measures a flood from many, whose passwords are all checked.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RqkrVDqdiQEMWAkNGQ2tYA
This commit is contained in:
@@ -13,6 +13,13 @@
|
||||
{
|
||||
admin off
|
||||
auto_https off
|
||||
# Who a request is from, {client_ip}: Cloudflare's Cf-Connecting-IP for the tunnel's requests,
|
||||
# taken only from cloudflared, and the peer for everyone else's. ipx counts wrong passwords by it
|
||||
# (#409), and without this every request through the tunnel is cloudflared's one address.
|
||||
servers {
|
||||
trusted_proxies static {$TUNNEL_PEER:255.255.255.255}
|
||||
client_ip_headers Cf-Connecting-IP
|
||||
}
|
||||
# Requests, their times and upstream errors as Prometheus metrics, served below (#371).
|
||||
metrics
|
||||
# Everything else Caddy logs, its errors among them, which carry the request too: the same
|
||||
@@ -95,6 +102,9 @@ http://{$WEB_BIND::8080} {
|
||||
# Live updates are a stream: flushed as they come, never buffered.
|
||||
reverse_proxy {$IPX_UPSTREAM:ipx:8099} {
|
||||
flush_interval -1
|
||||
# The client alone, not the chain Caddy would otherwise pass on, whose last address is
|
||||
# cloudflared's for the tunnel: ipx takes the last as who is asking (#409).
|
||||
header_up X-Forwarded-For {client_ip}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user