Add ipAllowListStrategy option for allowlist/whitelist annotations

This commit is contained in:
Mathieu Herbert
2026-04-30 17:16:11 +02:00
committed by GitHub
parent 47851c212f
commit 3854630763
7 changed files with 194 additions and 30 deletions
@@ -408,6 +408,9 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-providers-kubernetesingressnginx-httpsentrypoint" href="#opt-providers-kubernetesingressnginx-httpsentrypoint" title="#opt-providers-kubernetesingressnginx-httpsentrypoint">providers.kubernetesingressnginx.httpsentrypoint</a> | Defines the EntryPoint to use for HTTPS requests. | |
| <a id="opt-providers-kubernetesingressnginx-ingressclass" href="#opt-providers-kubernetesingressnginx-ingressclass" title="#opt-providers-kubernetesingressnginx-ingressclass">providers.kubernetesingressnginx.ingressclass</a> | Name of the ingress class this controller satisfies. | nginx |
| <a id="opt-providers-kubernetesingressnginx-ingressclassbyname" href="#opt-providers-kubernetesingressnginx-ingressclassbyname" title="#opt-providers-kubernetesingressnginx-ingressclassbyname">providers.kubernetesingressnginx.ingressclassbyname</a> | Define if Ingress Controller should watch for Ingress Class by Name together with Controller Class. | false |
| <a id="opt-providers-kubernetesingressnginx-ipallowliststrategy-depth" href="#opt-providers-kubernetesingressnginx-ipallowliststrategy-depth" title="#opt-providers-kubernetesingressnginx-ipallowliststrategy-depth">providers.kubernetesingressnginx.ipallowliststrategy.depth</a> | | 0 |
| <a id="opt-providers-kubernetesingressnginx-ipallowliststrategy-excludedips" href="#opt-providers-kubernetesingressnginx-ipallowliststrategy-excludedips" title="#opt-providers-kubernetesingressnginx-ipallowliststrategy-excludedips">providers.kubernetesingressnginx.ipallowliststrategy.excludedips</a> | | |
| <a id="opt-providers-kubernetesingressnginx-ipallowliststrategy-ipv6subnet" href="#opt-providers-kubernetesingressnginx-ipallowliststrategy-ipv6subnet" title="#opt-providers-kubernetesingressnginx-ipallowliststrategy-ipv6subnet">providers.kubernetesingressnginx.ipallowliststrategy.ipv6subnet</a> | | 0 |
| <a id="opt-providers-kubernetesingressnginx-proxybodysize" href="#opt-providers-kubernetesingressnginx-proxybodysize" title="#opt-providers-kubernetesingressnginx-proxybodysize">providers.kubernetesingressnginx.proxybodysize</a> | Default maximum size of a client request body in bytes. | 1048576 |
| <a id="opt-providers-kubernetesingressnginx-proxybuffering" href="#opt-providers-kubernetesingressnginx-proxybuffering" title="#opt-providers-kubernetesingressnginx-proxybuffering">providers.kubernetesingressnginx.proxybuffering</a> | Defines whether to enable response buffering. | false |
| <a id="opt-providers-kubernetesingressnginx-proxybuffersize" href="#opt-providers-kubernetesingressnginx-proxybuffersize" title="#opt-providers-kubernetesingressnginx-proxybuffersize">providers.kubernetesingressnginx.proxybuffersize</a> | Default buffer size for reading the response body. | 8192 |
@@ -65,20 +65,27 @@ providers:
controllerClass: "k8s.io/ingress-nginx"
watchIngressWithoutClass: false
ingressClassByName: false
globalAuthURL: "http://foo.com/auth"
proxyConnectTimeout: 60
proxyReadTimeout: 60
proxySendTimeout: 60
proxyRequestBuffering: false
clientBodyBufferSize: "16384" # 16k
proxyBuffering: false
proxyBodySize: "1048576" # 1m
proxyBufferSize: "8192" # 8k
proxyBuffersNumber: 4
upstreamKeepaliveTimeout: 60
customHTTPErrors:
- "404"
- "503"
allowCrossNamespaceResources: true
allowSnippetAnnotations: false
globalAllowedResponseHeaders:
- "X-Custom-Header1"
- "X-Custom-Header2"
ipAllowListStrategy:
depth: 2
strictValidatePathType: false
```
@@ -94,17 +101,25 @@ providers:
controllerClass = "k8s.io/ingress-nginx"
watchIngressWithoutClass = false
ingressClassByName = false
globalAuthURL = "http://foo.com/auth"
proxyConnectTimeout = 60
proxyReadTimeout = 60
proxySendTimeout = 60
proxyRequestBuffering = false
clientBodyBufferSize = "16384" # 16k
proxyBuffering = false
proxyBodySize = "1048576" # 1m
proxyBufferSize = "8192" # 8k
proxyBuffersNumber = 4
upstreamKeepaliveTimeout = 60
customHTTPErrors = ["404", "503"]
allowCrossNamespaceResources = true
allowSnippetAnnotations = false
globalAllowedResponseHeaders = ["X-Custom-Header1", "X-Custom-Header2"]
strictValidatePathType = false
[providers.kubernetesIngressNGINX.ipAllowListStrategy]
depth = 2
```
```bash tab="CLI"
@@ -114,16 +129,22 @@ providers:
--providers.kubernetesingressnginx.controllerclass=k8s.io/ingress-nginx
--providers.kubernetesingressnginx.watchingresswithoutclass=false
--providers.kubernetesingressnginx.ingressclassbyname=false
--providers.kubernetesingressnginx.globalauthurl=http://foo.com/auth
--providers.kubernetesingressnginx.proxyconnecttimeout=60
--providers.kubernetesingressnginx.proxyreadtimeout=60
--providers.kubernetesingressnginx.proxysendtimeout=60
--providers.kubernetesingressnginx.proxyrequestbuffering=false
--providers.kubernetesingressnginx.clientbodybuffersize=16384 # 16k
--providers.kubernetesingressnginx.proxybuffering=false
--providers.kubernetesingressnginx.proxybodysize=1048576 # 1m
--providers.kubernetesingressnginx.proxybuffersize=8192 # 8k
--providers.kubernetesingressnginx.proxybuffersnumber=4
--providers.kubernetesingressnginx.upstreamkeepalimetimeout=60
--providers.kubernetesingressnginx.customhttperrors=404,503
--providers.kubernetesingressnginx.allowCrossNamespaceResources=true
--providers.kubernetesingressnginx.allowsnippetannotations=false
--providers.kubernetesingressnginx.globalAllowedResponseHeaders=X-Custom-Header1,X-Custom-Header2
--providers.kubernetesingressnginx.ipallowliststrategy.depth=2
--providers.kubernetesingressnginx.strictvalidatepathtype=false
```
@@ -164,6 +185,7 @@ This provider watches for incoming Ingress events and automatically translates N
| <a id="opt-providers-kubernetesIngressNGINX-token" href="#opt-providers-kubernetesIngressNGINX-token" title="#opt-providers-kubernetesIngressNGINX-token">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`token`</a> | Bearer token used for the Kubernetes client configuration. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-certAuthFilePath" href="#opt-providers-kubernetesIngressNGINX-certAuthFilePath" title="#opt-providers-kubernetesIngressNGINX-certAuthFilePath">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`certAuthFilePath`</a> | Path to the certificate authority file.<br />Used for the Kubernetes client configuration. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-throttleDuration" href="#opt-providers-kubernetesIngressNGINX-throttleDuration" title="#opt-providers-kubernetesIngressNGINX-throttleDuration">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`throttleDuration`</a> | Minimum amount of time to wait between two Kubernetes events before producing a new configuration.<br />This prevents a Kubernetes cluster that updates many times per second from continuously changing your Traefik configuration.<br />If empty, every event is caught. | 0s | No |
| <a id="opt-providers-kubernetesIngressNGINX-globalAuthURL" href="#opt-providers-kubernetesIngressNGINX-globalAuthURL" title="#opt-providers-kubernetesIngressNGINX-globalAuthURL">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`globalAuthURL`</a> | URL to the service that provides authentication for all the locations. Per-ingress `auth-url` annotation has precedence over this option. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-watchNamespace" href="#opt-providers-kubernetesIngressNGINX-watchNamespace" title="#opt-providers-kubernetesIngressNGINX-watchNamespace">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchNamespace`</a> | Namespace the controller watches for updates to Kubernetes objects. All namespaces are watched if this parameter is left empty. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-watchNamespaceSelector" href="#opt-providers-kubernetesIngressNGINX-watchNamespaceSelector" title="#opt-providers-kubernetesIngressNGINX-watchNamespaceSelector">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchNamespaceSelector`</a> | Selector selects namespaces the controller watches for updates to Kubernetes objects. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-ingressClass" href="#opt-providers-kubernetesIngressNGINX-ingressClass" title="#opt-providers-kubernetesIngressNGINX-ingressClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ingressClass`</a> | Name of the IngressClass this controller handles. When `ingressClassByName` is `true`, IngressClasses with this name are included in discovery regardless of their `spec.controller` value. | "nginx" | No |
@@ -175,18 +197,25 @@ This provider watches for incoming Ingress events and automatically translates N
| <a id="opt-providers-kubernetesIngressNGINX-defaultBackendService" href="#opt-providers-kubernetesIngressNGINX-defaultBackendService" title="#opt-providers-kubernetesIngressNGINX-defaultBackendService">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`defaultBackendService`</a> | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form 'namespace/name'. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-disableSvcExternalName" href="#opt-providers-kubernetesIngressNGINX-disableSvcExternalName" title="#opt-providers-kubernetesIngressNGINX-disableSvcExternalName">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`disableSvcExternalName`</a> | Disable support for Services of type ExternalName. | false | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxyConnectTimeout" href="#opt-providers-kubernetesIngressNGINX-proxyConnectTimeout" title="#opt-providers-kubernetesIngressNGINX-proxyConnectTimeout">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyConnectTimeout`</a> | Amount of time to wait until a connection to a server can be established. The value is unitless and in seconds. This is used as the global connection timeout when no ingress-specific timeout is configured. An ingress-specific timeout can be configured using [`nginx.ingress.kubernetes.io/proxy-connect-timeout`](../../../../routing-configuration/kubernetes/ingress-nginx/#opt-nginx-ingress-kubernetes-ioproxy-connect-timeout) annotation. | 60 | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxyReadTimeout" href="#opt-providers-kubernetesIngressNGINX-proxyReadTimeout" title="#opt-providers-kubernetesIngressNGINX-proxyReadTimeout">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyReadTimeout`</a> | Amount of time between two successive read operations. The value is unitless and in seconds. This is used as the global read timeout when no ingress-specific timeout is configured. An ingress-specific timeout can be configured using [`nginx.ingress.kubernetes.io/proxy-read-timeout`](../../../../routing-configuration/kubernetes/ingress-nginx/#opt-nginx-ingress-kubernetes-ioproxy-read-timeout) annotation. | 60 | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxySendTimeout" href="#opt-providers-kubernetesIngressNGINX-proxySendTimeout" title="#opt-providers-kubernetesIngressNGINX-proxySendTimeout">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxySendTimeout`</a> | Amount of time between two successive write operations. The value is unitless and in seconds. This is used as the global send timeout when no ingress-specific timeout is configured. An ingress-specific timeout can be configured using [`nginx.ingress.kubernetes.io/proxy-send-timeout`](../../../../routing-configuration/kubernetes/ingress-nginx/#opt-nginx-ingress-kubernetes-ioproxy-send-timeout) annotation. | 60 | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxyrequestbuffering" href="#opt-providers-kubernetesIngressNGINX-proxyrequestbuffering" title="#opt-providers-kubernetesIngressNGINX-proxyrequestbuffering">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyrequestbuffering`</a> | Defines whether request buffering is enabled by default for all ingresses. | false | No |
| <a id="opt-providers-kubernetesIngressNGINX-clientBodyBufferSize" href="#opt-providers-kubernetesIngressNGINX-clientBodyBufferSize" title="#opt-providers-kubernetesIngressNGINX-clientBodyBufferSize">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`clientBodyBufferSize`</a> | Default buffer size for reading client request body in bytes. | 16384 | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxybuffering" href="#opt-providers-kubernetesIngressNGINX-proxybuffering" title="#opt-providers-kubernetesIngressNGINX-proxybuffering">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxybuffering`</a> | Defines whether response buffering is enabled by default for all ingresses. | false | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxyBodySize" href="#opt-providers-kubernetesIngressNGINX-proxyBodySize" title="#opt-providers-kubernetesIngressNGINX-proxyBodySize">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyBodySize`</a> | Default maximum size of a client request body in bytes. | 1048576 | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxyBufferSize" href="#opt-providers-kubernetesIngressNGINX-proxyBufferSize" title="#opt-providers-kubernetesIngressNGINX-proxyBufferSize">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyBufferSize`</a> | Default buffer size for reading the response body in bytes. | 8192 | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxyBuffersNumber" href="#opt-providers-kubernetesIngressNGINX-proxyBuffersNumber" title="#opt-providers-kubernetesIngressNGINX-proxyBuffersNumber">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyBuffersNumber`</a> | Default number of buffers for reading a response. | 4 | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxyBuffersNumber-2" href="#opt-providers-kubernetesIngressNGINX-proxyBuffersNumber-2" title="#opt-providers-kubernetesIngressNGINX-proxyBuffersNumber-2">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyBuffersNumber`</a> | Default number of buffers for reading a response. | 4 | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxyNextUpstreama" href="#opt-providers-kubernetesIngressNGINX-proxyNextUpstreama" title="#opt-providers-kubernetesIngressNGINX-proxyNextUpstreama">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyNextUpstream`</a></a> | Defines in which cases a request should be retried. Accepted values are a space-separated list of: `error`, `timeout`, `http_XXX` (e.g. http_502), `non_idempotent`, and `off` (disables retry). This is used as the global proxy-next-upstream configuration when no ingress-specific value is configured. An ingress-specific configuration can be set using [`nginx.ingress.kubernetes.io/proxy-next-upstream`](../../../../routing-configuration/kubernetes/ingress-nginx/#opt-nginx-ingress-kubernetes-ioproxy-next-upstream) annotation. | "error timeout" | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxyNextUpstreamTriesa" href="#opt-providers-kubernetesIngressNGINX-proxyNextUpstreamTriesa" title="#opt-providers-kubernetesIngressNGINX-proxyNextUpstreamTriesa">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyNextUpstreamTries`</a></a> | Limits the number of possible tries if the backend server does not reply. 0 means unlimited tries, which is capped to the number of available servers. This is used as the global retry count configuration when no ingress-specific value is configured. An ingress-specific retry limit can be set using [`nginx.ingress.kubernetes.io/proxy-next-upstream-tries`](../../../../routing-configuration/kubernetes/ingress-nginx/#opt-nginx-ingress-kubernetes-ioproxy-next-upstream-tries) annotation. | 3 | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxyNextUpstreamTimeouta" href="#opt-providers-kubernetesIngressNGINX-proxyNextUpstreamTimeouta" title="#opt-providers-kubernetesIngressNGINX-proxyNextUpstreamTimeouta">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyNextUpstreamTimeout`</a></a> | Limits the total elapsed time to retry the request if the backend server does not reply. Timeout value is unitless and in seconds. 0 means no timeout. This is used as the global retry timeout when no ingress-specific value is configured. An ingress-specific retry timeout can be set using [`nginx.ingress.kubernetes.io/proxy-next-upstream-timeout`](../../../../routing-configuration/kubernetes/ingress-nginx/#opt-nginx-ingress-kubernetes-ioproxy-next-upstream-timeout) annotation. | 0 | No |
| <a id="opt-providers-kubernetesIngressNGINX-customHTTPErrors" href="#opt-providers-kubernetesIngressNGINX-customHTTPErrors" title="#opt-providers-kubernetesIngressNGINX-customHTTPErrors">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`customHTTPErrors`<br/></a> | Defines which status should result in calling the default backend to return an error page. | [] | No || <a id="opt-providers-kubernetesIngressNGINX-allowCrossNamespaceResources" href="#opt-providers-kubernetesIngressNGINX-allowCrossNamespaceResources" title="#opt-providers-kubernetesIngressNGINX-allowCrossNamespaceResources">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`allowCrossNamespaceResources`</a> | Allow Ingress to reference resources (e.g. ConfigMaps, Secrets) in different namespaces. | false | No |
| <a id="opt-providers-kubernetesIngressNGINX-upstreamKeepaliveTimeout" href="#opt-providers-kubernetesIngressNGINX-upstreamKeepaliveTimeout" title="#opt-providers-kubernetesIngressNGINX-upstreamKeepaliveTimeout">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`upstreamKeepaliveTimeout`</a> | Defines the idle timeout for keep-alive connections to upstream servers. The value is unitless and in seconds. | 60 | No |
| <a id="opt-providers-kubernetesIngressNGINX-customHTTPErrors" href="#opt-providers-kubernetesIngressNGINX-customHTTPErrors" title="#opt-providers-kubernetesIngressNGINX-customHTTPErrors">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`customHTTPErrors`<br/></a> | Defines which status should result in calling the default backend to return an error page. | [] | No |
| <a id="opt-providers-kubernetesIngressNGINX-allowCrossNamespaceResources" href="#opt-providers-kubernetesIngressNGINX-allowCrossNamespaceResources" title="#opt-providers-kubernetesIngressNGINX-allowCrossNamespaceResources">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`allowCrossNamespaceResources`</a> | Allow Ingress to reference resources (e.g. ConfigMaps, Secrets) in different namespaces. | false | No |
| <a id="opt-providers-kubernetesIngressNGINX-globalAllowedResponseHeaders" href="#opt-providers-kubernetesIngressNGINX-globalAllowedResponseHeaders" title="#opt-providers-kubernetesIngressNGINX-globalAllowedResponseHeaders">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`globalAllowedResponseHeaders`</a> | List of allowed response headers inside the custom headers annotations. It is required to configure it for the custom headers annotations to take effect. | [] | No |
| <a id="opt-providers-kubernetesIngressNGINX-ipAllowListStrategy" href="#opt-providers-kubernetesIngressNGINX-ipAllowListStrategy" title="#opt-providers-kubernetesIngressNGINX-ipAllowListStrategy">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ipAllowListStrategy`</a> | Defines the IP strategy to determine the client IP for `allowlist-source-range` and `whitelist-source-range` annotations. When set, the strategy is applied to every generated IPAllowList middleware. | - | No |
| <a id="opt-providers-kubernetesIngressNGINX-ipAllowListStrategy-depth" href="#opt-providers-kubernetesIngressNGINX-ipAllowListStrategy-depth" title="#opt-providers-kubernetesIngressNGINX-ipAllowListStrategy-depth">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ipAllowListStrategy.`<br/>`depth`</a> | Number of trusted proxy hops to skip when extracting the client IP from the `X-Forwarded-For` header. 0 disables depth-based extraction. | 0 | No |
| <a id="opt-providers-kubernetesIngressNGINX-ipAllowListStrategy-excludedIPs" href="#opt-providers-kubernetesIngressNGINX-ipAllowListStrategy-excludedIPs" title="#opt-providers-kubernetesIngressNGINX-ipAllowListStrategy-excludedIPs">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ipAllowListStrategy.`<br/>`excludedIPs`</a> | List of IPs to exclude when scanning the `X-Forwarded-For` header to find the client IP. | [] | No |
| <a id="opt-providers-kubernetesIngressNGINX-ipAllowListStrategy-ipv6Subnet" href="#opt-providers-kubernetesIngressNGINX-ipAllowListStrategy-ipv6Subnet" title="#opt-providers-kubernetesIngressNGINX-ipAllowListStrategy-ipv6Subnet">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ipAllowListStrategy.`<br/>`ipv6Subnet`</a> | IPv6 subnet size used to group IPv6 addresses when checking the allow list. 0 disables subnet grouping. | 0 | No |
| <a id="opt-providers-kubernetesIngressNGINX-httpentrypoint" href="#opt-providers-kubernetesIngressNGINX-httpentrypoint" title="#opt-providers-kubernetesIngressNGINX-httpentrypoint">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`httpentrypoint`</a> | Defines the EntryPoint to use for HTTP requests. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-httpsentrypoint" href="#opt-providers-kubernetesIngressNGINX-httpsentrypoint" title="#opt-providers-kubernetesIngressNGINX-httpsentrypoint">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`httpsentrypoint`</a> | Defines the EntryPoint to use for HTTPS requests. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-strictValidatePathType" href="#opt-providers-kubernetesIngressNGINX-strictValidatePathType" title="#opt-providers-kubernetesIngressNGINX-strictValidatePathType">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`strictValidatePathType`</a> | Defines whether to reject the entire ingress when any path contains regex characters and pathType is Prefix or Exact. | true | No |
@@ -54,12 +54,12 @@ spec:
## Configuration Options
| Field | Description | Default | Required |
|:-----------|:------------------------------|:--------|:---------|
| <a id="opt-sourceRange" href="#opt-sourceRange" title="#opt-sourceRange">`sourceRange`</a> | List of allowed IPs (or ranges of allowed IPs by using CIDR notation). | | Yes |
| <a id="opt-ipStrategy-depth" href="#opt-ipStrategy-depth" title="#opt-ipStrategy-depth">`ipStrategy.depth`</a> | Depth position of the IP to select in the `X-Forwarded-For` header (starting from the right).<br />0 means no depth.<br />If greater than the total number of IPs in `X-Forwarded-For`, then the client IP is empty<br /> If higher than 0, the `excludedIPs` options is not evaluated.<br /> More information about [`ipStrategy](#ipstrategy), and [`depth`](#example-of-depth--x-forwarded-for) below. | 0 | No |
| <a id="opt-ipStrategy-excludedIPs" href="#opt-ipStrategy-excludedIPs" title="#opt-ipStrategy-excludedIPs">`ipStrategy.excludedIPs`</a> | Allows Traefik to scan the `X-Forwarded-For` header and select the first IP not in the list.<br />If `depth` is specified, `excludedIPs` is ignored.<br /> More information about [`ipStrategy](#ipstrategy), and [`excludedIPs`](#example-of-excludedips--x-forwarded-for) below. | | No |
| <a id="opt-ipStrategy-ipv6Subnet" href="#opt-ipStrategy-ipv6Subnet" title="#opt-ipStrategy-ipv6Subnet">`ipStrategy.ipv6Subnet`</a> | If `ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to. <br />More information about [`ipStrategy.ipv6Subnet`](#ipstrategyipv6subnet), and [`excludedIPs`](#example-of-excludedips--x-forwarded-for) below. | | No |
| Field | Description | Default | Required |
|:-----------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------|:---------|
| <a id="opt-sourceRange" href="#opt-sourceRange" title="#opt-sourceRange">`sourceRange`</a> | List of allowed IPs (or ranges of allowed IPs by using CIDR notation). | | Yes |
| <a id="opt-ipStrategy-depth" href="#opt-ipStrategy-depth" title="#opt-ipStrategy-depth">`ipStrategy.depth`</a> | Depth position of the IP to select in the `X-Forwarded-For` header (starting from the right).<br />0 means no depth.<br />If greater than the total number of IPs in `X-Forwarded-For`, then the client IP is empty<br /> If higher than 0, the `excludedIPs` options is not evaluated.<br /> More information about [`ipStrategy`](#ipstrategy), and [`depth`](#example-of-depth-x-forwarded-for) below. | 0 | No |
| <a id="opt-ipStrategy-excludedIPs" href="#opt-ipStrategy-excludedIPs" title="#opt-ipStrategy-excludedIPs">`ipStrategy.excludedIPs`</a> | Allows Traefik to scan the `X-Forwarded-For` header and select the first IP not in the list.<br />If `depth` is specified, `excludedIPs` is ignored.<br /> More information about [`ipStrategy`](#ipstrategy), and [`excludedIPs`](#example-of-excludedips-x-forwarded-for) below. | | No |
| <a id="opt-ipStrategy-ipv6Subnet" href="#opt-ipStrategy-ipv6Subnet" title="#opt-ipStrategy-ipv6Subnet">`ipStrategy.ipv6Subnet`</a> | If `ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to. <br />More information about [`ipStrategy.ipv6Subnet`](#ipstrategyipv6subnet), and [`excludedIPs`](#example-of-excludedips-x-forwarded-for) below. | | No |
### ipStrategy
@@ -364,6 +364,12 @@ The following annotations are organized by category for easier navigation.
### IP Whitelist
!!! info "Client IP Strategy"
By default, the client IP is determined from the remote address of the incoming request.
When Traefik is behind a reverse proxy, the actual client IP is often found in the `X-Forwarded-For` header instead.
This can be configured globally using the provider option [`ipAllowListStrategy`](../../../install-configuration/providers/kubernetes/kubernetes-ingress-nginx/#opt-providers-kubernetesIngressNGINX-ipAllowListStrategy).
| Annotation | Limitations / Notes |
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-iowhitelist-source-range" href="#opt-nginx-ingress-kubernetes-iowhitelist-source-range" title="#opt-nginx-ingress-kubernetes-iowhitelist-source-range">`nginx.ingress.kubernetes.io/whitelist-source-range`</a> | |
@@ -98,26 +98,7 @@ type Provider struct {
DefaultBackendService string `description:"Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form 'namespace/name'." json:"defaultBackendService,omitempty" toml:"defaultBackendService,omitempty" yaml:"defaultBackendService,omitempty" export:"true"`
DisableSvcExternalName bool `description:"Disable support for Services of type ExternalName." json:"disableSvcExternalName,omitempty" toml:"disableSvcExternalName,omitempty" yaml:"disableSvcExternalName,omitempty" export:"true"`
// Configuration options available within the NGINX Ingress Controller ConfigMap.
ProxyRequestBuffering bool `description:"Defines whether to enable request buffering." json:"proxyRequestBuffering,omitempty" toml:"proxyRequestBuffering,omitempty" yaml:"proxyRequestBuffering,omitempty" export:"true"`
ClientBodyBufferSize int64 `description:"Default buffer size for reading client request body." json:"clientBodyBufferSize,omitempty" toml:"clientBodyBufferSize,omitempty" yaml:"clientBodyBufferSize,omitempty" export:"true"`
ProxyBodySize int64 `description:"Default maximum size of a client request body in bytes." json:"proxyBodySize,omitempty" toml:"proxyBodySize,omitempty" yaml:"proxyBodySize,omitempty" export:"true"`
ProxyBuffering bool `description:"Defines whether to enable response buffering." json:"proxyBuffering,omitempty" toml:"proxyBuffering,omitempty" yaml:"proxyBuffering,omitempty" export:"true"`
ProxyBufferSize int64 `description:"Default buffer size for reading the response body." json:"proxyBufferSize,omitempty" toml:"proxyBufferSize,omitempty" yaml:"proxyBufferSize,omitempty" export:"true"`
ProxyBuffersNumber int `description:"Default number of buffers for reading a response." json:"proxyBuffersNumber,omitempty" toml:"proxyBuffersNumber,omitempty" yaml:"proxyBuffersNumber,omitempty" export:"true"`
ProxyConnectTimeout int `description:"Amount of time to wait until a connection to a server can be established. Timeout value is unitless and in seconds." json:"proxyConnectTimeout,omitempty" toml:"proxyConnectTimeout,omitempty" yaml:"proxyConnectTimeout,omitempty" export:"true"`
ProxyReadTimeout int `description:"Amount of time between two successive read operations. Timeout value is unitless and in seconds." json:"proxyReadTimeout,omitempty" toml:"proxyReadTimeout,omitempty" yaml:"proxyReadTimeout,omitempty" export:"true"`
ProxySendTimeout int `description:"Amount of time between two successive write operations. Timeout value is unitless and in seconds." json:"proxySendTimeout,omitempty" toml:"proxySendTimeout,omitempty" yaml:"proxySendTimeout,omitempty" export:"true"`
ProxyNextUpstream string `description:"Defines in which cases a request should be retried." json:"proxyNextUpstream,omitempty" toml:"proxyNextUpstream,omitempty" yaml:"proxyNextUpstream,omitempty" export:"true"`
ProxyNextUpstreamTries int `description:"Limits the number of possible tries if the backend server does not reply." json:"proxyNextUpstreamTries,omitempty" toml:"proxyNextUpstreamTries,omitempty" yaml:"proxyNextUpstreamTries,omitempty" export:"true"`
ProxyNextUpstreamTimeout int `description:"Limits the total elapsed time to retry the request if the backend server does not reply. Timeout value is unitless and in seconds." json:"proxyNextUpstreamTimeout,omitempty" toml:"proxyNextUpstreamTimeout,omitempty" yaml:"proxyNextUpstreamTimeout,omitempty" export:"true"`
CustomHTTPErrors []string `description:"Defines which status should result in calling the default backend to return an error page." json:"customHTTPErrors,omitempty" toml:"customHTTPErrors,omitempty" yaml:"customHTTPErrors,omitempty" export:"true"`
UpstreamKeepaliveTimeout int `description:"Defines the idle timeout for keep-alive connections to upstream servers. Timeout value is unitless and in seconds." json:"upstreamKeepaliveTimeout,omitempty" toml:"upstreamKeepaliveTimeout,omitempty" yaml:"upstreamKeepaliveTimeout,omitempty" export:"true"`
AllowCrossNamespaceResources bool `description:"Allow Ingress to reference resources (e.g. ConfigMaps, Secrets) in different namespaces." json:"allowCrossNamespaceResources,omitempty" toml:"allowCrossNamespaceResources,omitempty" yaml:"allowCrossNamespaceResources,omitempty" export:"true"`
GlobalAllowedResponseHeaders []string `description:"List of allowed response headers inside the custom headers annotations." json:"globalAllowedResponseHeaders,omitempty" toml:"globalAllowedResponseHeaders,omitempty" yaml:"globalAllowedResponseHeaders,omitempty" export:"true"`
AllowSnippetAnnotations bool `description:"Enables to parse and add -snippet annotations/directives." json:"allowSnippetAnnotations,omitempty" toml:"allowSnippetAnnotations,omitempty" yaml:"allowSnippetAnnotations,omitempty" export:"true"`
IPAllowListStrategy *dynamic.IPStrategy `description:"Defines the IP strategy to determine the client IP for allowlist/whitelist source range annotations." json:"ipAllowListStrategy,omitempty" toml:"ipAllowListStrategy,omitempty" yaml:"ipAllowListStrategy,omitempty" export:"true"`
HTTPEntryPoint string `description:"Defines the EntryPoint to use for HTTP requests." json:"httpEntryPoint,omitempty" toml:"httpEntryPoint,omitempty" yaml:"httpEntryPoint,omitempty" export:"true"`
HTTPSEntryPoint string `description:"Defines the EntryPoint to use for HTTPS requests." json:"httpsEntryPoint,omitempty" toml:"httpsEntryPoint,omitempty" yaml:"httpsEntryPoint,omitempty" export:"true"`
@@ -127,7 +108,25 @@ type Provider struct {
// Its value is set to the HTTPEntryPoint value if it is set, otherwise it is computed in SetEffectiveConfiguration.
NonTLSEntryPoints []string `json:"-" toml:"-" yaml:"-" label:"-" file:"-"`
StrictValidatePathType bool `description:"Defines whether to reject the entire ingress when any path contains regex characters and pathType is Prefix or Exact." json:"strictValidatePathType,omitempty" toml:"strictValidatePathType,omitempty" yaml:"strictValidatePathType,omitempty" export:"true"`
// Configuration options available within the NGINX Ingress Controller ConfigMap.
ProxyRequestBuffering bool `description:"Defines whether to enable request buffering." json:"proxyRequestBuffering,omitempty" toml:"proxyRequestBuffering,omitempty" yaml:"proxyRequestBuffering,omitempty" export:"true"`
ClientBodyBufferSize int64 `description:"Default buffer size for reading client request body." json:"clientBodyBufferSize,omitempty" toml:"clientBodyBufferSize,omitempty" yaml:"clientBodyBufferSize,omitempty" export:"true"`
ProxyBodySize int64 `description:"Default maximum size of a client request body in bytes." json:"proxyBodySize,omitempty" toml:"proxyBodySize,omitempty" yaml:"proxyBodySize,omitempty" export:"true"`
ProxyBuffering bool `description:"Defines whether to enable response buffering." json:"proxyBuffering,omitempty" toml:"proxyBuffering,omitempty" yaml:"proxyBuffering,omitempty" export:"true"`
ProxyBufferSize int64 `description:"Default buffer size for reading the response body." json:"proxyBufferSize,omitempty" toml:"proxyBufferSize,omitempty" yaml:"proxyBufferSize,omitempty" export:"true"`
ProxyBuffersNumber int `description:"Default number of buffers for reading a response." json:"proxyBuffersNumber,omitempty" toml:"proxyBuffersNumber,omitempty" yaml:"proxyBuffersNumber,omitempty" export:"true"`
ProxyConnectTimeout int `description:"Amount of time to wait until a connection to a server can be established. Timeout value is unitless and in seconds." json:"proxyConnectTimeout,omitempty" toml:"proxyConnectTimeout,omitempty" yaml:"proxyConnectTimeout,omitempty" export:"true"`
ProxyReadTimeout int `description:"Amount of time between two successive read operations. Timeout value is unitless and in seconds." json:"proxyReadTimeout,omitempty" toml:"proxyReadTimeout,omitempty" yaml:"proxyReadTimeout,omitempty" export:"true"`
ProxySendTimeout int `description:"Amount of time between two successive write operations. Timeout value is unitless and in seconds." json:"proxySendTimeout,omitempty" toml:"proxySendTimeout,omitempty" yaml:"proxySendTimeout,omitempty" export:"true"`
ProxyNextUpstream string `description:"Defines in which cases a request should be retried." json:"proxyNextUpstream,omitempty" toml:"proxyNextUpstream,omitempty" yaml:"proxyNextUpstream,omitempty" export:"true"`
ProxyNextUpstreamTries int `description:"Limits the number of possible tries if the backend server does not reply." json:"proxyNextUpstreamTries,omitempty" toml:"proxyNextUpstreamTries,omitempty" yaml:"proxyNextUpstreamTries,omitempty" export:"true"`
ProxyNextUpstreamTimeout int `description:"Limits the total elapsed time to retry the request if the backend server does not reply. Timeout value is unitless and in seconds." json:"proxyNextUpstreamTimeout,omitempty" toml:"proxyNextUpstreamTimeout,omitempty" yaml:"proxyNextUpstreamTimeout,omitempty" export:"true"`
CustomHTTPErrors []string `description:"Defines which status should result in calling the default backend to return an error page." json:"customHTTPErrors,omitempty" toml:"customHTTPErrors,omitempty" yaml:"customHTTPErrors,omitempty" export:"true"`
UpstreamKeepaliveTimeout int `description:"Defines the idle timeout for keep-alive connections to upstream servers. Timeout value is unitless and in seconds." json:"upstreamKeepaliveTimeout,omitempty" toml:"upstreamKeepaliveTimeout,omitempty" yaml:"upstreamKeepaliveTimeout,omitempty" export:"true"`
AllowCrossNamespaceResources bool `description:"Allow Ingress to reference resources (e.g. ConfigMaps, Secrets) in different namespaces." json:"allowCrossNamespaceResources,omitempty" toml:"allowCrossNamespaceResources,omitempty" yaml:"allowCrossNamespaceResources,omitempty" export:"true"`
GlobalAllowedResponseHeaders []string `description:"List of allowed response headers inside the custom headers annotations." json:"globalAllowedResponseHeaders,omitempty" toml:"globalAllowedResponseHeaders,omitempty" yaml:"globalAllowedResponseHeaders,omitempty" export:"true"`
AllowSnippetAnnotations bool `description:"Enables to parse and add -snippet annotations/directives." json:"allowSnippetAnnotations,omitempty" toml:"allowSnippetAnnotations,omitempty" yaml:"allowSnippetAnnotations,omitempty" export:"true"`
StrictValidatePathType bool `description:"Defines whether to reject the entire ingress when any path contains regex characters and pathType is Prefix or Exact." json:"strictValidatePathType,omitempty" toml:"strictValidatePathType,omitempty" yaml:"strictValidatePathType,omitempty" export:"true"`
allowedHeaders []string
defaultBackendServiceNamespace string
@@ -30,6 +30,7 @@ func TestLoadIngresses(t *testing.T) {
defaultBackendServiceNamespace string
allowCrossNamespaceResources bool
globalAllowedResponseHeaders []string
ipAllowListStrategy *dynamic.IPStrategy
allowSnippetAnnotations bool
globalAuthURL string
strictValidatePathType *bool
@@ -6281,6 +6282,128 @@ func TestLoadIngresses(t *testing.T) {
TLS: &dynamic.TLSConfiguration{},
},
},
{
desc: "AllowlistSourceRange with global IPAllowListDepth",
ipAllowListStrategy: &dynamic.IPStrategy{Depth: 2},
paths: []string{
"services.yml",
"ingressclasses.yml",
"ingresses/ingress-with-allowlist-single-ip.yml",
},
expected: &dynamic.Configuration{
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Services: map[string]*dynamic.TCPService{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"default-ingress-with-allowlist-single-ip-rule-0-path-0": {
EntryPoints: []string{"http"},
Rule: `Host("allowlist-source-range.localhost") && Path("/")`,
RuleSyntax: "default",
Middlewares: []string{"default-ingress-with-allowlist-single-ip-rule-0-path-0-allowed-source-range", "default-ingress-with-allowlist-single-ip-rule-0-path-0-retry"},
Service: "default-ingress-with-allowlist-single-ip-whoami-80",
Observability: &dynamic.RouterObservabilityConfig{
Metadata: &dynamic.ObservabilityMetadata{
Ingress: &dynamic.KubernetesIngressMetadata{
Namespace: "default",
IngressName: "ingress-with-allowlist-single-ip",
ServiceName: "whoami",
ServicePort: "80",
},
},
},
},
"default-ingress-with-allowlist-single-ip-rule-0-path-0-tls": {
EntryPoints: []string{"https"},
Rule: `Host("allowlist-source-range.localhost") && Path("/")`,
RuleSyntax: "default",
Middlewares: []string{"default-ingress-with-allowlist-single-ip-rule-0-path-0-tls-allowed-source-range", "default-ingress-with-allowlist-single-ip-rule-0-path-0-tls-retry"},
Service: "default-ingress-with-allowlist-single-ip-whoami-80",
TLS: &dynamic.RouterTLSConfig{},
Observability: &dynamic.RouterObservabilityConfig{
Metadata: &dynamic.ObservabilityMetadata{
Ingress: &dynamic.KubernetesIngressMetadata{
Namespace: "default",
IngressName: "ingress-with-allowlist-single-ip",
ServiceName: "whoami",
ServicePort: "80",
},
},
},
},
},
Middlewares: map[string]*dynamic.Middleware{
"default-ingress-with-allowlist-single-ip-rule-0-path-0-allowed-source-range": {
IPAllowList: &dynamic.IPAllowList{
SourceRange: []string{"192.168.20.1"},
IPStrategy: &dynamic.IPStrategy{
Depth: 2,
},
},
},
"default-ingress-with-allowlist-single-ip-rule-0-path-0-tls-allowed-source-range": {
IPAllowList: &dynamic.IPAllowList{
SourceRange: []string{"192.168.20.1"},
IPStrategy: &dynamic.IPStrategy{
Depth: 2,
},
},
},
"default-ingress-with-allowlist-single-ip-rule-0-path-0-retry": {
Retry: &dynamic.Retry{
Attempts: 3,
},
},
"default-ingress-with-allowlist-single-ip-rule-0-path-0-tls-retry": {
Retry: &dynamic.Retry{
Attempts: 3,
},
},
},
Services: map[string]*dynamic.Service{
"unavailable-service": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: "wrr",
PassHostHeader: ptr.To(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
},
},
"default-ingress-with-allowlist-single-ip-whoami-80": {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://10.10.0.1:80",
},
{
URL: "http://10.10.0.2:80",
},
},
Strategy: "wrr",
PassHostHeader: ptr.To(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: dynamic.DefaultFlushInterval,
},
ServersTransport: "default-ingress-with-allowlist-single-ip",
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{
"default-ingress-with-allowlist-single-ip": {
ForwardingTimeouts: &dynamic.ForwardingTimeouts{
DialTimeout: ptypes.Duration(60 * time.Second),
ReadTimeout: ptypes.Duration(60 * time.Second),
WriteTimeout: ptypes.Duration(60 * time.Second),
IdleConnTimeout: ptypes.Duration(60 * time.Second),
},
},
},
},
TLS: &dynamic.TLSConfiguration{},
},
},
{
desc: "AllowlistSourceRange with single CIDR",
paths: []string{
@@ -15012,6 +15135,7 @@ func TestLoadIngresses(t *testing.T) {
NonTLSEntryPoints: []string{"http"},
TLSEntryPoints: []string{"https"},
allowedHeaders: test.globalAllowedResponseHeaders,
IPAllowListStrategy: test.ipAllowListStrategy,
AllowCrossNamespaceResources: test.allowCrossNamespaceResources,
GlobalAuthURL: test.globalAuthURL,
}
@@ -229,7 +229,10 @@ func (p *Provider) buildIPAllowList(loc *location) {
ranges = append(ranges, strings.TrimSpace(r))
}
loc.IPAllowList = &dynamic.IPAllowList{SourceRange: ranges}
loc.IPAllowList = &dynamic.IPAllowList{
SourceRange: ranges,
IPStrategy: p.IPAllowListStrategy,
}
}
func (p *Provider) buildCORS(loc *location) {