|
| 1 | +--- |
| 2 | +id: x-forwarded-for-settings |
| 3 | +title: X-Forwarded-For Settings |
| 4 | +description: This page documents X-Forwarded-HTTP header settings. |
| 5 | +keywords: |
| 6 | + - reference |
| 7 | + - X-Forwarded-For settings |
| 8 | + - x-forwarded-for-http-header |
| 9 | + - x forwarded for http header |
| 10 | + - the number of trusted hops |
| 11 | + - xff_num_trusted_hops |
| 12 | + - xff num trusted hops |
| 13 | +pagination_prev: null |
| 14 | +pagination_next: null |
| 15 | +toc_max_heading_level: 2 |
| 16 | +--- |
| 17 | + |
| 18 | +import Tabs from '@theme/Tabs'; |
| 19 | +import TabItem from '@theme/TabItem'; |
| 20 | + |
| 21 | +# X-Forwarded-For Settings |
| 22 | + |
| 23 | +The `X-Forwarded-For` (XFF) HTTP header lists the IP addresses a request has passed through on its way from the end user (client) to a backend service. |
| 24 | + |
| 25 | +(This is most relevant for deployments where there is another L7 proxy or load balancer in front of Pomerium, or in between Pomerium and upstream services.) |
| 26 | + |
| 27 | +The following settings affect the way Pomerium sets or consumes the XFF header. |
| 28 | + |
| 29 | +## Skip XFF Append |
| 30 | + |
| 31 | +By default, when Pomerium receives a request, it appends the IP address of the direct downstream client to the XFF header before proxying the request to the upstream service. |
| 32 | + |
| 33 | +However, if you set the **Skip XFF Append** (`skip_xff_append`) option to `true`, Pomerium will not modify an incoming XFF header. Instead, Pomerium will pass this incoming header to the upstream service unchanged. |
| 34 | + |
| 35 | +### How to configure |
| 36 | + |
| 37 | +<Tabs> |
| 38 | +<TabItem value="Core" label="Core"> |
| 39 | + |
| 40 | +| **Config file keys** | **Environment variables** | **Type** | **Default** | |
| 41 | +| :------------------- | :------------------------ | :-------- | :---------- | |
| 42 | +| `skip_xff_append` | `SKIP_XFF_APPEND` | `boolean` | `false` | |
| 43 | + |
| 44 | +### Examples |
| 45 | + |
| 46 | +```yaml |
| 47 | +skip_xff_append: true |
| 48 | +``` |
| 49 | +
|
| 50 | +```bash |
| 51 | +SKIP_XFF_APPEND=true |
| 52 | +``` |
| 53 | + |
| 54 | +</TabItem> |
| 55 | +<TabItem value="Enterprise" label="Enterprise"> |
| 56 | + |
| 57 | +Configure **X-Forward-For HTTP Header** with the toggle button in the Console. The button has three states: |
| 58 | + |
| 59 | +- **Unset** ("-") uses the value in your configuration file |
| 60 | +- **Checkmark** sets `skip_xff_append` to `true` |
| 61 | +- **Empty** sets `skip_xff_append` to `false` |
| 62 | + |
| 63 | + |
| 64 | + |
| 65 | +</TabItem> |
| 66 | +<TabItem value="Kubernetes" label="Kubernetes"> |
| 67 | + |
| 68 | +Kubernetes does not support `skip_xff_append` |
| 69 | + |
| 70 | +</TabItem> |
| 71 | +</Tabs> |
| 72 | + |
| 73 | +### Skip XFF Append examples |
| 74 | + |
| 75 | +Assume you have a load balancer in front of Pomerium, and it connects to Pomerium from IP address `10.1.2.3`. Say that the load balancer is configured to populate the `X-Forwarded-For` header, so that if a client connects to the load balancer from IP address `192.0.5.1`, then the load balancer will set `X-Forwarded-For: 192.0.5.1` on the request to Pomerium. |
| 76 | + |
| 77 | +With `skip_xff_append` set to `false` (the default behavior), Pomerium will then append the IP address of the load balancer on the request made to the upstream service: |
| 78 | + |
| 79 | +```plain title="Request Details" |
| 80 | +X-Forwarded-For: 192.0.5.1,10.1.2.3 |
| 81 | +``` |
| 82 | + |
| 83 | +With `skip_xff_append` set to `true`, Pomerium will not append the IP address of the load balancer on the request made to the upstream service: |
| 84 | + |
| 85 | +```plain title="Request Details" |
| 86 | +X-Forwarded-For: 192.0.5.1 |
| 87 | +``` |
| 88 | + |
| 89 | +## XFF Number of Trusted Hops |
| 90 | + |
| 91 | +The **XFF Number of Trusted Hops** (`xff_num_trusted_hops`) setting instructs Pomerium whether to trust an incoming request's XFF header. |
| 92 | + |
| 93 | +When unset or set to `0`, Pomerium will not trust the incoming XFF header. Pomerium will consider the client IP address to be the IP address of the direct downstream client. |
| 94 | + |
| 95 | +This affects the client IP address logged in the access logs (if configured; see [Access log fields](/docs/reference/access-log-fields#access-log-fields-and-defaults)). The client IP address is also sent to the upstream service in the [`x-envoy-external-address` header](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-envoy-external-address). |
| 96 | + |
| 97 | +:::info X-Forwarded-Proto header |
| 98 | + |
| 99 | +This setting also affects whether Pomerium trusts the [`X-Forwarded-Proto` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto). This header indicates the originating protocol (either HTTP or HTTPS) of the downstream client request. Pomerium will only trust the downstream `X-Forwarded-Proto` header if you set `xff_num_trusted_hops` to a _non-zero_ value. |
| 100 | + |
| 101 | +When set to `0`, Pomerium will set the `X-Forwarded-Proto` header to either `http` or `https` depending on whether the downstream connection is secured over TLS. |
| 102 | + |
| 103 | +::: |
| 104 | + |
| 105 | +### How to configure |
| 106 | + |
| 107 | +<Tabs> |
| 108 | +<TabItem value="Core" label="Core"> |
| 109 | + |
| 110 | +| **Config file keys** | **Environment variables** | **Type** | **Usage** | |
| 111 | +| :--------------------- | :------------------------ | :------- | :----------- | |
| 112 | +| `xff_num_trusted_hops` | `XFF_NUM_TRUSTED_HOPS` | `uint32` | **optional** | |
| 113 | + |
| 114 | +### Examples |
| 115 | + |
| 116 | +```yaml |
| 117 | +xff_num_trusted_hops: 2 |
| 118 | +``` |
| 119 | +
|
| 120 | +```bash |
| 121 | +XFF_NUM_TRUSTED_HOPS=2 |
| 122 | +``` |
| 123 | + |
| 124 | +</TabItem> |
| 125 | +<TabItem value="Enterprise" label="Enterprise"> |
| 126 | + |
| 127 | +`xff_num_trusted_hops` is a bootstrap configuration setting and is not configurable in the Console. |
| 128 | + |
| 129 | +</TabItem> |
| 130 | +<TabItem value="Kubernetes" label="Kubernetes"> |
| 131 | + |
| 132 | +Kubernetes does not support `xff_num_trusted_hops` |
| 133 | + |
| 134 | +</TabItem> |
| 135 | +</Tabs> |
| 136 | + |
| 137 | +### XFF Number of Trusted Hops examples |
| 138 | + |
| 139 | +As in the previous example, assume you have a load balancer in front of Pomerium, which connects to Pomerium from IP address `10.1.2.3`, and is configured to populate the `X-Forwarded-For` header. |
| 140 | + |
| 141 | +With `xff_num_trusted_hops` set to `0`, Pomerium's access log will show the load balancer IP address (`10.1.2.3`) as the client IP address for all incoming requests. |
| 142 | + |
| 143 | +```yaml {title="config.yaml"} |
| 144 | +xff_num_trusted_hops: 0 |
| 145 | +access_log_fields: [forwarded-for, ip, method, path] |
| 146 | +``` |
| 147 | +
|
| 148 | +Example access log entry: |
| 149 | +
|
| 150 | +```json |
| 151 | +{ |
| 152 | + "level": "info", |
| 153 | + "service": "envoy", |
| 154 | + "forwarded-for": "192.0.5.1,10.1.2.3", |
| 155 | + "ip": "10.1.2.3", |
| 156 | + "method": "GET", |
| 157 | + "path": "/", |
| 158 | + "time": "2024-07-08T16:42:48-07:00", |
| 159 | + "message": "http-request" |
| 160 | +} |
| 161 | +``` |
| 162 | + |
| 163 | +With the `xff_num_trusted_hops` option set to `1`, Pomerium will trust the client IP address populated by the load balancer: |
| 164 | + |
| 165 | +```yaml {title="config.yaml"} |
| 166 | +xff_num_trusted_hops: 1 |
| 167 | +access_log_fields: [forwarded-for, ip, method, path] |
| 168 | +``` |
| 169 | +
|
| 170 | +Example access log entry: |
| 171 | +
|
| 172 | +```json |
| 173 | +{ |
| 174 | + "level": "info", |
| 175 | + "service": "envoy", |
| 176 | + "forwarded-for": "192.0.5.1,10.1.2.3", |
| 177 | + // highlight-next-line |
| 178 | + "ip": "192.0.5.1", |
| 179 | + "method": "GET", |
| 180 | + "path": "/", |
| 181 | + "time": "2024-07-08T16:42:48-07:00", |
| 182 | + "message": "http-request" |
| 183 | +} |
| 184 | +``` |
| 185 | + |
| 186 | +:::info Additional Resource |
| 187 | + |
| 188 | +See the [**Envoy docs**](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers.html?highlight=skip_xff_append#x-forwarded-for) for more information about the `X-Forwarded-For` header. |
| 189 | + |
| 190 | +::: |
0 commit comments