Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions http/proxy.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
# Proxy IP parser

This middleware parses the following headers: `X-Forwarded-*`, `Forwarded`, `True-Client-IP`, and `X-Real-IP`.
This middleware resolves the real client IP from proxy headers when a request arrives
through a trusted subnet. By default it consults, in order: `Forwarded`, `X-Forwarded-For`,
`X-Real-IP`, `True-Client-IP`, and `CF-Connecting-IP`. The set and order of headers can be
customized with `trusted_headers`.
Comment on lines +3 to +6

## Description
When the proxy is trusted, the leftmost IP address is used as `RemoteAddr`. Otherwise, `RemoteAddr` is not changed.

When the immediate peer is within one of the `trusted_subnets`, the middleware resolves the
client IP from the configured headers — the first non-empty match wins — and sets it as
`RemoteAddr`. Otherwise `RemoteAddr` is left unchanged.

The middleware is active only when `trusted_subnets` is configured; without it, forwarding
headers are never trusted.

## Usage

Expand Down Expand Up @@ -33,3 +42,30 @@ http:
```

{% endcode %}

## Trusted headers

`trusted_headers` is an ordered allowlist of the headers used to resolve the client IP. The
middleware checks them in order and uses the first non-empty value; headers that are not
listed are ignored, and custom headers are supported. When `trusted_headers` is omitted, the
default order is used: `Forwarded`, `X-Forwarded-For`, `X-Real-IP`, `True-Client-IP`,
`CF-Connecting-IP`.

For example, to trust only `X-Real-IP` and Cloudflare's `CF-Connecting-IP` while ignoring
`X-Forwarded-*`:
Comment on lines +54 to +55

{% code title=".rr.yaml" %}

```yaml
http:
trusted_subnets: [ "10.0.0.0/8", "127.0.0.0/8" ]
trusted_headers: [ "X-Real-IP", "CF-Connecting-IP" ]
```

{% endcode %}

{% hint style="info" %}
`X-Forwarded-For` uses the left-most address from its comma-separated list, and `Forwarded`
is parsed per [RFC 7239](https://datatracker.ietf.org/doc/html/rfc7239) (`for=`). All other
headers, including custom ones, are taken verbatim.
{% endhint %}