Skip to content

Make Original Client IP Available to Ingress-Nginx #63

@artntek

Description

@artntek

Goal

We want ingress-nginx to have access to the original client IP address for each request, so we can audit these in the access logs, and use them for IP filtering (e.g. adc /wp-admin whitelist), etc.

Current State

I could not make IP filtering work with ingress-nginx, because nginx sees internal IP addresses (from 192.168.0.0/16) as the "source" of each incoming request - example from nginx logs:

# in prod-k8s context:
$ kubectl logs -n ingress-nginx -f $(kc get pods -n ingress-nginx | grep "ingress-nginx" | awk '{print $1}')
[...]
192.168.86.128 - - [24/May/2025:15:47:25 +0000] "GET /metacat/d1/mn/v2/object?fromDate=2025-03-27T21:02:11.053%2B00:00&toDate=2025-05-24T15:47:25.025%2B00:00&replicaStatus=0&start=0&count=1000 HTTP/1.1" 200 948 "-" "Apache-HttpClient/4.5.14 (Java/17.0.7)" 1061 0.367 [opc-metacatopc-hl-8080] [] 192.168.175.215:8080 948 0.367 200 940b41a67e62553d86f77ebed279bda4
192.168.23.192 - - [24/May/2025:15:48:00 +0000] "GET /metacat/d1/mn/v2/object?count=1 HTTP/2.0" 200 563 "-" "checkmk-active-httpv2/2.3.0/chrome" 71 0.244 [opc-metacatopc-hl-8080] [] 192.168.175.215:8080 563 0.243 200 c51d07feadcf7493c83d6acbc6acd683
192.168.23.192 - - [24/May/2025:15:48:06 +0000] "GET / HTTP/1.1" 301 162 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" 320 0.000 [goa-mcuigoa-metacatui-80] [] - - - - 7932d75a1962bd1971c878b727f85f1a
192.168.23.192 - - [24/May/2025:15:48:07 +0000] "" 400 0 "-" "-" 0 0.241 [] [] - - - - 181a722f7716cf946ec333633379d8a4
192.168.23.192 - - [24/May/2025:15:48:16 +0000] "GET / HTTP/1.1" 404 146 "-" "check_http/v2.4.0 (monitoring-plugins 2.4.0)" 118 0.001 [upstream-default-backend] [] 127.0.0.1:8181 146 0.001 404 14a322dfaa7273eed1b88b66fca8856a
[...]

The documentation says:

By default NGINX uses the content of the header X-Forwarded-For as the source of truth to get information about the client IP address

...but I couldn't get this to work. Tried all the following annotations (see k8s-cluster-config/[prod_cluster/metacatarctic/wordpress/values-prod-cluster-wordpress-arctic.yaml)

nginx.ingress.kubernetes.io/enable-real-ip: "true"
nginx.ingress.kubernetes.io/proxy-real-ip-cidr: "0.0.0.0/0"
nginx.ingress.kubernetes.io/set_real_ip_from: "0.0.0.0/0"
# also tried: "128.111.85.128/25" and "192.168.0.0/16"
nginx.ingress.kubernetes.io/real_ip_header: "X-Forwarded-For"
# also tried: "X-Real-IP" and "CF-Connecting-IP"
nginx.ingress.kubernetes.io/real_ip_recursive: "on"
nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
nginx.ingress.kubernetes.io/use-proxy-protocol: "false"
nginx.ingress.kubernetes.io/whitelist-source-range: |
  128.111.61.0/24,
  128.111.64.0/22,
  128.111.85.0/24,
  128.111.180.0/22,
  128.111.188.0/22,
  128.111.196.0/23,
  207.71.230.208/29
# Only way I could get filtering to "work" is by adding the internal IPs:
#  , 192.168.0.0/16

Next steps

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions