Skip to content

Commit e34bbe9

Browse files
Claudegaby
andcommitted
📒 docs: improve clarity for ProxyHeader and TrustProxy configuration
- Updated c.IP() documentation in docs/api/ctx.md with clear explanation that both TrustProxy and ProxyHeader must be configured - Added comprehensive examples showing proper reverse proxy setup - Enhanced ProxyHeader, TrustProxy, and TrustProxyConfig descriptions in docs/api/fiber.md with security warnings - Added new "Getting the Real Client IP Address" section to docs/guide/reverse-proxy.md with complete examples - Included table of common proxy headers and configuration testing example - All markdown linting checks pass This addresses the confusion reported in the issue where users set ProxyHeader but didn't realize TrustProxy was also required. Co-authored-by: gaby <835733+gaby@users.noreply.github.com>
1 parent 7597ae5 commit e34bbe9

3 files changed

Lines changed: 165 additions & 7 deletions

File tree

docs/api/ctx.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,14 +1145,43 @@ app.Get("/", func(c fiber.Ctx) error {
11451145
})
11461146
```
11471147

1148-
When registering the proxy request header in the Fiber app, the IP address of the header is returned [(Fiber configuration)](fiber.md#proxyheader)
1148+
:::info
1149+
By default, `c.IP()` returns the remote IP address from the TCP connection. When your Fiber app is behind a reverse proxy (like Nginx, Traefik, or a load balancer), you need to configure **both** [`TrustProxy`](fiber.md#trustproxy) and [`ProxyHeader`](fiber.md#proxyheader) to read the client IP from proxy headers like `X-Forwarded-For`.
11491150

1150-
```go
1151+
**Important:** You must enable `TrustProxy` and configure trusted proxy IPs to prevent header spoofing. Simply setting `ProxyHeader` alone will not work.
1152+
:::
1153+
1154+
#### Configuration for apps behind a reverse proxy
1155+
1156+
```go title="Example - Basic Configuration"
11511157
app := fiber.New(fiber.Config{
1158+
// Enable proxy support
1159+
TrustProxy: true,
1160+
// Specify which header contains the real client IP
11521161
ProxyHeader: fiber.HeaderXForwardedFor,
1162+
// Configure which proxy IPs to trust
1163+
TrustProxyConfig: fiber.TrustProxyConfig{
1164+
// Trust private IP ranges (for internal load balancers)
1165+
Private: true,
1166+
// Or specify exact proxy IPs/ranges
1167+
// Proxies: []string{"10.10.0.58", "192.168.0.0/24"},
1168+
},
11531169
})
11541170
```
11551171

1172+
```go title="Example - Specific Proxy IPs"
1173+
app := fiber.New(fiber.Config{
1174+
TrustProxy: true,
1175+
ProxyHeader: fiber.HeaderXForwardedFor,
1176+
TrustProxyConfig: fiber.TrustProxyConfig{
1177+
// Trust only specific proxy IP addresses
1178+
Proxies: []string{"10.10.0.58", "192.168.1.0/24"},
1179+
},
1180+
})
1181+
```
1182+
1183+
See [`TrustProxy`](fiber.md#trustproxy) and [`TrustProxyConfig`](fiber.md#trustproxyconfig) for more details on security considerations and configuration options.
1184+
11561185
### IPs
11571186

11581187
Returns an array of IP addresses specified in the [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) request header.

docs/api/fiber.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ app := fiber.New(fiber.Config{
7171
| <Reference id="msgpackencoder">MsgPackEncoder</Reference> | `utils.MsgPackMarshal` | Allowing for flexibility in using another msgpack library for encoding. | `binder.UnimplementedMsgpackMarshal` |
7272
| <Reference id="passlocalstocontext">PassLocalsToContext</Reference> | `bool` | Controls whether `StoreInContext` also propagates values into the request `context.Context` for Fiber-backed contexts. `StoreInContext` always writes to `c.Locals()`. `ValueFromContext` for Fiber-backed contexts always reads from `c.Locals()`. | `false` |
7373
| <Reference id="passlocalstoviews">PassLocalsToViews</Reference> | `bool` | PassLocalsToViews Enables passing of the locals set on a fiber.Ctx to the template engine. See our **Template Middleware** for supported engines. | `false` |
74-
| <Reference id="proxyheader">ProxyHeader</Reference> | `string` | This will enable `c.IP()` to return the value of the given header key. By default `c.IP()`will return the Remote IP from the TCP connection, this property can be useful if you are behind a load balancer e.g. _X-Forwarded-\*_. | `""` |
74+
| <Reference id="proxyheader">ProxyHeader</Reference> | `string` | Specifies the header name to read the client's real IP address from when behind a reverse proxy. Common values: `fiber.HeaderXForwardedFor`, `"X-Real-IP"`, `"CF-Connecting-IP"` (Cloudflare). <br /><br />**Important:** This setting **requires** `TrustProxy` to be enabled and `TrustProxyConfig` to be properly configured. Without `TrustProxy`, this setting has no effect and `c.IP()` will always return the remote IP from the TCP connection. <br /><br />**Security Warning:** Headers can be easily spoofed. Always configure `TrustProxyConfig` to validate the proxy IP address, otherwise malicious clients can forge headers to bypass IP-based access controls. | `""` |
7575
| <Reference id="readbuffersize">ReadBufferSize</Reference> | `int` | per-connection buffer size for requests' reading. This also limits the maximum header size. Increase this buffer if your clients send multi-KB RequestURIs and/or multi-KB headers \(for example, BIG cookies\). | `4096` |
7676
| <Reference id="readtimeout">ReadTimeout</Reference> | `time.Duration` | The amount of time allowed to read the full request, including the body. The default timeout is unlimited. | `0` |
7777
| <Reference id="reducememoryusage">ReduceMemoryUsage</Reference> | `bool` | Aggressively reduces memory usage at the cost of higher CPU usage if set to true. | `false` |
@@ -80,8 +80,8 @@ app := fiber.New(fiber.Config{
8080
| <Reference id="streamrequestbody">StreamRequestBody</Reference> | `bool` | StreamRequestBody enables request body streaming, and calls the handler sooner when given body is larger than the current limit. | `false` |
8181
| <Reference id="strictrouting">StrictRouting</Reference> | `bool` | When enabled, the router treats `/foo` and `/foo/` as different. Otherwise, the router treats `/foo` and `/foo/` as the same. | `false` |
8282
| <Reference id="structvalidator">StructValidator</Reference> | `StructValidator` | If you want to validate header/form/query... automatically when to bind, you can define struct validator. Fiber doesn't have default validator, so it'll skip validator step if you don't use any validator. | `nil` |
83-
| <Reference id="trustproxy">TrustProxy</Reference> | `bool` | When true, Fiber validates the proxy IP against `TrustProxyConfig.Proxies`. <br /><br />By default, `c.Protocol()`, `c.IP()`, and `c.Hostname()` read values from standard X-Forwarded headers. If the remote IP matches a trusted proxy, these methods behave as if `TrustProxy` were disabled. Otherwise, `c.Protocol()` reflects the connection scheme, `c.IP()` uses `RemoteIP()` from Fasthttp, and `c.Hostname()` uses `fasthttp.Request.URI().Host()` | `false` |
84-
| <Reference id="trustproxyconfig">TrustProxyConfig</Reference> | `TrustProxyConfig` | Configure trusted proxy IP's. Look at `TrustProxy` doc. <br /> <br /> `TrustProxyConfig.Proxies` can take IP or IP range addresses. | `nil` |
83+
| <Reference id="trustproxy">TrustProxy</Reference> | `bool` | Enables trust of reverse proxy headers. When enabled, Fiber will check if the request is coming from a trusted proxy (configured in `TrustProxyConfig`) before reading values from proxy headers. <br /><br />**Required for**: Using `ProxyHeader` to read client IP from headers like `X-Forwarded-For`. <br /><br />**Behavior when enabled:** If the remote IP is trusted (matches `TrustProxyConfig`), then `c.IP()` reads from `ProxyHeader`, `c.Protocol()` reads from `X-Forwarded-Proto`, and `c.Hostname()` reads from `X-Forwarded-Host`. If the remote IP is NOT trusted, these methods ignore proxy headers and use the actual connection values instead. <br /><br />**Security:** This prevents header spoofing by validating the proxy's IP address. Always configure `TrustProxyConfig` when enabling this option. | `false` |
84+
| <Reference id="trustproxyconfig">TrustProxyConfig</Reference> | `TrustProxyConfig` | Configures which proxy IP addresses or ranges to trust. Only effective when `TrustProxy` is enabled. <br /><br />**Fields:** <br />• `Proxies` - List of trusted proxy IPs or CIDR ranges (e.g., `[]string{"10.10.0.58", "192.168.0.0/24"}`) <br />• `Loopback` - Trust loopback addresses (127.0.0.0/8, ::1/128) <br />• `Private` - Trust all private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7) <br />• `LinkLocal` - Trust link-local addresses (169.254.0.0/16, fe80::/10) <br />• `UnixSocket` - Trust Unix domain socket connections <br /><br />**Example:** For an app behind Nginx at 10.10.0.58, use `TrustProxyConfig{Proxies: []string{"10.10.0.58"}}` or `TrustProxyConfig{Private: true}` if using private network IPs. | `nil` |
8585
| <Reference id="unescapepath">UnescapePath</Reference> | `bool` | Converts all encoded characters in the route back before setting the path for the context, so that the routing can also work with URL encoded special characters | `false` |
8686
| <Reference id="views">Views</Reference> | `Views` | Views is the interface that wraps the Render function. See our **Template Middleware** for supported engines. | `nil` |
8787
| <Reference id="viewslayout">ViewsLayout</Reference> | `string` | Views Layout is the global layout for all template render until override on Render function. See our **Template Middleware** for supported engines. | `""` |

0 commit comments

Comments
 (0)