Add support for ipv6 subnet in ipStrategy
This commit is contained in:
parent
a398536688
commit
312ebb17ab
17 changed files with 544 additions and 12 deletions
|
@ -101,7 +101,7 @@ If none are set, the default is to use the `requestHost`.
|
|||
|
||||
#### `sourceCriterion.ipStrategy`
|
||||
|
||||
The `ipStrategy` option defines two parameters that configures how Traefik determines the client IP: `depth`, and `excludedIPs`.
|
||||
The `ipStrategy` option defines three parameters that configures how Traefik determines the client IP: `depth`, `excludedIPs` and `ipv6Subnet`.
|
||||
|
||||
!!! important "As a middleware, InFlightReq happens before the actual proxying to the backend takes place. In addition, the previous network hop only gets appended to `X-Forwarded-For` during the last stages of proxying, i.e. after it has already passed through the middleware. Therefore, during InFlightReq, as the previous network hop is not yet present in `X-Forwarded-For`, it cannot be used and/or relied upon."
|
||||
|
||||
|
@ -112,6 +112,9 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and select
|
|||
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP is empty.
|
||||
- `depth` is ignored if its value is less than or equal to 0.
|
||||
|
||||
If `ipStrategy.ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
|
||||
See [ipStrategy.ipv6Subnet](#ipstrategyipv6subnet) for more details.
|
||||
|
||||
!!! example "Example of Depth & X-Forwarded-For"
|
||||
|
||||
If `depth` is set to 2, and the request `X-Forwarded-For` header is `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP is `"10.0.0.1"` (at depth 4) but the IP used as the criterion is `"12.0.0.1"` (`depth=2`).
|
||||
|
@ -218,6 +221,63 @@ http:
|
|||
excludedIPs = ["127.0.0.1/32", "192.168.1.7"]
|
||||
```
|
||||
|
||||
##### `ipStrategy.ipv6Subnet`
|
||||
|
||||
This strategy applies to `Depth` and `RemoteAddr` strategy only.
|
||||
If `ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
|
||||
|
||||
This is useful for grouping IPv6 addresses into subnets to prevent bypassing this middleware by obtaining a new IPv6.
|
||||
|
||||
- `ipv6Subnet` is ignored if its value is outside of 0-128 interval
|
||||
|
||||
!!! example "Example of ipv6Subnet"
|
||||
|
||||
If `ipv6Subnet` is provided, the IP is transformed in the following way.
|
||||
|
||||
| `IP` | `ipv6Subnet` | clientIP |
|
||||
|---------------------------|--------------|-----------------------|
|
||||
| `"::abcd:1111:2222:3333"` | `64` | `"::0:0:0:0"` |
|
||||
| `"::abcd:1111:2222:3333"` | `80` | `"::abcd:0:0:0:0"` |
|
||||
| `"::abcd:1111:2222:3333"` | `96` | `"::abcd:1111:0:0:0"` |
|
||||
|
||||
```yaml tab="Docker & Swarm"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.ipv6Subnet=64"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-inflightreq
|
||||
spec:
|
||||
inFlightReq:
|
||||
sourceCriterion:
|
||||
ipStrategy:
|
||||
ipv6Subnet: 64
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.ipv6Subnet=64"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
http:
|
||||
middlewares:
|
||||
test-inflightreq:
|
||||
inFlightReq:
|
||||
sourceCriterion:
|
||||
ipStrategy:
|
||||
ipv6Subnet: 64
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-inflightreq.inflightreq]
|
||||
[http.middlewares.test-inflightreq.inFlightReq.sourceCriterion.ipStrategy]
|
||||
ipv6Subnet = 64
|
||||
```
|
||||
|
||||
#### `sourceCriterion.requestHeaderName`
|
||||
|
||||
Name of the header used to group incoming requests.
|
||||
|
|
|
@ -75,6 +75,9 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th
|
|||
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP will be empty.
|
||||
- `depth` is ignored if its value is less than or equal to 0.
|
||||
|
||||
If `ipStrategy.ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
|
||||
See [ipStrategy.ipv6Subnet](#ipstrategyipv6subnet) for more details.
|
||||
|
||||
!!! example "Examples of Depth & X-Forwarded-For"
|
||||
|
||||
If `depth` is set to 2, and the request `X-Forwarded-For` header is `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP is `"10.0.0.1"` (at depth 4) but the IP used is `"12.0.0.1"` (`depth=2`).
|
||||
|
@ -204,3 +207,60 @@ http:
|
|||
[http.middlewares.test-ipallowlist.ipAllowList.ipStrategy]
|
||||
excludedIPs = ["127.0.0.1/32", "192.168.1.7"]
|
||||
```
|
||||
|
||||
#### `ipStrategy.ipv6Subnet`
|
||||
|
||||
This strategy applies to `Depth` and `RemoteAddr` strategy only.
|
||||
If `ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
|
||||
|
||||
This is useful for grouping IPv6 addresses into subnets to prevent bypassing this middleware by obtaining a new IPv6.
|
||||
|
||||
- `ipv6Subnet` is ignored if its value is outside of 0-128 interval
|
||||
|
||||
!!! example "Example of ipv6Subnet"
|
||||
|
||||
If `ipv6Subnet` is provided, the IP is transformed in the following way.
|
||||
|
||||
| `IP` | `ipv6Subnet` | clientIP |
|
||||
|---------------------------|--------------|-----------------------|
|
||||
| `"::abcd:1111:2222:3333"` | `64` | `"::0:0:0:0"` |
|
||||
| `"::abcd:1111:2222:3333"` | `80` | `"::abcd:0:0:0:0"` |
|
||||
| `"::abcd:1111:2222:3333"` | `96` | `"::abcd:1111:0:0:0"` |
|
||||
|
||||
```yaml tab="Docker & Swarm"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcecriterion.ipstrategy.ipv6Subnet=64"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-ipallowlist
|
||||
spec:
|
||||
ipallowlist:
|
||||
sourceCriterion:
|
||||
ipStrategy:
|
||||
ipv6Subnet: 64
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcecriterion.ipstrategy.ipv6Subnet=64"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
http:
|
||||
middlewares:
|
||||
test-ipallowlist:
|
||||
ipallowlist:
|
||||
sourceCriterion:
|
||||
ipStrategy:
|
||||
ipv6Subnet: 64
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-ipallowlist.ipallowlist]
|
||||
[http.middlewares.test-ipallowlist.ipallowlist.sourceCriterion.ipStrategy]
|
||||
ipv6Subnet = 64
|
||||
```
|
||||
|
|
|
@ -81,6 +81,9 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th
|
|||
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP will be empty.
|
||||
- `depth` is ignored if its value is less than or equal to 0.
|
||||
|
||||
If `ipStrategy.ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
|
||||
See [ipStrategy.ipv6Subnet](#ipstrategyipv6subnet) for more details.
|
||||
|
||||
!!! example "Examples of Depth & X-Forwarded-For"
|
||||
|
||||
If `depth` is set to 2, and the request `X-Forwarded-For` header is `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP is `"10.0.0.1"` (at depth 4) but the IP used for the whitelisting is `"12.0.0.1"` (`depth=2`).
|
||||
|
@ -210,3 +213,60 @@ http:
|
|||
[http.middlewares.test-ipwhitelist.ipWhiteList.ipStrategy]
|
||||
excludedIPs = ["127.0.0.1/32", "192.168.1.7"]
|
||||
```
|
||||
|
||||
#### `ipStrategy.ipv6Subnet`
|
||||
|
||||
This strategy applies to `Depth` and `RemoteAddr` strategy only.
|
||||
If `ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
|
||||
|
||||
This is useful for grouping IPv6 addresses into subnets to prevent bypassing this middleware by obtaining a new IPv6.
|
||||
|
||||
- `ipv6Subnet` is ignored if its value is outside of 0-128 interval
|
||||
|
||||
!!! example "Example of ipv6Subnet"
|
||||
|
||||
If `ipv6Subnet` is provided, the IP is transformed in the following way.
|
||||
|
||||
| `IP` | `ipv6Subnet` | clientIP |
|
||||
|---------------------------|--------------|-----------------------|
|
||||
| `"::abcd:1111:2222:3333"` | `64` | `"::0:0:0:0"` |
|
||||
| `"::abcd:1111:2222:3333"` | `80` | `"::abcd:0:0:0:0"` |
|
||||
| `"::abcd:1111:2222:3333"` | `96` | `"::abcd:1111:0:0:0"` |
|
||||
|
||||
```yaml tab="Docker & Swarm"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ipWhiteList.ipWhiteList.sourcecriterion.ipstrategy.ipv6Subnet=64"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-ipWhiteList
|
||||
spec:
|
||||
ipWhiteList:
|
||||
sourceCriterion:
|
||||
ipStrategy:
|
||||
ipv6Subnet: 64
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-ipWhiteList.ipWhiteList.sourcecriterion.ipstrategy.ipv6Subnet=64"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
http:
|
||||
middlewares:
|
||||
test-ipWhiteList:
|
||||
ipWhiteList:
|
||||
sourceCriterion:
|
||||
ipStrategy:
|
||||
ipv6Subnet: 64
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-ipWhiteList.ipWhiteList]
|
||||
[http.middlewares.test-ipWhiteList.ipWhiteList.sourceCriterion.ipStrategy]
|
||||
ipv6Subnet = 64
|
||||
```
|
||||
|
|
|
@ -211,7 +211,7 @@ If none are set, the default is to use the request's remote address field (as an
|
|||
|
||||
#### `sourceCriterion.ipStrategy`
|
||||
|
||||
The `ipStrategy` option defines two parameters that configures how Traefik determines the client IP: `depth`, and `excludedIPs`.
|
||||
The `ipStrategy` option defines three parameters that configures how Traefik determines the client IP: `depth`, `excludedIPs` and `ipv6Subnet`.
|
||||
|
||||
!!! important "As a middleware, rate-limiting happens before the actual proxying to the backend takes place. In addition, the previous network hop only gets appended to `X-Forwarded-For` during the last stages of proxying, i.e. after it has already passed through rate-limiting. Therefore, during rate-limiting, as the previous network hop is not yet present in `X-Forwarded-For`, it cannot be found and/or relied upon."
|
||||
|
||||
|
@ -222,6 +222,9 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and select
|
|||
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP is empty.
|
||||
- `depth` is ignored if its value is less than or equal to 0.
|
||||
|
||||
If `ipStrategy.ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
|
||||
See [ipStrategy.ipv6Subnet](#ipstrategyipv6subnet) for more details.
|
||||
|
||||
!!! example "Example of Depth & X-Forwarded-For"
|
||||
|
||||
If `depth` is set to 2, and the request `X-Forwarded-For` header is `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP is `"10.0.0.1"` (at depth 4) but the IP used as the criterion is `"12.0.0.1"` (`depth=2`).
|
||||
|
@ -355,6 +358,63 @@ http:
|
|||
excludedIPs = ["127.0.0.1/32", "192.168.1.7"]
|
||||
```
|
||||
|
||||
##### `ipStrategy.ipv6Subnet`
|
||||
|
||||
This strategy applies to `Depth` and `RemoteAddr` strategy only.
|
||||
If `ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
|
||||
|
||||
This is useful for grouping IPv6 addresses into subnets to prevent bypassing this middleware by obtaining a new IPv6.
|
||||
|
||||
- `ipv6Subnet` is ignored if its value is outside of 0-128 interval
|
||||
|
||||
!!! example "Example of ipv6Subnet"
|
||||
|
||||
If `ipv6Subnet` is provided, the IP is transformed in the following way.
|
||||
|
||||
| `IP` | `ipv6Subnet` | clientIP |
|
||||
|---------------------------|--------------|-----------------------|
|
||||
| `"::abcd:1111:2222:3333"` | `64` | `"::0:0:0:0"` |
|
||||
| `"::abcd:1111:2222:3333"` | `80` | `"::abcd:0:0:0:0"` |
|
||||
| `"::abcd:1111:2222:3333"` | `96` | `"::abcd:1111:0:0:0"` |
|
||||
|
||||
```yaml tab="Docker & Swarm"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.ipv6Subnet=64"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-ratelimit
|
||||
spec:
|
||||
ratelimit:
|
||||
sourceCriterion:
|
||||
ipStrategy:
|
||||
ipv6Subnet: 64
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.ipv6Subnet=64"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
http:
|
||||
middlewares:
|
||||
test-ratelimit:
|
||||
ratelimit:
|
||||
sourceCriterion:
|
||||
ipStrategy:
|
||||
ipv6Subnet: 64
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-ratelimit.ratelimit]
|
||||
[http.middlewares.test-ratelimit.ratelimit.sourceCriterion.ipStrategy]
|
||||
ipv6Subnet = 64
|
||||
```
|
||||
|
||||
#### `sourceCriterion.requestHeaderName`
|
||||
|
||||
Name of the header used to group incoming requests.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue