Deprecate IPWhiteList middleware in favor of IPAllowList
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
This commit is contained in:
parent
9662cdca64
commit
0e92b02474
36 changed files with 1268 additions and 50 deletions
195
docs/content/middlewares/http/ipallowlist.md
Normal file
195
docs/content/middlewares/http/ipallowlist.md
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
---
|
||||||
|
title: "Traefik HTTP Middlewares IPAllowList"
|
||||||
|
description: "Learn how to use IPAllowList in HTTP middleware for limiting clients to specific IPs in Traefik Proxy. Read the technical documentation."
|
||||||
|
---
|
||||||
|
|
||||||
|
# IPAllowList
|
||||||
|
|
||||||
|
Limiting Clients to Specific IPs
|
||||||
|
{: .subtitle }
|
||||||
|
|
||||||
|
IPAllowList accepts / refuses requests based on the client IP.
|
||||||
|
|
||||||
|
## Configuration Examples
|
||||||
|
|
||||||
|
```yaml tab="Docker & Swarm"
|
||||||
|
# Accepts request from defined IP
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: test-ipallowlist
|
||||||
|
spec:
|
||||||
|
ipAllowList:
|
||||||
|
sourceRange:
|
||||||
|
- 127.0.0.1/32
|
||||||
|
- 192.168.1.7
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Accepts request from defined IP
|
||||||
|
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Accepts request from defined IP
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
test-ipallowlist:
|
||||||
|
ipAllowList:
|
||||||
|
sourceRange:
|
||||||
|
- "127.0.0.1/32"
|
||||||
|
- "192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Accepts request from defined IP
|
||||||
|
[http.middlewares]
|
||||||
|
[http.middlewares.test-ipallowlist.ipAllowList]
|
||||||
|
sourceRange = ["127.0.0.1/32", "192.168.1.7"]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
### `sourceRange`
|
||||||
|
|
||||||
|
The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
||||||
|
|
||||||
|
### `ipStrategy`
|
||||||
|
|
||||||
|
The `ipStrategy` option defines two parameters that set how Traefik determines the client IP: `depth`, and `excludedIPs`.
|
||||||
|
If no strategy is set, the default behavior is to match `sourceRange` against the Remote address found in the request.
|
||||||
|
|
||||||
|
!!! important "As a middleware, whitelisting 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 whitelisting. Therefore, during whitelisting, as the previous network hop is not yet present in `X-Forwarded-For`, it cannot be matched against `sourceRange`."
|
||||||
|
|
||||||
|
#### `ipStrategy.depth`
|
||||||
|
|
||||||
|
The `depth` option tells Traefik to use the `X-Forwarded-For` header and take the IP located at the `depth` position (starting from the right).
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
!!! 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`).
|
||||||
|
|
||||||
|
| `X-Forwarded-For` | `depth` | clientIP |
|
||||||
|
|-----------------------------------------|---------|--------------|
|
||||||
|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `1` | `"13.0.0.1"` |
|
||||||
|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `3` | `"11.0.0.1"` |
|
||||||
|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `5` | `""` |
|
||||||
|
|
||||||
|
```yaml tab="Docker & Swarm"
|
||||||
|
# Allowlisting Based on `X-Forwarded-For` with `depth=2`
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||||
|
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth=2"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
# Allowlisting Based on `X-Forwarded-For` with `depth=2`
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: test-ipallowlist
|
||||||
|
spec:
|
||||||
|
ipAllowList:
|
||||||
|
sourceRange:
|
||||||
|
- 127.0.0.1/32
|
||||||
|
- 192.168.1.7
|
||||||
|
ipStrategy:
|
||||||
|
depth: 2
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Allowlisting Based on `X-Forwarded-For` with `depth=2`
|
||||||
|
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||||
|
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth=2"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Allowlisting Based on `X-Forwarded-For` with `depth=2`
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
test-ipallowlist:
|
||||||
|
ipAllowList:
|
||||||
|
sourceRange:
|
||||||
|
- "127.0.0.1/32"
|
||||||
|
- "192.168.1.7"
|
||||||
|
ipStrategy:
|
||||||
|
depth: 2
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Allowlisting Based on `X-Forwarded-For` with `depth=2`
|
||||||
|
[http.middlewares]
|
||||||
|
[http.middlewares.test-ipallowlist.ipAllowList]
|
||||||
|
sourceRange = ["127.0.0.1/32", "192.168.1.7"]
|
||||||
|
[http.middlewares.test-ipallowlist.ipAllowList.ipStrategy]
|
||||||
|
depth = 2
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `ipStrategy.excludedIPs`
|
||||||
|
|
||||||
|
`excludedIPs` configures Traefik to scan the `X-Forwarded-For` header and select the first IP not in the list.
|
||||||
|
|
||||||
|
!!! important "If `depth` is specified, `excludedIPs` is ignored."
|
||||||
|
|
||||||
|
!!! example "Example of ExcludedIPs & X-Forwarded-For"
|
||||||
|
|
||||||
|
| `X-Forwarded-For` | `excludedIPs` | clientIP |
|
||||||
|
|-----------------------------------------|-----------------------|--------------|
|
||||||
|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"12.0.0.1,13.0.0.1"` | `"11.0.0.1"` |
|
||||||
|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
|
||||||
|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"10.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
|
||||||
|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,16.0.0.1"` | `"13.0.0.1"` |
|
||||||
|
| `"10.0.0.1,11.0.0.1"` | `"10.0.0.1,11.0.0.1"` | `""` |
|
||||||
|
|
||||||
|
```yaml tab="Docker & Swarm"
|
||||||
|
# Exclude from `X-Forwarded-For`
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
# Exclude from `X-Forwarded-For`
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: test-ipallowlist
|
||||||
|
spec:
|
||||||
|
ipAllowList:
|
||||||
|
ipStrategy:
|
||||||
|
excludedIPs:
|
||||||
|
- 127.0.0.1/32
|
||||||
|
- 192.168.1.7
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Exclude from `X-Forwarded-For`
|
||||||
|
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Exclude from `X-Forwarded-For`
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
test-ipallowlist:
|
||||||
|
ipAllowList:
|
||||||
|
ipStrategy:
|
||||||
|
excludedIPs:
|
||||||
|
- "127.0.0.1/32"
|
||||||
|
- "192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Exclude from `X-Forwarded-For`
|
||||||
|
[http.middlewares]
|
||||||
|
[http.middlewares.test-ipallowlist.ipAllowList]
|
||||||
|
[http.middlewares.test-ipallowlist.ipAllowList.ipStrategy]
|
||||||
|
excludedIPs = ["127.0.0.1/32", "192.168.1.7"]
|
||||||
|
```
|
|
@ -8,9 +8,13 @@ description: "Learn how to use IPWhiteList in HTTP middleware for limiting clien
|
||||||
Limiting Clients to Specific IPs
|
Limiting Clients to Specific IPs
|
||||||
{: .subtitle }
|
{: .subtitle }
|
||||||
|
|
||||||
![IpWhiteList](../../assets/img/middleware/ipwhitelist.png)
|
![IPWhiteList](../../assets/img/middleware/ipwhitelist.png)
|
||||||
|
|
||||||
IPWhitelist accepts / refuses requests based on the client IP.
|
IPWhiteList accepts / refuses requests based on the client IP.
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
|
||||||
|
This middleware is deprecated, please use the [IPAllowList](./ipallowlist.md) middleware instead.
|
||||||
|
|
||||||
## Configuration Examples
|
## Configuration Examples
|
||||||
|
|
||||||
|
|
60
docs/content/middlewares/tcp/ipallowlist.md
Normal file
60
docs/content/middlewares/tcp/ipallowlist.md
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
---
|
||||||
|
title: "Traefik TCP Middlewares IPAllowList"
|
||||||
|
description: "Learn how to use IPAllowList in TCP middleware for limiting clients to specific IPs in Traefik Proxy. Read the technical documentation."
|
||||||
|
---
|
||||||
|
|
||||||
|
# IPAllowList
|
||||||
|
|
||||||
|
Limiting Clients to Specific IPs
|
||||||
|
{: .subtitle }
|
||||||
|
|
||||||
|
IPAllowList accepts / refuses connections based on the client IP.
|
||||||
|
|
||||||
|
## Configuration Examples
|
||||||
|
|
||||||
|
```yaml tab="Docker & Swarm"
|
||||||
|
# Accepts connections from defined IP
|
||||||
|
labels:
|
||||||
|
- "traefik.tcp.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: MiddlewareTCP
|
||||||
|
metadata:
|
||||||
|
name: test-ipallowlist
|
||||||
|
spec:
|
||||||
|
ipAllowList:
|
||||||
|
sourceRange:
|
||||||
|
- 127.0.0.1/32
|
||||||
|
- 192.168.1.7
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Accepts request from defined IP
|
||||||
|
- "traefik.tcp.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Accepts request from defined IP
|
||||||
|
[tcp.middlewares]
|
||||||
|
[tcp.middlewares.test-ipallowlist.ipAllowList]
|
||||||
|
sourceRange = ["127.0.0.1/32", "192.168.1.7"]
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Accepts request from defined IP
|
||||||
|
tcp:
|
||||||
|
middlewares:
|
||||||
|
test-ipallowlist:
|
||||||
|
ipAllowList:
|
||||||
|
sourceRange:
|
||||||
|
- "127.0.0.1/32"
|
||||||
|
- "192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
### `sourceRange`
|
||||||
|
|
||||||
|
The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
|
@ -8,7 +8,11 @@ description: "Learn how to use IPWhiteList in TCP middleware for limiting client
|
||||||
Limiting Clients to Specific IPs
|
Limiting Clients to Specific IPs
|
||||||
{: .subtitle }
|
{: .subtitle }
|
||||||
|
|
||||||
IPWhitelist accepts / refuses connections based on the client IP.
|
IPWhiteList accepts / refuses connections based on the client IP.
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
|
||||||
|
This middleware is deprecated, please use the [IPAllowList](./ipallowlist.md) middleware instead.
|
||||||
|
|
||||||
## Configuration Examples
|
## Configuration Examples
|
||||||
|
|
||||||
|
|
|
@ -523,3 +523,13 @@ kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.10/docs/co
|
||||||
### Traefik Hub
|
### Traefik Hub
|
||||||
|
|
||||||
In `v2.10`, Traefik Hub configuration has been removed because Traefik Hub v2 doesn't require this configuration.
|
In `v2.10`, Traefik Hub configuration has been removed because Traefik Hub v2 doesn't require this configuration.
|
||||||
|
|
||||||
|
## v2.11
|
||||||
|
|
||||||
|
### IPWhiteList (HTTP)
|
||||||
|
|
||||||
|
In `v2.11`, the `IPWhiteList` middleware is deprecated, please use the [IPAllowList](../middlewares/http/ipallowlist.md) middleware instead.
|
||||||
|
|
||||||
|
### IPWhiteList (TCP)
|
||||||
|
|
||||||
|
In `v2.11`, the `IPWhiteList` middleware is deprecated, please use the [IPAllowList](../middlewares/tcp/ipallowlist.md) middleware instead.
|
||||||
|
|
|
@ -121,6 +121,9 @@
|
||||||
- "traefik.http.middlewares.middleware21.stripprefix.forceslash=true"
|
- "traefik.http.middlewares.middleware21.stripprefix.forceslash=true"
|
||||||
- "traefik.http.middlewares.middleware21.stripprefix.prefixes=foobar, foobar"
|
- "traefik.http.middlewares.middleware21.stripprefix.prefixes=foobar, foobar"
|
||||||
- "traefik.http.middlewares.middleware22.stripprefixregex.regex=foobar, foobar"
|
- "traefik.http.middlewares.middleware22.stripprefixregex.regex=foobar, foobar"
|
||||||
|
- "traefik.http.middlewares.middleware23.ipallowlist.ipstrategy.depth=42"
|
||||||
|
- "traefik.http.middlewares.middleware23.ipallowlist.ipstrategy.excludedips=foobar, foobar"
|
||||||
|
- "traefik.http.middlewares.middleware23.ipallowlist.sourcerange=foobar, foobar"
|
||||||
- "traefik.http.routers.router0.entrypoints=foobar, foobar"
|
- "traefik.http.routers.router0.entrypoints=foobar, foobar"
|
||||||
- "traefik.http.routers.router0.middlewares=foobar, foobar"
|
- "traefik.http.routers.router0.middlewares=foobar, foobar"
|
||||||
- "traefik.http.routers.router0.priority=42"
|
- "traefik.http.routers.router0.priority=42"
|
||||||
|
@ -167,6 +170,7 @@
|
||||||
- "traefik.http.services.service01.loadbalancer.server.scheme=foobar"
|
- "traefik.http.services.service01.loadbalancer.server.scheme=foobar"
|
||||||
- "traefik.tcp.middlewares.tcpmiddleware00.ipwhitelist.sourcerange=foobar, foobar"
|
- "traefik.tcp.middlewares.tcpmiddleware00.ipwhitelist.sourcerange=foobar, foobar"
|
||||||
- "traefik.tcp.middlewares.tcpmiddleware01.inflightconn.amount=42"
|
- "traefik.tcp.middlewares.tcpmiddleware01.inflightconn.amount=42"
|
||||||
|
- "traefik.tcp.middlewares.tcpmiddleware02.ipallowlist.sourcerange=foobar, foobar"
|
||||||
- "traefik.tcp.routers.tcprouter0.entrypoints=foobar, foobar"
|
- "traefik.tcp.routers.tcprouter0.entrypoints=foobar, foobar"
|
||||||
- "traefik.tcp.routers.tcprouter0.middlewares=foobar, foobar"
|
- "traefik.tcp.routers.tcprouter0.middlewares=foobar, foobar"
|
||||||
- "traefik.tcp.routers.tcprouter0.rule=foobar"
|
- "traefik.tcp.routers.tcprouter0.rule=foobar"
|
||||||
|
|
|
@ -284,6 +284,12 @@
|
||||||
[http.middlewares.Middleware22]
|
[http.middlewares.Middleware22]
|
||||||
[http.middlewares.Middleware22.stripPrefixRegex]
|
[http.middlewares.Middleware22.stripPrefixRegex]
|
||||||
regex = ["foobar", "foobar"]
|
regex = ["foobar", "foobar"]
|
||||||
|
[http.middlewares.Middleware23]
|
||||||
|
[http.middlewares.Middleware23.ipAllowList]
|
||||||
|
sourceRange = ["foobar", "foobar"]
|
||||||
|
[http.middlewares.Middleware23.ipAllowList.ipStrategy]
|
||||||
|
depth = 42
|
||||||
|
excludedIPs = ["foobar", "foobar"]
|
||||||
[http.serversTransports]
|
[http.serversTransports]
|
||||||
[http.serversTransports.ServersTransport0]
|
[http.serversTransports.ServersTransport0]
|
||||||
serverName = "foobar"
|
serverName = "foobar"
|
||||||
|
|
|
@ -323,6 +323,16 @@ http:
|
||||||
regex:
|
regex:
|
||||||
- foobar
|
- foobar
|
||||||
- foobar
|
- foobar
|
||||||
|
Middleware23:
|
||||||
|
ipAllowList:
|
||||||
|
sourceRange:
|
||||||
|
- foobar
|
||||||
|
- foobar
|
||||||
|
ipStrategy:
|
||||||
|
depth: 42
|
||||||
|
excludedIPs:
|
||||||
|
- foobar
|
||||||
|
- foobar
|
||||||
serversTransports:
|
serversTransports:
|
||||||
ServersTransport0:
|
ServersTransport0:
|
||||||
serverName: foobar
|
serverName: foobar
|
||||||
|
@ -437,6 +447,11 @@ tcp:
|
||||||
TCPMiddleware01:
|
TCPMiddleware01:
|
||||||
inFlightConn:
|
inFlightConn:
|
||||||
amount: 42
|
amount: 42
|
||||||
|
TCPMiddleware02:
|
||||||
|
ipAllowList:
|
||||||
|
sourceRange:
|
||||||
|
- foobar
|
||||||
|
- foobar
|
||||||
udp:
|
udp:
|
||||||
routers:
|
routers:
|
||||||
UDPRouter0:
|
UDPRouter0:
|
||||||
|
|
|
@ -1151,7 +1151,7 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration
|
description: 'IPStrategy holds the IP strategy configuration
|
||||||
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -1176,14 +1176,43 @@ spec:
|
||||||
type: boolean
|
type: boolean
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
ipWhiteList:
|
ipAllowList:
|
||||||
description: 'IPWhiteList holds the IP whitelist middleware configuration.
|
description: 'IPAllowList holds the IP allowlist middleware configuration.
|
||||||
This middleware accepts / refuses requests based on the client IP.
|
This middleware accepts / refuses requests based on the client IP.
|
||||||
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/'
|
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/'
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration used
|
description: 'IPStrategy holds the IP strategy configuration used
|
||||||
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
|
properties:
|
||||||
|
depth:
|
||||||
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
header and take the IP located at the depth position (starting
|
||||||
|
from the right).
|
||||||
|
type: integer
|
||||||
|
excludedIPs:
|
||||||
|
description: ExcludedIPs configures Traefik to scan the X-Forwarded-For
|
||||||
|
header and select the first IP not in the list.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
sourceRange:
|
||||||
|
description: SourceRange defines the set of allowed IPs (or ranges
|
||||||
|
of allowed IPs by using CIDR notation).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
ipWhiteList:
|
||||||
|
description: 'IPWhiteList holds the IP whitelist middleware configuration.
|
||||||
|
This middleware accepts / refuses requests based on the client IP.
|
||||||
|
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/
|
||||||
|
Deprecated: please use IPAllowList instead.'
|
||||||
|
properties:
|
||||||
|
ipStrategy:
|
||||||
|
description: 'IPStrategy holds the IP strategy configuration used
|
||||||
|
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -1347,7 +1376,7 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration
|
description: 'IPStrategy holds the IP strategy configuration
|
||||||
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -1535,8 +1564,22 @@ spec:
|
||||||
format: int64
|
format: int64
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
ipAllowList:
|
||||||
|
description: 'IPAllowList defines the IPAllowList middleware configuration.
|
||||||
|
This middleware accepts/refuses connections based on the client
|
||||||
|
IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipallowlist/'
|
||||||
|
properties:
|
||||||
|
sourceRange:
|
||||||
|
description: SourceRange defines the allowed IPs (or ranges of
|
||||||
|
allowed IPs by using CIDR notation).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
ipWhiteList:
|
ipWhiteList:
|
||||||
description: IPWhiteList defines the IPWhiteList middleware configuration.
|
description: 'IPWhiteList defines the IPWhiteList middleware configuration.
|
||||||
|
This middleware accepts/refuses connections based on the client
|
||||||
|
IP. Deprecated: please use IPAllowList instead. More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipwhitelist/'
|
||||||
properties:
|
properties:
|
||||||
sourceRange:
|
sourceRange:
|
||||||
description: SourceRange defines the allowed IPs (or ranges of
|
description: SourceRange defines the allowed IPs (or ranges of
|
||||||
|
@ -3415,7 +3458,7 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration
|
description: 'IPStrategy holds the IP strategy configuration
|
||||||
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -3440,14 +3483,43 @@ spec:
|
||||||
type: boolean
|
type: boolean
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
ipWhiteList:
|
ipAllowList:
|
||||||
description: 'IPWhiteList holds the IP whitelist middleware configuration.
|
description: 'IPAllowList holds the IP allowlist middleware configuration.
|
||||||
This middleware accepts / refuses requests based on the client IP.
|
This middleware accepts / refuses requests based on the client IP.
|
||||||
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/'
|
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/'
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration used
|
description: 'IPStrategy holds the IP strategy configuration used
|
||||||
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
|
properties:
|
||||||
|
depth:
|
||||||
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
header and take the IP located at the depth position (starting
|
||||||
|
from the right).
|
||||||
|
type: integer
|
||||||
|
excludedIPs:
|
||||||
|
description: ExcludedIPs configures Traefik to scan the X-Forwarded-For
|
||||||
|
header and select the first IP not in the list.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
sourceRange:
|
||||||
|
description: SourceRange defines the set of allowed IPs (or ranges
|
||||||
|
of allowed IPs by using CIDR notation).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
ipWhiteList:
|
||||||
|
description: 'IPWhiteList holds the IP whitelist middleware configuration.
|
||||||
|
This middleware accepts / refuses requests based on the client IP.
|
||||||
|
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/
|
||||||
|
Deprecated: please use IPAllowList instead.'
|
||||||
|
properties:
|
||||||
|
ipStrategy:
|
||||||
|
description: 'IPStrategy holds the IP strategy configuration used
|
||||||
|
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -3611,7 +3683,7 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration
|
description: 'IPStrategy holds the IP strategy configuration
|
||||||
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -3799,8 +3871,22 @@ spec:
|
||||||
format: int64
|
format: int64
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
ipAllowList:
|
||||||
|
description: 'IPAllowList defines the IPAllowList middleware configuration.
|
||||||
|
This middleware accepts/refuses connections based on the client
|
||||||
|
IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipallowlist/'
|
||||||
|
properties:
|
||||||
|
sourceRange:
|
||||||
|
description: SourceRange defines the allowed IPs (or ranges of
|
||||||
|
allowed IPs by using CIDR notation).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
ipWhiteList:
|
ipWhiteList:
|
||||||
description: IPWhiteList defines the IPWhiteList middleware configuration.
|
description: 'IPWhiteList defines the IPWhiteList middleware configuration.
|
||||||
|
This middleware accepts/refuses connections based on the client
|
||||||
|
IP. Deprecated: please use IPAllowList instead. More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipwhitelist/'
|
||||||
properties:
|
properties:
|
||||||
sourceRange:
|
sourceRange:
|
||||||
description: SourceRange defines the allowed IPs (or ranges of
|
description: SourceRange defines the allowed IPs (or ranges of
|
||||||
|
|
|
@ -148,7 +148,7 @@ spec:
|
||||||
- name: whoamitcp
|
- name: whoamitcp
|
||||||
port: 8080
|
port: 8080
|
||||||
middlewares:
|
middlewares:
|
||||||
- name: ipwhitelist
|
- name: ipallowlist
|
||||||
tls:
|
tls:
|
||||||
secretName: foosecret
|
secretName: foosecret
|
||||||
passthrough: false
|
passthrough: false
|
||||||
|
|
|
@ -140,6 +140,11 @@
|
||||||
| `traefik/http/middlewares/Middleware21/stripPrefix/prefixes/1` | `foobar` |
|
| `traefik/http/middlewares/Middleware21/stripPrefix/prefixes/1` | `foobar` |
|
||||||
| `traefik/http/middlewares/Middleware22/stripPrefixRegex/regex/0` | `foobar` |
|
| `traefik/http/middlewares/Middleware22/stripPrefixRegex/regex/0` | `foobar` |
|
||||||
| `traefik/http/middlewares/Middleware22/stripPrefixRegex/regex/1` | `foobar` |
|
| `traefik/http/middlewares/Middleware22/stripPrefixRegex/regex/1` | `foobar` |
|
||||||
|
| `traefik/http/middlewares/Middleware23/ipAllowList/ipStrategy/depth` | `42` |
|
||||||
|
| `traefik/http/middlewares/Middleware23/ipAllowList/ipStrategy/excludedIPs/0` | `foobar` |
|
||||||
|
| `traefik/http/middlewares/Middleware23/ipAllowList/ipStrategy/excludedIPs/1` | `foobar` |
|
||||||
|
| `traefik/http/middlewares/Middleware23/ipAllowList/sourceRange/0` | `foobar` |
|
||||||
|
| `traefik/http/middlewares/Middleware23/ipAllowList/sourceRange/1` | `foobar` |
|
||||||
| `traefik/http/routers/Router0/entryPoints/0` | `foobar` |
|
| `traefik/http/routers/Router0/entryPoints/0` | `foobar` |
|
||||||
| `traefik/http/routers/Router0/entryPoints/1` | `foobar` |
|
| `traefik/http/routers/Router0/entryPoints/1` | `foobar` |
|
||||||
| `traefik/http/routers/Router0/middlewares/0` | `foobar` |
|
| `traefik/http/routers/Router0/middlewares/0` | `foobar` |
|
||||||
|
|
|
@ -121,6 +121,9 @@
|
||||||
"traefik.http.middlewares.middleware21.stripprefix.forceslash": "true",
|
"traefik.http.middlewares.middleware21.stripprefix.forceslash": "true",
|
||||||
"traefik.http.middlewares.middleware21.stripprefix.prefixes": "foobar, foobar",
|
"traefik.http.middlewares.middleware21.stripprefix.prefixes": "foobar, foobar",
|
||||||
"traefik.http.middlewares.middleware22.stripprefixregex.regex": "foobar, foobar",
|
"traefik.http.middlewares.middleware22.stripprefixregex.regex": "foobar, foobar",
|
||||||
|
"traefik.http.middlewares.middleware23.ipallowlist.ipstrategy.depth": "42",
|
||||||
|
"traefik.http.middlewares.middleware23.ipallowlist.ipstrategy.excludedips": "foobar, foobar",
|
||||||
|
"traefik.http.middlewares.middleware23.ipallowlist.sourcerange": "foobar, foobar",
|
||||||
"traefik.http.routers.router0.entrypoints": "foobar, foobar",
|
"traefik.http.routers.router0.entrypoints": "foobar, foobar",
|
||||||
"traefik.http.routers.router0.middlewares": "foobar, foobar",
|
"traefik.http.routers.router0.middlewares": "foobar, foobar",
|
||||||
"traefik.http.routers.router0.priority": "42",
|
"traefik.http.routers.router0.priority": "42",
|
||||||
|
@ -167,6 +170,7 @@
|
||||||
"traefik.http.services.service01.loadbalancer.server.scheme": "foobar",
|
"traefik.http.services.service01.loadbalancer.server.scheme": "foobar",
|
||||||
"traefik.tcp.middlewares.tcpmiddleware00.ipwhitelist.sourcerange": "foobar, foobar",
|
"traefik.tcp.middlewares.tcpmiddleware00.ipwhitelist.sourcerange": "foobar, foobar",
|
||||||
"traefik.tcp.middlewares.tcpmiddleware01.inflightconn.amount": "42",
|
"traefik.tcp.middlewares.tcpmiddleware01.inflightconn.amount": "42",
|
||||||
|
"traefik.tcp.middlewares.tcpmiddleware02.ipallowlist.sourcerange": "foobar, foobar",
|
||||||
"traefik.tcp.routers.tcprouter0.entrypoints": "foobar, foobar",
|
"traefik.tcp.routers.tcprouter0.entrypoints": "foobar, foobar",
|
||||||
"traefik.tcp.routers.tcprouter0.middlewares": "foobar, foobar",
|
"traefik.tcp.routers.tcprouter0.middlewares": "foobar, foobar",
|
||||||
"traefik.tcp.routers.tcprouter0.rule": "foobar",
|
"traefik.tcp.routers.tcprouter0.rule": "foobar",
|
||||||
|
|
|
@ -577,7 +577,7 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration
|
description: 'IPStrategy holds the IP strategy configuration
|
||||||
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -602,14 +602,43 @@ spec:
|
||||||
type: boolean
|
type: boolean
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
ipWhiteList:
|
ipAllowList:
|
||||||
description: 'IPWhiteList holds the IP whitelist middleware configuration.
|
description: 'IPAllowList holds the IP allowlist middleware configuration.
|
||||||
This middleware accepts / refuses requests based on the client IP.
|
This middleware accepts / refuses requests based on the client IP.
|
||||||
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/'
|
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/'
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration used
|
description: 'IPStrategy holds the IP strategy configuration used
|
||||||
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
|
properties:
|
||||||
|
depth:
|
||||||
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
header and take the IP located at the depth position (starting
|
||||||
|
from the right).
|
||||||
|
type: integer
|
||||||
|
excludedIPs:
|
||||||
|
description: ExcludedIPs configures Traefik to scan the X-Forwarded-For
|
||||||
|
header and select the first IP not in the list.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
sourceRange:
|
||||||
|
description: SourceRange defines the set of allowed IPs (or ranges
|
||||||
|
of allowed IPs by using CIDR notation).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
ipWhiteList:
|
||||||
|
description: 'IPWhiteList holds the IP whitelist middleware configuration.
|
||||||
|
This middleware accepts / refuses requests based on the client IP.
|
||||||
|
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/
|
||||||
|
Deprecated: please use IPAllowList instead.'
|
||||||
|
properties:
|
||||||
|
ipStrategy:
|
||||||
|
description: 'IPStrategy holds the IP strategy configuration used
|
||||||
|
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -773,7 +802,7 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration
|
description: 'IPStrategy holds the IP strategy configuration
|
||||||
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
|
|
@ -45,8 +45,22 @@ spec:
|
||||||
format: int64
|
format: int64
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
ipAllowList:
|
||||||
|
description: 'IPAllowList defines the IPAllowList middleware configuration.
|
||||||
|
This middleware accepts/refuses connections based on the client
|
||||||
|
IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipallowlist/'
|
||||||
|
properties:
|
||||||
|
sourceRange:
|
||||||
|
description: SourceRange defines the allowed IPs (or ranges of
|
||||||
|
allowed IPs by using CIDR notation).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
ipWhiteList:
|
ipWhiteList:
|
||||||
description: IPWhiteList defines the IPWhiteList middleware configuration.
|
description: 'IPWhiteList defines the IPWhiteList middleware configuration.
|
||||||
|
This middleware accepts/refuses connections based on the client
|
||||||
|
IP. Deprecated: please use IPAllowList instead. More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipwhitelist/'
|
||||||
properties:
|
properties:
|
||||||
sourceRange:
|
sourceRange:
|
||||||
description: SourceRange defines the allowed IPs (or ranges of
|
description: SourceRange defines the allowed IPs (or ranges of
|
||||||
|
|
|
@ -577,7 +577,7 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration
|
description: 'IPStrategy holds the IP strategy configuration
|
||||||
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -602,14 +602,43 @@ spec:
|
||||||
type: boolean
|
type: boolean
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
ipWhiteList:
|
ipAllowList:
|
||||||
description: 'IPWhiteList holds the IP whitelist middleware configuration.
|
description: 'IPAllowList holds the IP allowlist middleware configuration.
|
||||||
This middleware accepts / refuses requests based on the client IP.
|
This middleware accepts / refuses requests based on the client IP.
|
||||||
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/'
|
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/'
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration used
|
description: 'IPStrategy holds the IP strategy configuration used
|
||||||
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
|
properties:
|
||||||
|
depth:
|
||||||
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
header and take the IP located at the depth position (starting
|
||||||
|
from the right).
|
||||||
|
type: integer
|
||||||
|
excludedIPs:
|
||||||
|
description: ExcludedIPs configures Traefik to scan the X-Forwarded-For
|
||||||
|
header and select the first IP not in the list.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
sourceRange:
|
||||||
|
description: SourceRange defines the set of allowed IPs (or ranges
|
||||||
|
of allowed IPs by using CIDR notation).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
ipWhiteList:
|
||||||
|
description: 'IPWhiteList holds the IP whitelist middleware configuration.
|
||||||
|
This middleware accepts / refuses requests based on the client IP.
|
||||||
|
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/
|
||||||
|
Deprecated: please use IPAllowList instead.'
|
||||||
|
properties:
|
||||||
|
ipStrategy:
|
||||||
|
description: 'IPStrategy holds the IP strategy configuration used
|
||||||
|
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -773,7 +802,7 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration
|
description: 'IPStrategy holds the IP strategy configuration
|
||||||
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
|
|
@ -45,8 +45,22 @@ spec:
|
||||||
format: int64
|
format: int64
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
ipAllowList:
|
||||||
|
description: 'IPAllowList defines the IPAllowList middleware configuration.
|
||||||
|
This middleware accepts/refuses connections based on the client
|
||||||
|
IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipallowlist/'
|
||||||
|
properties:
|
||||||
|
sourceRange:
|
||||||
|
description: SourceRange defines the allowed IPs (or ranges of
|
||||||
|
allowed IPs by using CIDR notation).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
ipWhiteList:
|
ipWhiteList:
|
||||||
description: IPWhiteList defines the IPWhiteList middleware configuration.
|
description: 'IPWhiteList defines the IPWhiteList middleware configuration.
|
||||||
|
This middleware accepts/refuses connections based on the client
|
||||||
|
IP. Deprecated: please use IPAllowList instead. More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipwhitelist/'
|
||||||
properties:
|
properties:
|
||||||
sourceRange:
|
sourceRange:
|
||||||
description: SourceRange defines the allowed IPs (or ranges of
|
description: SourceRange defines the allowed IPs (or ranges of
|
||||||
|
|
|
@ -124,7 +124,8 @@ nav:
|
||||||
- 'Errors': 'middlewares/http/errorpages.md'
|
- 'Errors': 'middlewares/http/errorpages.md'
|
||||||
- 'ForwardAuth': 'middlewares/http/forwardauth.md'
|
- 'ForwardAuth': 'middlewares/http/forwardauth.md'
|
||||||
- 'Headers': 'middlewares/http/headers.md'
|
- 'Headers': 'middlewares/http/headers.md'
|
||||||
- 'IpWhitelist': 'middlewares/http/ipwhitelist.md'
|
- 'IPWhiteList': 'middlewares/http/ipwhitelist.md'
|
||||||
|
- 'IPAllowList': 'middlewares/http/ipallowlist.md'
|
||||||
- 'InFlightReq': 'middlewares/http/inflightreq.md'
|
- 'InFlightReq': 'middlewares/http/inflightreq.md'
|
||||||
- 'PassTLSClientCert': 'middlewares/http/passtlsclientcert.md'
|
- 'PassTLSClientCert': 'middlewares/http/passtlsclientcert.md'
|
||||||
- 'RateLimit': 'middlewares/http/ratelimit.md'
|
- 'RateLimit': 'middlewares/http/ratelimit.md'
|
||||||
|
@ -138,7 +139,8 @@ nav:
|
||||||
- 'TCP':
|
- 'TCP':
|
||||||
- 'Overview': 'middlewares/tcp/overview.md'
|
- 'Overview': 'middlewares/tcp/overview.md'
|
||||||
- 'InFlightConn': 'middlewares/tcp/inflightconn.md'
|
- 'InFlightConn': 'middlewares/tcp/inflightconn.md'
|
||||||
- 'IpWhitelist': 'middlewares/tcp/ipwhitelist.md'
|
- 'IPWhiteList': 'middlewares/tcp/ipwhitelist.md'
|
||||||
|
- 'IPAllowList': 'middlewares/tcp/ipallowlist.md'
|
||||||
- 'Plugins & Plugin Catalog': 'plugins/index.md'
|
- 'Plugins & Plugin Catalog': 'plugins/index.md'
|
||||||
- 'Operations':
|
- 'Operations':
|
||||||
- 'CLI': 'operations/cli.md'
|
- 'CLI': 'operations/cli.md'
|
||||||
|
|
|
@ -1151,7 +1151,7 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration
|
description: 'IPStrategy holds the IP strategy configuration
|
||||||
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -1176,14 +1176,43 @@ spec:
|
||||||
type: boolean
|
type: boolean
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
ipWhiteList:
|
ipAllowList:
|
||||||
description: 'IPWhiteList holds the IP whitelist middleware configuration.
|
description: 'IPAllowList holds the IP allowlist middleware configuration.
|
||||||
This middleware accepts / refuses requests based on the client IP.
|
This middleware accepts / refuses requests based on the client IP.
|
||||||
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/'
|
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/'
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration used
|
description: 'IPStrategy holds the IP strategy configuration used
|
||||||
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
|
properties:
|
||||||
|
depth:
|
||||||
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
header and take the IP located at the depth position (starting
|
||||||
|
from the right).
|
||||||
|
type: integer
|
||||||
|
excludedIPs:
|
||||||
|
description: ExcludedIPs configures Traefik to scan the X-Forwarded-For
|
||||||
|
header and select the first IP not in the list.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
sourceRange:
|
||||||
|
description: SourceRange defines the set of allowed IPs (or ranges
|
||||||
|
of allowed IPs by using CIDR notation).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
ipWhiteList:
|
||||||
|
description: 'IPWhiteList holds the IP whitelist middleware configuration.
|
||||||
|
This middleware accepts / refuses requests based on the client IP.
|
||||||
|
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/
|
||||||
|
Deprecated: please use IPAllowList instead.'
|
||||||
|
properties:
|
||||||
|
ipStrategy:
|
||||||
|
description: 'IPStrategy holds the IP strategy configuration used
|
||||||
|
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -1347,7 +1376,7 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration
|
description: 'IPStrategy holds the IP strategy configuration
|
||||||
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -1535,8 +1564,22 @@ spec:
|
||||||
format: int64
|
format: int64
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
ipAllowList:
|
||||||
|
description: 'IPAllowList defines the IPAllowList middleware configuration.
|
||||||
|
This middleware accepts/refuses connections based on the client
|
||||||
|
IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipallowlist/'
|
||||||
|
properties:
|
||||||
|
sourceRange:
|
||||||
|
description: SourceRange defines the allowed IPs (or ranges of
|
||||||
|
allowed IPs by using CIDR notation).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
ipWhiteList:
|
ipWhiteList:
|
||||||
description: IPWhiteList defines the IPWhiteList middleware configuration.
|
description: 'IPWhiteList defines the IPWhiteList middleware configuration.
|
||||||
|
This middleware accepts/refuses connections based on the client
|
||||||
|
IP. Deprecated: please use IPAllowList instead. More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipwhitelist/'
|
||||||
properties:
|
properties:
|
||||||
sourceRange:
|
sourceRange:
|
||||||
description: SourceRange defines the allowed IPs (or ranges of
|
description: SourceRange defines the allowed IPs (or ranges of
|
||||||
|
@ -3415,7 +3458,7 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration
|
description: 'IPStrategy holds the IP strategy configuration
|
||||||
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -3440,14 +3483,43 @@ spec:
|
||||||
type: boolean
|
type: boolean
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
ipWhiteList:
|
ipAllowList:
|
||||||
description: 'IPWhiteList holds the IP whitelist middleware configuration.
|
description: 'IPAllowList holds the IP allowlist middleware configuration.
|
||||||
This middleware accepts / refuses requests based on the client IP.
|
This middleware accepts / refuses requests based on the client IP.
|
||||||
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/'
|
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/'
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration used
|
description: 'IPStrategy holds the IP strategy configuration used
|
||||||
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
|
properties:
|
||||||
|
depth:
|
||||||
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
header and take the IP located at the depth position (starting
|
||||||
|
from the right).
|
||||||
|
type: integer
|
||||||
|
excludedIPs:
|
||||||
|
description: ExcludedIPs configures Traefik to scan the X-Forwarded-For
|
||||||
|
header and select the first IP not in the list.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
sourceRange:
|
||||||
|
description: SourceRange defines the set of allowed IPs (or ranges
|
||||||
|
of allowed IPs by using CIDR notation).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
ipWhiteList:
|
||||||
|
description: 'IPWhiteList holds the IP whitelist middleware configuration.
|
||||||
|
This middleware accepts / refuses requests based on the client IP.
|
||||||
|
More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/
|
||||||
|
Deprecated: please use IPAllowList instead.'
|
||||||
|
properties:
|
||||||
|
ipStrategy:
|
||||||
|
description: 'IPStrategy holds the IP strategy configuration used
|
||||||
|
by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -3611,7 +3683,7 @@ spec:
|
||||||
properties:
|
properties:
|
||||||
ipStrategy:
|
ipStrategy:
|
||||||
description: 'IPStrategy holds the IP strategy configuration
|
description: 'IPStrategy holds the IP strategy configuration
|
||||||
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy'
|
used by Traefik to determine the client IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy'
|
||||||
properties:
|
properties:
|
||||||
depth:
|
depth:
|
||||||
description: Depth tells Traefik to use the X-Forwarded-For
|
description: Depth tells Traefik to use the X-Forwarded-For
|
||||||
|
@ -3799,8 +3871,22 @@ spec:
|
||||||
format: int64
|
format: int64
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
ipAllowList:
|
||||||
|
description: 'IPAllowList defines the IPAllowList middleware configuration.
|
||||||
|
This middleware accepts/refuses connections based on the client
|
||||||
|
IP. More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipallowlist/'
|
||||||
|
properties:
|
||||||
|
sourceRange:
|
||||||
|
description: SourceRange defines the allowed IPs (or ranges of
|
||||||
|
allowed IPs by using CIDR notation).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
ipWhiteList:
|
ipWhiteList:
|
||||||
description: IPWhiteList defines the IPWhiteList middleware configuration.
|
description: 'IPWhiteList defines the IPWhiteList middleware configuration.
|
||||||
|
This middleware accepts/refuses connections based on the client
|
||||||
|
IP. Deprecated: please use IPAllowList instead. More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipwhitelist/'
|
||||||
properties:
|
properties:
|
||||||
sourceRange:
|
sourceRange:
|
||||||
description: SourceRange defines the allowed IPs (or ranges of
|
description: SourceRange defines the allowed IPs (or ranges of
|
||||||
|
|
18
integration/fixtures/simple_allowlist.toml
Normal file
18
integration/fixtures/simple_allowlist.toml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
[global]
|
||||||
|
checkNewVersion = false
|
||||||
|
sendAnonymousUsage = false
|
||||||
|
|
||||||
|
[log]
|
||||||
|
level = "DEBUG"
|
||||||
|
|
||||||
|
[entryPoints]
|
||||||
|
[entryPoints.web]
|
||||||
|
address = ":8000"
|
||||||
|
[entryPoints.web.ForwardedHeaders]
|
||||||
|
insecure = true
|
||||||
|
|
||||||
|
[api]
|
||||||
|
insecure = true
|
||||||
|
|
||||||
|
[providers]
|
||||||
|
[providers.docker]
|
41
integration/resources/compose/allowlist.yml
Normal file
41
integration/resources/compose/allowlist.yml
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
version: "3.8"
|
||||||
|
services:
|
||||||
|
noOverrideAllowlist:
|
||||||
|
image: traefik/whoami
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.rt1.rule: Host(`no.override.allowlist.docker.local`)
|
||||||
|
traefik.http.routers.rt1.middlewares: wl1
|
||||||
|
traefik.http.middlewares.wl1.ipallowlist.sourceRange: 8.8.8.8
|
||||||
|
|
||||||
|
overrideIPStrategyRemoteAddrAllowlist:
|
||||||
|
image: traefik/whoami
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.rt2.rule: Host(`override.remoteaddr.allowlist.docker.local`)
|
||||||
|
traefik.http.routers.rt2.middlewares: wl2
|
||||||
|
traefik.http.middlewares.wl2.ipallowlist.sourceRange: 8.8.8.8
|
||||||
|
traefik.http.middlewares.wl2.ipallowlist.ipStrategy: true
|
||||||
|
|
||||||
|
overrideIPStrategyDepthAllowlist:
|
||||||
|
image: traefik/whoami
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.rt3.rule: Host(`override.depth.allowlist.docker.local`)
|
||||||
|
traefik.http.routers.rt3.middlewares: wl3
|
||||||
|
traefik.http.middlewares.wl3.ipallowlist.sourceRange: 8.8.8.8
|
||||||
|
traefik.http.middlewares.wl3.ipallowlist.ipStrategy.depth: 3
|
||||||
|
|
||||||
|
overrideIPStrategyExcludedIPsAllowlist:
|
||||||
|
image: traefik/whoami
|
||||||
|
labels:
|
||||||
|
traefik.enable: true
|
||||||
|
traefik.http.routers.rt4.rule: Host(`override.excludedips.allowlist.docker.local`)
|
||||||
|
traefik.http.routers.rt4.middlewares: wl4
|
||||||
|
traefik.http.middlewares.wl4.ipallowlist.sourceRange: 8.8.8.8
|
||||||
|
traefik.http.middlewares.wl4.ipallowlist.ipStrategy.excludedIPs: 10.0.0.1,10.0.0.2
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
name: traefik-test-network
|
||||||
|
external: true
|
|
@ -546,6 +546,76 @@ func (s *SimpleSuite) TestIPStrategyWhitelist(c *check.C) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SimpleSuite) TestIPStrategyAllowlist(c *check.C) {
|
||||||
|
s.createComposeProject(c, "allowlist")
|
||||||
|
|
||||||
|
s.composeUp(c)
|
||||||
|
defer s.composeDown(c)
|
||||||
|
|
||||||
|
cmd, output := s.traefikCmd(withConfigFile("fixtures/simple_allowlist.toml"))
|
||||||
|
defer output(c)
|
||||||
|
|
||||||
|
err := cmd.Start()
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
defer s.killCmd(cmd)
|
||||||
|
|
||||||
|
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second, try.BodyContains("override"))
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second, try.BodyContains("override.remoteaddr.allowlist.docker.local"))
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
xForwardedFor string
|
||||||
|
host string
|
||||||
|
expectedStatusCode int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "override remote addr reject",
|
||||||
|
xForwardedFor: "8.8.8.8,8.8.8.8",
|
||||||
|
host: "override.remoteaddr.allowlist.docker.local",
|
||||||
|
expectedStatusCode: 403,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "override depth accept",
|
||||||
|
xForwardedFor: "8.8.8.8,10.0.0.1,127.0.0.1",
|
||||||
|
host: "override.depth.allowlist.docker.local",
|
||||||
|
expectedStatusCode: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "override depth reject",
|
||||||
|
xForwardedFor: "10.0.0.1,8.8.8.8,127.0.0.1",
|
||||||
|
host: "override.depth.allowlist.docker.local",
|
||||||
|
expectedStatusCode: 403,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "override excludedIPs reject",
|
||||||
|
xForwardedFor: "10.0.0.3,10.0.0.1,10.0.0.2",
|
||||||
|
host: "override.excludedips.allowlist.docker.local",
|
||||||
|
expectedStatusCode: 403,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "override excludedIPs accept",
|
||||||
|
xForwardedFor: "8.8.8.8,10.0.0.1,10.0.0.2",
|
||||||
|
host: "override.excludedips.allowlist.docker.local",
|
||||||
|
expectedStatusCode: 200,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
req := httptest.NewRequest(http.MethodGet, "http://127.0.0.1:8000", nil)
|
||||||
|
req.Header.Set("X-Forwarded-For", test.xForwardedFor)
|
||||||
|
req.Host = test.host
|
||||||
|
req.RequestURI = ""
|
||||||
|
|
||||||
|
err = try.Request(req, 1*time.Second, try.StatusCodeIs(test.expectedStatusCode))
|
||||||
|
if err != nil {
|
||||||
|
c.Fatalf("Error while %s: %v", test.desc, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SimpleSuite) TestXForwardedHeaders(c *check.C) {
|
func (s *SimpleSuite) TestXForwardedHeaders(c *check.C) {
|
||||||
s.createComposeProject(c, "whitelist")
|
s.createComposeProject(c, "whitelist")
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ type Middleware struct {
|
||||||
ReplacePathRegex *ReplacePathRegex `json:"replacePathRegex,omitempty" toml:"replacePathRegex,omitempty" yaml:"replacePathRegex,omitempty" export:"true"`
|
ReplacePathRegex *ReplacePathRegex `json:"replacePathRegex,omitempty" toml:"replacePathRegex,omitempty" yaml:"replacePathRegex,omitempty" export:"true"`
|
||||||
Chain *Chain `json:"chain,omitempty" toml:"chain,omitempty" yaml:"chain,omitempty" export:"true"`
|
Chain *Chain `json:"chain,omitempty" toml:"chain,omitempty" yaml:"chain,omitempty" export:"true"`
|
||||||
IPWhiteList *IPWhiteList `json:"ipWhiteList,omitempty" toml:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty" export:"true"`
|
IPWhiteList *IPWhiteList `json:"ipWhiteList,omitempty" toml:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty" export:"true"`
|
||||||
|
IPAllowList *IPAllowList `json:"ipAllowList,omitempty" toml:"ipAllowList,omitempty" yaml:"ipAllowList,omitempty" export:"true"`
|
||||||
Headers *Headers `json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty" export:"true"`
|
Headers *Headers `json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty" export:"true"`
|
||||||
Errors *ErrorPage `json:"errors,omitempty" toml:"errors,omitempty" yaml:"errors,omitempty" export:"true"`
|
Errors *ErrorPage `json:"errors,omitempty" toml:"errors,omitempty" yaml:"errors,omitempty" export:"true"`
|
||||||
RateLimit *RateLimit `json:"rateLimit,omitempty" toml:"rateLimit,omitempty" yaml:"rateLimit,omitempty" export:"true"`
|
RateLimit *RateLimit `json:"rateLimit,omitempty" toml:"rateLimit,omitempty" yaml:"rateLimit,omitempty" export:"true"`
|
||||||
|
@ -346,7 +347,7 @@ func (h *Headers) HasSecureHeadersDefined() bool {
|
||||||
// +k8s:deepcopy-gen=true
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
// IPStrategy holds the IP strategy configuration used by Traefik to determine the client IP.
|
// IPStrategy holds the IP strategy configuration used by Traefik to determine the client IP.
|
||||||
// More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/#ipstrategy
|
// More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/#ipstrategy
|
||||||
type IPStrategy struct {
|
type IPStrategy struct {
|
||||||
// Depth tells Traefik to use the X-Forwarded-For header and take the IP located at the depth position (starting from the right).
|
// Depth tells Traefik to use the X-Forwarded-For header and take the IP located at the depth position (starting from the right).
|
||||||
Depth int `json:"depth,omitempty" toml:"depth,omitempty" yaml:"depth,omitempty" export:"true"`
|
Depth int `json:"depth,omitempty" toml:"depth,omitempty" yaml:"depth,omitempty" export:"true"`
|
||||||
|
@ -388,6 +389,7 @@ func (s *IPStrategy) Get() (ip.Strategy, error) {
|
||||||
// IPWhiteList holds the IP whitelist middleware configuration.
|
// IPWhiteList holds the IP whitelist middleware configuration.
|
||||||
// This middleware accepts / refuses requests based on the client IP.
|
// This middleware accepts / refuses requests based on the client IP.
|
||||||
// More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/
|
// More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipwhitelist/
|
||||||
|
// Deprecated: please use IPAllowList instead.
|
||||||
type IPWhiteList struct {
|
type IPWhiteList struct {
|
||||||
// SourceRange defines the set of allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
// SourceRange defines the set of allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
||||||
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
|
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
|
||||||
|
@ -396,6 +398,17 @@ type IPWhiteList struct {
|
||||||
|
|
||||||
// +k8s:deepcopy-gen=true
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
|
// IPAllowList holds the IP allowlist middleware configuration.
|
||||||
|
// This middleware accepts / refuses requests based on the client IP.
|
||||||
|
// More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/ipallowlist/
|
||||||
|
type IPAllowList struct {
|
||||||
|
// SourceRange defines the set of allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
||||||
|
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
|
||||||
|
IPStrategy *IPStrategy `json:"ipStrategy,omitempty" toml:"ipStrategy,omitempty" yaml:"ipStrategy,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
// InFlightReq holds the in-flight request middleware configuration.
|
// InFlightReq holds the in-flight request middleware configuration.
|
||||||
// This middleware limits the number of requests being processed and served concurrently.
|
// This middleware limits the number of requests being processed and served concurrently.
|
||||||
// More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/inflightreq/
|
// More info: https://doc.traefik.io/traefik/v2.10/middlewares/http/inflightreq/
|
||||||
|
|
|
@ -6,6 +6,7 @@ package dynamic
|
||||||
type TCPMiddleware struct {
|
type TCPMiddleware struct {
|
||||||
InFlightConn *TCPInFlightConn `json:"inFlightConn,omitempty" toml:"inFlightConn,omitempty" yaml:"inFlightConn,omitempty" export:"true"`
|
InFlightConn *TCPInFlightConn `json:"inFlightConn,omitempty" toml:"inFlightConn,omitempty" yaml:"inFlightConn,omitempty" export:"true"`
|
||||||
IPWhiteList *TCPIPWhiteList `json:"ipWhiteList,omitempty" toml:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty" export:"true"`
|
IPWhiteList *TCPIPWhiteList `json:"ipWhiteList,omitempty" toml:"ipWhiteList,omitempty" yaml:"ipWhiteList,omitempty" export:"true"`
|
||||||
|
IPAllowList *TCPIPAllowList `json:"ipAllowList,omitempty" toml:"ipAllowList,omitempty" yaml:"ipAllowList,omitempty" export:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen=true
|
// +k8s:deepcopy-gen=true
|
||||||
|
@ -23,8 +24,15 @@ type TCPInFlightConn struct {
|
||||||
// +k8s:deepcopy-gen=true
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
// TCPIPWhiteList holds the TCP IPWhiteList middleware configuration.
|
// TCPIPWhiteList holds the TCP IPWhiteList middleware configuration.
|
||||||
// This middleware accepts/refuses connections based on the client IP.
|
|
||||||
type TCPIPWhiteList struct {
|
type TCPIPWhiteList struct {
|
||||||
// SourceRange defines the allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
// SourceRange defines the allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
||||||
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
|
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
||||||
|
// TCPIPAllowList holds the TCP IPAllowList middleware configuration.
|
||||||
|
type TCPIPAllowList struct {
|
||||||
|
// SourceRange defines the allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
||||||
|
SourceRange []string `json:"sourceRange,omitempty" toml:"sourceRange,omitempty" yaml:"sourceRange,omitempty"`
|
||||||
|
}
|
||||||
|
|
|
@ -532,6 +532,32 @@ func (in *HealthCheck) DeepCopy() *HealthCheck {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *IPAllowList) DeepCopyInto(out *IPAllowList) {
|
||||||
|
*out = *in
|
||||||
|
if in.SourceRange != nil {
|
||||||
|
in, out := &in.SourceRange, &out.SourceRange
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
if in.IPStrategy != nil {
|
||||||
|
in, out := &in.IPStrategy, &out.IPStrategy
|
||||||
|
*out = new(IPStrategy)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAllowList.
|
||||||
|
func (in *IPAllowList) DeepCopy() *IPAllowList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(IPAllowList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *IPStrategy) DeepCopyInto(out *IPStrategy) {
|
func (in *IPStrategy) DeepCopyInto(out *IPStrategy) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
@ -659,6 +685,11 @@ func (in *Middleware) DeepCopyInto(out *Middleware) {
|
||||||
*out = new(IPWhiteList)
|
*out = new(IPWhiteList)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.IPAllowList != nil {
|
||||||
|
in, out := &in.IPAllowList, &out.IPAllowList
|
||||||
|
*out = new(IPAllowList)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.Headers != nil {
|
if in.Headers != nil {
|
||||||
in, out := &in.Headers, &out.Headers
|
in, out := &in.Headers, &out.Headers
|
||||||
*out = new(Headers)
|
*out = new(Headers)
|
||||||
|
@ -1355,6 +1386,27 @@ func (in *TCPConfiguration) DeepCopy() *TCPConfiguration {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *TCPIPAllowList) DeepCopyInto(out *TCPIPAllowList) {
|
||||||
|
*out = *in
|
||||||
|
if in.SourceRange != nil {
|
||||||
|
in, out := &in.SourceRange, &out.SourceRange
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPIPAllowList.
|
||||||
|
func (in *TCPIPAllowList) DeepCopy() *TCPIPAllowList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(TCPIPAllowList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *TCPIPWhiteList) DeepCopyInto(out *TCPIPWhiteList) {
|
func (in *TCPIPWhiteList) DeepCopyInto(out *TCPIPWhiteList) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
@ -1405,6 +1457,11 @@ func (in *TCPMiddleware) DeepCopyInto(out *TCPMiddleware) {
|
||||||
*out = new(TCPIPWhiteList)
|
*out = new(TCPIPWhiteList)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.IPAllowList != nil {
|
||||||
|
in, out := &in.IPAllowList, &out.IPAllowList
|
||||||
|
*out = new(TCPIPAllowList)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
88
pkg/middlewares/ipallowlist/ip_allowlist.go
Normal file
88
pkg/middlewares/ipallowlist/ip_allowlist.go
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
package ipallowlist
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/opentracing/opentracing-go/ext"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/ip"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/log"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/middlewares"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/tracing"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
typeName = "IPAllowLister"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ipAllowLister is a middleware that provides Checks of the Requesting IP against a set of Allowlists.
|
||||||
|
type ipAllowLister struct {
|
||||||
|
next http.Handler
|
||||||
|
allowLister *ip.Checker
|
||||||
|
strategy ip.Strategy
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// New builds a new IPAllowLister given a list of CIDR-Strings to allow.
|
||||||
|
func New(ctx context.Context, next http.Handler, config dynamic.IPAllowList, name string) (http.Handler, error) {
|
||||||
|
logger := log.FromContext(middlewares.GetLoggerCtx(ctx, name, typeName))
|
||||||
|
logger.Debug("Creating middleware")
|
||||||
|
|
||||||
|
if len(config.SourceRange) == 0 {
|
||||||
|
return nil, errors.New("sourceRange is empty, IPAllowLister not created")
|
||||||
|
}
|
||||||
|
|
||||||
|
checker, err := ip.NewChecker(config.SourceRange)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot parse CIDRs %s: %w", config.SourceRange, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
strategy, err := config.IPStrategy.Get()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debugf("Setting up IPAllowLister with sourceRange: %s", config.SourceRange)
|
||||||
|
|
||||||
|
return &ipAllowLister{
|
||||||
|
strategy: strategy,
|
||||||
|
allowLister: checker,
|
||||||
|
next: next,
|
||||||
|
name: name,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (al *ipAllowLister) GetTracingInformation() (string, ext.SpanKindEnum) {
|
||||||
|
return al.name, tracing.SpanKindNoneEnum
|
||||||
|
}
|
||||||
|
|
||||||
|
func (al *ipAllowLister) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
ctx := middlewares.GetLoggerCtx(req.Context(), al.name, typeName)
|
||||||
|
logger := log.FromContext(ctx)
|
||||||
|
|
||||||
|
clientIP := al.strategy.GetIP(req)
|
||||||
|
err := al.allowLister.IsAuthorized(clientIP)
|
||||||
|
if err != nil {
|
||||||
|
msg := fmt.Sprintf("Rejecting IP %s: %v", clientIP, err)
|
||||||
|
logger.Debug(msg)
|
||||||
|
tracing.SetErrorWithEvent(req, msg)
|
||||||
|
reject(ctx, rw)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logger.Debugf("Accepting IP %s", clientIP)
|
||||||
|
|
||||||
|
al.next.ServeHTTP(rw, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func reject(ctx context.Context, rw http.ResponseWriter) {
|
||||||
|
statusCode := http.StatusForbidden
|
||||||
|
|
||||||
|
rw.WriteHeader(statusCode)
|
||||||
|
_, err := rw.Write([]byte(http.StatusText(statusCode)))
|
||||||
|
if err != nil {
|
||||||
|
log.FromContext(ctx).Error(err)
|
||||||
|
}
|
||||||
|
}
|
100
pkg/middlewares/ipallowlist/ip_allowlist_test.go
Normal file
100
pkg/middlewares/ipallowlist/ip_allowlist_test.go
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
package ipallowlist
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewIPAllowLister(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
allowList dynamic.IPAllowList
|
||||||
|
expectedError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "invalid IP",
|
||||||
|
allowList: dynamic.IPAllowList{
|
||||||
|
SourceRange: []string{"foo"},
|
||||||
|
},
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "valid IP",
|
||||||
|
allowList: dynamic.IPAllowList{
|
||||||
|
SourceRange: []string{"10.10.10.10"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||||||
|
allowLister, err := New(context.Background(), next, test.allowList, "traefikTest")
|
||||||
|
|
||||||
|
if test.expectedError {
|
||||||
|
assert.Error(t, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotNil(t, allowLister)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIPAllowLister_ServeHTTP(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
allowList dynamic.IPAllowList
|
||||||
|
remoteAddr string
|
||||||
|
expected int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "authorized with remote address",
|
||||||
|
allowList: dynamic.IPAllowList{
|
||||||
|
SourceRange: []string{"20.20.20.20"},
|
||||||
|
},
|
||||||
|
remoteAddr: "20.20.20.20:1234",
|
||||||
|
expected: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "non authorized with remote address",
|
||||||
|
allowList: dynamic.IPAllowList{
|
||||||
|
SourceRange: []string{"20.20.20.20"},
|
||||||
|
},
|
||||||
|
remoteAddr: "20.20.20.21:1234",
|
||||||
|
expected: 403,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
|
||||||
|
allowLister, err := New(context.Background(), next, test.allowList, "traefikTest")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
|
req := httptest.NewRequest(http.MethodGet, "http://10.10.10.10", nil)
|
||||||
|
|
||||||
|
if len(test.remoteAddr) > 0 {
|
||||||
|
req.RemoteAddr = test.remoteAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
allowLister.ServeHTTP(recorder, req)
|
||||||
|
|
||||||
|
assert.Equal(t, test.expected, recorder.Code)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
65
pkg/middlewares/tcp/ipallowlist/ip_allowlist.go
Normal file
65
pkg/middlewares/tcp/ipallowlist/ip_allowlist.go
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
package ipallowlist
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/ip"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/log"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/middlewares"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/tcp"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
typeName = "IPAllowListerTCP"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ipAllowLister is a middleware that provides Checks of the Requesting IP against a set of Allowlists.
|
||||||
|
type ipAllowLister struct {
|
||||||
|
next tcp.Handler
|
||||||
|
allowLister *ip.Checker
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// New builds a new TCP IPAllowLister given a list of CIDR-Strings to allow.
|
||||||
|
func New(ctx context.Context, next tcp.Handler, config dynamic.TCPIPAllowList, name string) (tcp.Handler, error) {
|
||||||
|
logger := log.FromContext(middlewares.GetLoggerCtx(ctx, name, typeName))
|
||||||
|
logger.Debug("Creating middleware")
|
||||||
|
|
||||||
|
if len(config.SourceRange) == 0 {
|
||||||
|
return nil, errors.New("sourceRange is empty, IPAllowLister not created")
|
||||||
|
}
|
||||||
|
|
||||||
|
checker, err := ip.NewChecker(config.SourceRange)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot parse CIDRs %s: %w", config.SourceRange, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debugf("Setting up IPAllowLister with sourceRange: %s", config.SourceRange)
|
||||||
|
|
||||||
|
return &ipAllowLister{
|
||||||
|
allowLister: checker,
|
||||||
|
next: next,
|
||||||
|
name: name,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (al *ipAllowLister) ServeTCP(conn tcp.WriteCloser) {
|
||||||
|
ctx := middlewares.GetLoggerCtx(context.Background(), al.name, typeName)
|
||||||
|
logger := log.FromContext(ctx)
|
||||||
|
|
||||||
|
addr := conn.RemoteAddr().String()
|
||||||
|
|
||||||
|
err := al.allowLister.IsAuthorized(addr)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Connection from %s rejected: %v", addr, err)
|
||||||
|
conn.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debugf("Connection from %s accepted", addr)
|
||||||
|
|
||||||
|
al.next.ServeTCP(conn)
|
||||||
|
}
|
139
pkg/middlewares/tcp/ipallowlist/ip_allowlist_test.go
Normal file
139
pkg/middlewares/tcp/ipallowlist/ip_allowlist_test.go
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
package ipallowlist
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/tcp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewIPAllowLister(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
allowList dynamic.TCPIPAllowList
|
||||||
|
expectedError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "Empty config",
|
||||||
|
allowList: dynamic.TCPIPAllowList{},
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "invalid IP",
|
||||||
|
allowList: dynamic.TCPIPAllowList{
|
||||||
|
SourceRange: []string{"foo"},
|
||||||
|
},
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "valid IP",
|
||||||
|
allowList: dynamic.TCPIPAllowList{
|
||||||
|
SourceRange: []string{"10.10.10.10"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
next := tcp.HandlerFunc(func(conn tcp.WriteCloser) {})
|
||||||
|
allowLister, err := New(context.Background(), next, test.allowList, "traefikTest")
|
||||||
|
|
||||||
|
if test.expectedError {
|
||||||
|
assert.Error(t, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotNil(t, allowLister)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIPAllowLister_ServeHTTP(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
allowList dynamic.TCPIPAllowList
|
||||||
|
remoteAddr string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "authorized with remote address",
|
||||||
|
allowList: dynamic.TCPIPAllowList{
|
||||||
|
SourceRange: []string{"20.20.20.20"},
|
||||||
|
},
|
||||||
|
remoteAddr: "20.20.20.20:1234",
|
||||||
|
expected: "OK",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "non authorized with remote address",
|
||||||
|
allowList: dynamic.TCPIPAllowList{
|
||||||
|
SourceRange: []string{"20.20.20.20"},
|
||||||
|
},
|
||||||
|
remoteAddr: "20.20.20.21:1234",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
next := tcp.HandlerFunc(func(conn tcp.WriteCloser) {
|
||||||
|
write, err := conn.Write([]byte("OK"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, 2, write)
|
||||||
|
|
||||||
|
err = conn.Close()
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
allowLister, err := New(context.Background(), next, test.allowList, "traefikTest")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
server, client := net.Pipe()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
allowLister.ServeTCP(&contextWriteCloser{client, addr{test.remoteAddr}})
|
||||||
|
}()
|
||||||
|
|
||||||
|
read, err := io.ReadAll(server)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, test.expected, string(read))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type contextWriteCloser struct {
|
||||||
|
net.Conn
|
||||||
|
addr
|
||||||
|
}
|
||||||
|
|
||||||
|
type addr struct {
|
||||||
|
remoteAddr string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a addr) Network() string {
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a addr) String() string {
|
||||||
|
return a.remoteAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c contextWriteCloser) CloseWrite() error {
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c contextWriteCloser) RemoteAddr() net.Addr { return c.addr }
|
||||||
|
|
||||||
|
func (c contextWriteCloser) Context() context.Context {
|
||||||
|
return context.Background()
|
||||||
|
}
|
|
@ -288,6 +288,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
||||||
ReplacePathRegex: middleware.Spec.ReplacePathRegex,
|
ReplacePathRegex: middleware.Spec.ReplacePathRegex,
|
||||||
Chain: createChainMiddleware(ctxMid, middleware.Namespace, middleware.Spec.Chain),
|
Chain: createChainMiddleware(ctxMid, middleware.Namespace, middleware.Spec.Chain),
|
||||||
IPWhiteList: middleware.Spec.IPWhiteList,
|
IPWhiteList: middleware.Spec.IPWhiteList,
|
||||||
|
IPAllowList: middleware.Spec.IPAllowList,
|
||||||
Headers: middleware.Spec.Headers,
|
Headers: middleware.Spec.Headers,
|
||||||
Errors: errorPage,
|
Errors: errorPage,
|
||||||
RateLimit: rateLimit,
|
RateLimit: rateLimit,
|
||||||
|
@ -313,6 +314,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
||||||
conf.TCP.Middlewares[id] = &dynamic.TCPMiddleware{
|
conf.TCP.Middlewares[id] = &dynamic.TCPMiddleware{
|
||||||
InFlightConn: middlewareTCP.Spec.InFlightConn,
|
InFlightConn: middlewareTCP.Spec.InFlightConn,
|
||||||
IPWhiteList: middlewareTCP.Spec.IPWhiteList,
|
IPWhiteList: middlewareTCP.Spec.IPWhiteList,
|
||||||
|
IPAllowList: middlewareTCP.Spec.IPAllowList,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ type MiddlewareSpec struct {
|
||||||
ReplacePathRegex *dynamic.ReplacePathRegex `json:"replacePathRegex,omitempty"`
|
ReplacePathRegex *dynamic.ReplacePathRegex `json:"replacePathRegex,omitempty"`
|
||||||
Chain *Chain `json:"chain,omitempty"`
|
Chain *Chain `json:"chain,omitempty"`
|
||||||
IPWhiteList *dynamic.IPWhiteList `json:"ipWhiteList,omitempty"`
|
IPWhiteList *dynamic.IPWhiteList `json:"ipWhiteList,omitempty"`
|
||||||
|
IPAllowList *dynamic.IPAllowList `json:"ipAllowList,omitempty"`
|
||||||
Headers *dynamic.Headers `json:"headers,omitempty"`
|
Headers *dynamic.Headers `json:"headers,omitempty"`
|
||||||
Errors *ErrorPage `json:"errors,omitempty"`
|
Errors *ErrorPage `json:"errors,omitempty"`
|
||||||
RateLimit *RateLimit `json:"rateLimit,omitempty"`
|
RateLimit *RateLimit `json:"rateLimit,omitempty"`
|
||||||
|
|
|
@ -26,7 +26,14 @@ type MiddlewareTCPSpec struct {
|
||||||
// InFlightConn defines the InFlightConn middleware configuration.
|
// InFlightConn defines the InFlightConn middleware configuration.
|
||||||
InFlightConn *dynamic.TCPInFlightConn `json:"inFlightConn,omitempty"`
|
InFlightConn *dynamic.TCPInFlightConn `json:"inFlightConn,omitempty"`
|
||||||
// IPWhiteList defines the IPWhiteList middleware configuration.
|
// IPWhiteList defines the IPWhiteList middleware configuration.
|
||||||
|
// This middleware accepts/refuses connections based on the client IP.
|
||||||
|
// Deprecated: please use IPAllowList instead.
|
||||||
|
// More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipwhitelist/
|
||||||
IPWhiteList *dynamic.TCPIPWhiteList `json:"ipWhiteList,omitempty"`
|
IPWhiteList *dynamic.TCPIPWhiteList `json:"ipWhiteList,omitempty"`
|
||||||
|
// IPAllowList defines the IPAllowList middleware configuration.
|
||||||
|
// This middleware accepts/refuses connections based on the client IP.
|
||||||
|
// More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipallowlist/
|
||||||
|
IPAllowList *dynamic.TCPIPAllowList `json:"ipAllowList,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
|
@ -694,6 +694,11 @@ func (in *MiddlewareSpec) DeepCopyInto(out *MiddlewareSpec) {
|
||||||
*out = new(dynamic.IPWhiteList)
|
*out = new(dynamic.IPWhiteList)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.IPAllowList != nil {
|
||||||
|
in, out := &in.IPAllowList, &out.IPAllowList
|
||||||
|
*out = new(dynamic.IPAllowList)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.Headers != nil {
|
if in.Headers != nil {
|
||||||
in, out := &in.Headers, &out.Headers
|
in, out := &in.Headers, &out.Headers
|
||||||
*out = new(dynamic.Headers)
|
*out = new(dynamic.Headers)
|
||||||
|
@ -862,6 +867,11 @@ func (in *MiddlewareTCPSpec) DeepCopyInto(out *MiddlewareTCPSpec) {
|
||||||
*out = new(dynamic.TCPIPWhiteList)
|
*out = new(dynamic.TCPIPWhiteList)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.IPAllowList != nil {
|
||||||
|
in, out := &in.IPAllowList, &out.IPAllowList
|
||||||
|
*out = new(dynamic.TCPIPAllowList)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ type MiddlewareSpec struct {
|
||||||
ReplacePathRegex *dynamic.ReplacePathRegex `json:"replacePathRegex,omitempty"`
|
ReplacePathRegex *dynamic.ReplacePathRegex `json:"replacePathRegex,omitempty"`
|
||||||
Chain *Chain `json:"chain,omitempty"`
|
Chain *Chain `json:"chain,omitempty"`
|
||||||
IPWhiteList *dynamic.IPWhiteList `json:"ipWhiteList,omitempty"`
|
IPWhiteList *dynamic.IPWhiteList `json:"ipWhiteList,omitempty"`
|
||||||
|
IPAllowList *dynamic.IPAllowList `json:"ipAllowList,omitempty"`
|
||||||
Headers *dynamic.Headers `json:"headers,omitempty"`
|
Headers *dynamic.Headers `json:"headers,omitempty"`
|
||||||
Errors *ErrorPage `json:"errors,omitempty"`
|
Errors *ErrorPage `json:"errors,omitempty"`
|
||||||
RateLimit *RateLimit `json:"rateLimit,omitempty"`
|
RateLimit *RateLimit `json:"rateLimit,omitempty"`
|
||||||
|
|
|
@ -26,7 +26,14 @@ type MiddlewareTCPSpec struct {
|
||||||
// InFlightConn defines the InFlightConn middleware configuration.
|
// InFlightConn defines the InFlightConn middleware configuration.
|
||||||
InFlightConn *dynamic.TCPInFlightConn `json:"inFlightConn,omitempty"`
|
InFlightConn *dynamic.TCPInFlightConn `json:"inFlightConn,omitempty"`
|
||||||
// IPWhiteList defines the IPWhiteList middleware configuration.
|
// IPWhiteList defines the IPWhiteList middleware configuration.
|
||||||
|
// This middleware accepts/refuses connections based on the client IP.
|
||||||
|
// Deprecated: please use IPAllowList instead.
|
||||||
|
// More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipwhitelist/
|
||||||
IPWhiteList *dynamic.TCPIPWhiteList `json:"ipWhiteList,omitempty"`
|
IPWhiteList *dynamic.TCPIPWhiteList `json:"ipWhiteList,omitempty"`
|
||||||
|
// IPAllowList defines the IPAllowList middleware configuration.
|
||||||
|
// This middleware accepts/refuses connections based on the client IP.
|
||||||
|
// More info: https://doc.traefik.io/traefik/v2.10/middlewares/tcp/ipallowlist/
|
||||||
|
IPAllowList *dynamic.TCPIPAllowList `json:"ipAllowList,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
|
|
|
@ -694,6 +694,11 @@ func (in *MiddlewareSpec) DeepCopyInto(out *MiddlewareSpec) {
|
||||||
*out = new(dynamic.IPWhiteList)
|
*out = new(dynamic.IPWhiteList)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.IPAllowList != nil {
|
||||||
|
in, out := &in.IPAllowList, &out.IPAllowList
|
||||||
|
*out = new(dynamic.IPAllowList)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.Headers != nil {
|
if in.Headers != nil {
|
||||||
in, out := &in.Headers, &out.Headers
|
in, out := &in.Headers, &out.Headers
|
||||||
*out = new(dynamic.Headers)
|
*out = new(dynamic.Headers)
|
||||||
|
@ -862,6 +867,11 @@ func (in *MiddlewareTCPSpec) DeepCopyInto(out *MiddlewareTCPSpec) {
|
||||||
*out = new(dynamic.TCPIPWhiteList)
|
*out = new(dynamic.TCPIPWhiteList)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
|
if in.IPAllowList != nil {
|
||||||
|
in, out := &in.IPAllowList, &out.IPAllowList
|
||||||
|
*out = new(dynamic.TCPIPAllowList)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/containous/alice"
|
"github.com/containous/alice"
|
||||||
"github.com/traefik/traefik/v2/pkg/config/runtime"
|
"github.com/traefik/traefik/v2/pkg/config/runtime"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/log"
|
||||||
"github.com/traefik/traefik/v2/pkg/middlewares/addprefix"
|
"github.com/traefik/traefik/v2/pkg/middlewares/addprefix"
|
||||||
"github.com/traefik/traefik/v2/pkg/middlewares/auth"
|
"github.com/traefik/traefik/v2/pkg/middlewares/auth"
|
||||||
"github.com/traefik/traefik/v2/pkg/middlewares/buffering"
|
"github.com/traefik/traefik/v2/pkg/middlewares/buffering"
|
||||||
|
@ -19,6 +20,7 @@ import (
|
||||||
"github.com/traefik/traefik/v2/pkg/middlewares/customerrors"
|
"github.com/traefik/traefik/v2/pkg/middlewares/customerrors"
|
||||||
"github.com/traefik/traefik/v2/pkg/middlewares/headers"
|
"github.com/traefik/traefik/v2/pkg/middlewares/headers"
|
||||||
"github.com/traefik/traefik/v2/pkg/middlewares/inflightreq"
|
"github.com/traefik/traefik/v2/pkg/middlewares/inflightreq"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/middlewares/ipallowlist"
|
||||||
"github.com/traefik/traefik/v2/pkg/middlewares/ipwhitelist"
|
"github.com/traefik/traefik/v2/pkg/middlewares/ipwhitelist"
|
||||||
"github.com/traefik/traefik/v2/pkg/middlewares/passtlsclientcert"
|
"github.com/traefik/traefik/v2/pkg/middlewares/passtlsclientcert"
|
||||||
"github.com/traefik/traefik/v2/pkg/middlewares/ratelimiter"
|
"github.com/traefik/traefik/v2/pkg/middlewares/ratelimiter"
|
||||||
|
@ -231,6 +233,8 @@ func (b *Builder) buildConstructor(ctx context.Context, middlewareName string) (
|
||||||
|
|
||||||
// IPWhiteList
|
// IPWhiteList
|
||||||
if config.IPWhiteList != nil {
|
if config.IPWhiteList != nil {
|
||||||
|
log.FromContext(ctx).Warn("IPWhiteList is deprecated, please use IPAllowList instead.")
|
||||||
|
|
||||||
if middleware != nil {
|
if middleware != nil {
|
||||||
return nil, badConf
|
return nil, badConf
|
||||||
}
|
}
|
||||||
|
@ -239,6 +243,16 @@ func (b *Builder) buildConstructor(ctx context.Context, middlewareName string) (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IPAllowList
|
||||||
|
if config.IPAllowList != nil {
|
||||||
|
if middleware != nil {
|
||||||
|
return nil, badConf
|
||||||
|
}
|
||||||
|
middleware = func(next http.Handler) (http.Handler, error) {
|
||||||
|
return ipallowlist.New(ctx, next, *config.IPAllowList, middlewareName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// InFlightReq
|
// InFlightReq
|
||||||
if config.InFlightReq != nil {
|
if config.InFlightReq != nil {
|
||||||
if middleware != nil {
|
if middleware != nil {
|
||||||
|
|
Loading…
Reference in a new issue