среда, 23 января 2019 г.

Пробрасываем реальный IP-адрес в Nginx Ingress от Cloudfront

По умолчанию установленный Nginx Ingress с помощью HELM в AWS не пробрасывает реальный IP-адрес внутрь балансера, поэтому в логах ингресс-контроллера будут присутствовать логи с внутренних адресов сети.

В каком случае нам нужно иметь реальный адрес? Например если мы хотим на уровне ингресса или приложения анализировать адреса или для их блокировки.
Делается это несложно.

Включаем аннотацию для прокси в сервисе контроллера:
kubectl edit svc nginx-ingress-controller -n kube-system
metadata:
...
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*'

Разрешаем в конфигмапе использование прокси, добавляем список адресов Cloudfront и перезаписываем the_real_ip:
kubectl edit configmap nginx-ingress-controller -n kube-system
data:
...
  # curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq  -r '.prefixes[] | select(.service=="CLOUDFRONT") | .ip_prefix' | awk '{print $1}'
  proxy-real-ip-cidr: "54.155.0.0/16,172.96.98.0/24..."
  http-snippet: |
    map '' $the_real_ip {
      default          $http_x_forwarded_for;

    }
  use-proxy-protocol: "true"

Собственно говоря после этого все.
Идем в логи контроллера и смотрим адреса с которого приходят запросы:
kubectl logs -f nginx-ingress-controller-56f4bf4dc9-5pqjn
1.1.1.1 - [1.1.1.1] - - [22/Jan/2019:18:58:23 +0000] "GET /ping HTTP/1.1" 503 197 "-" "Wget" 85 0.000 [-]

В самом конфиге ингресса добавляем:
    nginx.ingress.kubernetes.io/server-snippet: |
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;