Получение “реального” IP в Nginx за сетью балансировщика нагрузки AWS

Вопрос или проблема

У меня есть сетевой балансировщик нагрузки, который перенаправляет трафик на контейнер Nginx, работающий в ECS (используя режим сети awsvpc). Моя конфигурация nginx выглядит следующим образом:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log info;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    server {
        allow all;
        listen 443 default ssl;
        ssl_certificate /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/privkey.pem;
        ssl_trusted_certificate /etc/nginx/ssl/chain.pem;

        ssl_prefer_server_ciphers on;
        ssl_protocols TLSv1.2;

        add_header Strict-Transport-Security "max-age=31536000";
        access_log /var/log/nginx/access.log;

        location / {
            proxy_pass http://blahblahblah;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr, $proxy_add_x_forwarded_for;
        }
    }
}

Однако, когда я смотрю логи, заголовок X-Forwarded-For не содержит “реальный” IP клиента, он просто содержит ряд внутренних IP (один из которых является внутренним IP сетевого балансировщика).

Я понимаю, что сетевой балансировщик нагрузки должен был сохранять “реальный” IP клиента как входящий IP, почему он не отображается в этом заголовке?

https://aws.amazon.com/blogs/aws/new-network-load-balancer-effortless-scaling-to-millions-of-requests-per-second/

Сохранение исходного адреса – С помощью сетевого балансировщика нагрузки исходный IP-адрес и порты источника для входящих соединений остаются неизменными, поэтому программное обеспечение приложения не обязано поддерживать X-Forwarded-For, прокси-протокол или другие обходные пути. Это также означает, что можно использовать обычные правила межсетевого экрана, включая группы безопасности VPC, на целевых экземплярах.

nginx начал поддерживать PROXY-протокол v2 с версии 1.13.11, что произошло примерно через месяц после вашего вопроса. Я столкнулся с этой проблемой сегодня, поэтому, если это будет полезно для кого-то еще:

http {
    #...
    server {
        listen 80   proxy_protocol;
        listen 443  ssl proxy_protocol;
        #...
    }
}
   
stream {
    #...
    server {
        listen 12345 proxy_protocol;
        #...
    }
}

Добавьте proxy_protocol к вашему слушателю. Это позволит вашему nginx принимать подключения по Proxy Protocol V2.

Если вы используете AWS LB, вам необходимо включить Proxy protocol v2 в вашей группе целевых экземпляров:

(Опция “Сохранить IP-адреса клиентов” не кажется необходимой, $proxy_protocol_addr отображается корректно в логах).

В вашем блоке location конфигурации nginx добавьте следующее:

real_ip_header X-Forwarded-For;
set_real_ip_from <вставьте IP-адрес балансировщика нагрузки>;

Вы можете найти IP-адрес ELB в разделе “Сетевые интерфейсы” в EC2.

Пример:

location ~ \.php$ {
    ........
    real_ip_header X-Forwarded-For;
    set_real_ip_from 10.0.1.192;
}

Ответ или решение

Чтобы получить "реальный" IP-адрес клиента в Nginx, работающем за сетевым балансировщиком нагрузки (NLB) AWS, необходимо правильно настроить Nginx для обработки заголовка X-Forwarded-For и/или использовать протокол Proxy. Рассмотрим шаги, которые необходимо выполнить.

Шаг 1: Включение протокола Proxy

Для начала убедитесь, что ваш сервер Nginx настроен на принятие соединений через протокол Proxy. Это можно сделать, добавив proxy_protocol в конфигурацию слушателей для портов 80 и 443 вашего Nginx, как показано ниже:

http {
    server {
        listen 80 proxy_protocol;
        listen 443 ssl proxy_protocol;

        ssl_certificate /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/privkey.pem;

        # Другие настройки...
    }
}

Шаг 2: Включение поддержки протокола Proxy в Target Group NLB

После того, как вы добавили proxy_protocol в конфигурацию Nginx, вам нужно убедиться, что в вашей группе целей (Target Group) NLB включена поддержка протокола Proxy. Для этого:

  1. Перейдите в консоль управления AWS.
  2. Найдите вашу группу целей.
  3. В настройках группы установите опцию для активации поддержки протокола Proxy V2.

Шаг 3: Настройка заголовка real_ip

Кроме того, вам нужно настроить Nginx так, чтобы он правильно обрабатывал заголовок X-Forwarded-For. Добавьте следующие строки в ваш блок location внутри конфигурации сервера:

location / {
    proxy_pass http://blahblahblah;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # Настройка для получения реального IP клиента
    real_ip_header X-Forwarded-For;
    set_real_ip_from <IP-адрес вашего сетевого балансировщика>; # Укажите внутренний IP адрес вашего NLB
}

Шаг 4: Найдите внутренний IP-адрес NLB

Чтобы найти внутренний IP-адрес вашего сетевого балансировщика, выполните следующие шаги:

  1. Перейдите в консоль EC2 в раздел "Сетевые интерфейсы" (Network Interfaces).
  2. Найдите сетевой интерфейс, связанный с вашим NLB, и запишите его внутренний IP-адрес.

Пример полной конфигурации

Ниже приведен пример полной конфигурации Nginx с включением всех вышеуказанных шагов:

worker_processes 1;

error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    server {
        listen 80 proxy_protocol;
        listen 443 ssl proxy_protocol;

        ssl_certificate /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/privkey.pem;
        ssl_trusted_certificate /etc/nginx/ssl/chain.pem;

        ssl_prefer_server_ciphers on;
        ssl_protocols TLSv1.2;

        add_header Strict-Transport-Security "max-age=31536000";
        access_log /var/log/nginx/access.log;

        location / {
            proxy_pass http://blahblahblah;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            # Получаем реальный IP
            real_ip_header X-Forwarded-For;
            set_real_ip_from <IP-адрес вашего сетевого балансировщика>;
        }
    }
}

Заключение

Следуя указанным шагам, вы сможете настроить Nginx для правильной обработки реального IP-адреса клиента, даже когда он находится за сетевым балансировщиком нагрузки AWS. Убедитесь, что вы проверили вашу конфигурацию и перезапустили Nginx для применения изменений.

Оцените материал
Добавить комментарий

Капча загружается...