Bobbin proxies sh.tangled.repo.* reads to the knot. In that proxy path it forwards only:
const FORWARDED_REQUEST_HEADERS: &[&HeaderName] =
&[&RANGE, &IF_RANGE, &IF_NONE_MATCH, &IF_MODIFIED_SINCE];
Knot2’s pre-auth limiter resolves the client identity from its configured xrpc.trusted_proxy_header, but falls back to socket.ip() in its absence:
pub(crate) fn effective_peer<H: HttpTransport, C: Clock>(
state: &XrpcState<H, C>,
socket: SocketPeer,
headers: &HeaderMap,
) -> Option<IpAddr> {
state
.trusted_proxy_header
.as_ref()
.and_then(|header| knot_types::forwarded_peer(headers, header))
.or(socket.ip())
}
Essentially, from the knot's point of view, Bobbin is a singular IP flooding it with requests. It's just getting hammered from whatever IP Bobbin is running on.
Knot2, conveniently, adds a per-client rate limiter. Per the example config, it is set up to respect X-Forward-For, but it's not able to respect something it's not getting.
Solution should just be to actually forward X-Forward-For, which is already something knot2 is configured to respect.
Associated pull request: https://tangled.org/tangled.org/core/pulls/2162/round/0