Перейти к содержанию

Идентификация IP‑адреса клиента при использовании балансировщика или прокси (NGINX)

В данной инструкции описаны настройки NGINX, необходимые для корректного определения IP‑адреса источника запроса (IP‑адреса клиента), если в вашей системе настроен прокси‑сервер или балансировщик нагрузки.

  • Если нода установлена из пакетов DEB / RPM, образа AWS / GCP / Яндекс.Облака или Docker‑контейнера на основе NGINX, используйте данную инструкцию.

  • Если нода установлена в форме Ingress‑контроллера K8s, используйте инструкцию.

  • Если нода установлена в форме sidecar‑контейнера K8s, необходимая конфигурация описана в инструкциях по установке с использованием Helm Charts и Kubernetes‑манифестов.

Как нода определяет IP‑адрес источника запроса

По умолчанию NGINX сохраняет IP‑адрес источника запроса в переменную $remote_addr. При анализе запроса нода получает данные об источнике запроса из этой переменной. Если перед передачей на ноду запрос прошел через прокси‑сервер или балансировщик нагрузки, в переменную $remote_addr записывается адрес прокси‑сервера или балансировщика нагрузки и нода определяет его как адрес источника запроса.

Использование балансировщика

IP‑адрес источника запроса, который определила нода, отображается в информации об атаке в Консоли управления Валарм.

Возможные проблемы при использовании IP‑адреса балансировщика или прокси

Если нода использует IP‑адрес балансировщика нагрузки или прокси‑сервера в качестве адреса источника запроса, следующие возможности Валарм могут работать некорректно:

  • Управление доступом к приложениям по IP‑адресам. Например:

    Нода не будет блокировать запросы, отправленные с IP‑адресов реальных клиентов из черного списка. При анализе запроса нода определит адрес балансировщика нагрузки в качестве адреса клиента и пропустит запрос к приложению.

  • Защита от брутфорс атак. Например:

    При обнаружении признаков брутфорс атаки среди запросов, которые прошли через балансировщик нагрузки, Валарм добавит в черный список IP‑адрес источника брутфорса, а именно: IP‑адрес балансировщика нагрузки. Нода будет блокировать все следующие запросы, которые прошли через балансировщик нагрузки с заблокированным адресом.

  • Перепроверка атак и Сканер уязвимостей. Например:

    Валарм определит IP‑адрес балансировщика нагрузки как адрес источника тестовых атак, сгенерированных модулем перепроверки атак и Сканером уязвимостей. Так как IP‑адрес балансировщика нагрузки не совпадает с адресами Валарм, тестовые атаки будут считаться реальными. Валарм отобразит тестовые атаки как отдельные события в Консоли управления Валарм и будет их перепроверять, что может привести к росту нагрузки на ваши приложения.

Если нода подключена через IPC‑сокеты, в качестве источника запросов будет определяться адрес 0.0.0.0.

Настройки для идентификации исходного IP‑адреса источника запроса

Нода Валарм получает IP‑адрес источника запроса из переменной NGINX $remote_addr. Чтобы в переменную записывался исходный адрес источника запроса, необходимо переопределить значение переменной с помощью модуля NGINX ngx_http_realip_module.

Модуль NGINX ngx_http_realip_module позволяет получить исходный адрес источника запроса и записать его в переменную $remote_addr одним из следующих способов:

  • Прочитать исходный адрес из специального заголовка, который балансировщик нагрузки или прокси‑сервер добавляет в запрос. Чаще всего заголовок называется X-Forwarded-For.

  • Если балансировщик нагрузки или прокси‑сервер поддерживает протокол PROXY, прочитать исходный адрес из заголовка PROXY.

Настройка NGINX для чтения заголовка X-Forwarded-For (X-Real-IP или другого)

Если балансировщик нагрузки или прокси‑сервер передает исходный IP‑адрес источника запроса в отдельном заголовке (X-Forwarded-For, X-Real-IP или другом), необходимо настроить модуль ngx_http_realip_module для чтения такого заголовка.

Для чтения заголовка X-Forwarded-For (X-Real-IP или другого) необходимо выполнить следующую конфигурацию NGINX на ноде Валарм:

  1. Откройте для редактирования файл с настройками NGINX:

    • /etc/nginx/conf.d/default.conf, если нода установлена из пакетов DEB / RPM.
    • /etc/nginx/nginx.conf, если нода установлена из образа AWS / GCP / Яндекс.Облака.
    • Если нода установлена из Docker‑образа на основе NGINX, необходимо создать конфигурационный файл NGINX локально и описать в нем все настройки, включая приведенные ниже. Готовый конфигурационный файл необходимо примонтировать в Docker‑контейнер по пути /etc/nginx/sites-enabled/default. Пример конфигурационного файла NGINX и команда для запуска контейнера с примонтированным файлом приведены в инструкции для Docker.
  2. В блок location или выше добавьте директиву set_real_ip_from с адресом балансировщика нагрузки или прокси‑сервера. Если у балансировщика или прокси‑сервера может быть несколько адресов, добавьте несколько директив. Например:

    ...
    location / {
        wallarm_mode block;
    
        set_real_ip_from 1.2.3.4;
        set_real_ip_from 192.0.2.0/24;
    }
    ...
    
  3. Определите, в каком заголовке балансировщик нагрузки передает реальный IP-адрес клиента. Для этого обратитесь к документации на используемый балансировщик нагрузки. Чаще всего используется заголовок X-Forwarded-For.

  4. В блок location или выше добавьте директиву real_ip_header с названием заголовка, в котором балансировщик нагрузки или прокси‑сервер передает реальный IP-адрес клиента. Например:

    ...
    location / {
        wallarm_mode block;
    
        set_real_ip_from 1.2.3.4;
        set_real_ip_from 192.0.2.0/24;
        real_ip_header X-Forwarded-For;
    }
    ...
    
  5. Перезапустите NGINX:

    sudo systemctl restart nginx
    
    sudo service nginx restart
    
    sudo systemctl restart nginx
    

    Теперь NGINX будет записывать значение указанного заголовка в переменную $remote_addr, таким образом нода прочитает из переменной исходный адрес источника.

  6. Проверьте результат.

Настройка NGINX для чтения заголовка PROXY

Если балансировщик нагрузки поддерживает протокол PROXY, вы можете настроить настроить модуль ngx_http_realip_module для чтения заголовка PROXY.

Для чтения заголовка PROXY необходимо выполнить следующую конфигурацию NGINX на ноде Валарм:

  1. Откройте для редактирования файл с настройками NGINX:

    • /etc/nginx/conf.d/default.conf, если нода установлена из пакетов DEB / RPM.
    • /etc/nginx/nginx.conf, если нода установлена из образа AWS / GCP / Яндекс.Облака.
    • Если нода установлена из Docker‑образа на основе NGINX, необходимо создать конфигурационный файл NGINX локально и описать в нем все настройки, включая приведенные ниже. Готовый конфигурационный файл необходимо примонтировать в Docker‑контейнер по пути /etc/nginx/sites-enabled/default. Пример конфигурационного файла NGINX и команда для запуска контейнера с примонтированным файлом приведены в инструкции для Docker.
  2. В блок server добавьте параметр proxy_protocol в директиву listen.

  3. В блок location или выше добавьте директиву set_real_ip_from с адресом балансировщика нагрузки или прокси‑сервера. Если у балансировщика или прокси‑сервера может быть несколько адресов, добавьте несколько директив. Например:

  4. В блок location или выше добавьте директиву real_ip_header со значением proxy_protocol.

    Пример конфигурационного файла NGINX со всеми директивами:

    server {
        listen 80 proxy_protocol;
        server_name localhost;
    
        set_real_ip_from <IP_ADDRESS_OF_YOUR_PROXY>;
        real_ip_header proxy_protocol;
    
        ...
    }
    
    • NGINX принимает соединение на порту 80.
    • Если во входящем запросе нет заголовка PROXY, NGINX определит запрос как невалидный.
    • NGINX запишет адрес источника из заголовка PROXY запроса, полученного с <IP_ADDRESS_OF_YOUR_PROXY>, в переменную $remote_addr. Таким образом нода прочитает из переменной исходный адрес источника.
  5. Перезапустите NGINX:

    sudo systemctl restart nginx
    
    sudo service nginx restart
    
    sudo systemctl restart nginx
    
  6. Проверьте результат.

Чтобы записывать исходный IP‑адрес клиента в логи, необходимо добавить директиву proxy_set_header и обновить список переменных в директиве log_format в конфигурации NGINX. Подробнее в инструкции по логированию в NGINX

Более подробная инструкция по идентификации исходного адреса источника запроса для протокола PROXY доступна в документации NGINX.

Проверка результата

  1. Отправьте тестовую атаку на адрес защищенного приложения. Например:

    curl http://localhost/?id='or+1=1--a-<script>prompt(1)</script>'
    
    printf "PROXY TCP4 <IP_ADDRESS_OF_YOUR_PROXY> <REAL_CLIENT_IP> 0 80\r\nGET /?id=or+1=1--a-<script>prompt(1)</script>\r\n\r\n" | nc localhost 80
    
  2. Перейдите в Консоль управления Валарм и убедитесь, что в информации об атаке отображатся исходный IP‑адрес источника запроса:

    IP‑адрес, с которого отправлен запрос

    Если NGINX прочитал адрес источника из заголовка X-Forwarded-For (X-Real-IP или другого), значение заголовка также отобразится в информации о запросе в сыром формате.

    Заголовок X-Forwarded-For в заголовке

Примеры настроек

Ниже приведены примеры настроек NGINX для идентификации исходного IP‑адреса клиента при использовании известных балансировщиков нагрузки.

Cloudflare CDN

Если вы используете Cloudflare CDN, вы можете настроить передачу реального адреса клиента, используя модуль NGINX ngx_http_realip_module:

...
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2c0f:f248::/32;
set_real_ip_from 2a06:98c0::/29;

real_ip_header CF-Connecting-IP;
#real_ip_header X-Forwarded-For;
real_ip_recursive on;
...
  • Перед применением конфигурации, необходимо соотнести список адресов в директивах set_real_ip_from с актуальным списком в документации Cloudflare.

  • В значении real_ip_header вы можете передать как CF-Connecting-IP, так и X-Forwarded-For. Cloudflare CDN передает адрес реального клиента в обоих заголовках, нода также прочитает любой из них. Подробнее в документации Cloudflare

Fastly CDN

Если вы используете Fastly CDN, вы можете настроить передачу реального адреса клиента, используя модуль NGINX ngx_http_realip_module:

...
set_real_ip_from 23.235.32.0/20;
set_real_ip_from 43.249.72.0/22;
set_real_ip_from 103.244.50.0/24;
set_real_ip_from 103.245.222.0/23;
set_real_ip_from 103.245.224.0/24;
set_real_ip_from 104.156.80.0/20;
set_real_ip_from 146.75.0.0/16;
set_real_ip_from 151.101.0.0/16;
set_real_ip_from 157.52.64.0/18;
set_real_ip_from 167.82.0.0/17;
set_real_ip_from 167.82.128.0/20;
set_real_ip_from 167.82.160.0/20;
set_real_ip_from 167.82.224.0/20;
set_real_ip_from 172.111.64.0/18;
set_real_ip_from 185.31.16.0/22;
set_real_ip_from 199.27.72.0/21;
set_real_ip_from 199.232.0.0/16;
set_real_ip_from 2a04:4e40::/32;
set_real_ip_from 2a04:4e42::/32;

real_ip_header X-Forwarded-For;
real_ip_recursive on;
...

Перед применением конфигурации, необходимо соотнести список адресов в директивах set_real_ip_from с актуальным списком в документации Fastly.

HAProxy

Если вы используете HAProxy, для определения исходного адреса клиента необходимо выполнить настройку как на стороне HAProxy, так и на стороне NGINX, установленного с нодой Валарм:

  • В конфигурационном файле /etc/haproxy/haproxy.cfg вставьте строку option forwardfor header X-Client-IP в блок директивы backend, отвечающий за связь HAProxy с нодой Валарм.

    Директива option forwardfor сообщает балансировщику HAProxy о том, что в запрос необходимо добавить заголовок со значением IP‑адреса клиента. Подробнее в документации HAProxy

    Например:

    ...
    # Публичный IP‑адрес для получения запросов
    frontend my_frontend
        bind <HAPROXY_IP>
        mode http
        default_backend my_backend
    
    # Бэкенд с нодой Валарм
    backend my_backend
        mode http
    option forwardfor header X-Client-IP
    server wallarm-node <WALLARM_NODE_IP>
    ...
    
    • <HAPROXY_IP> — IP‑адрес прокси‑сервера HAProxy, на который он принимает запросы от клиентов.
    • <WALLARM_NODE_IP> — IP‑адрес ноды Валарм, на который она принимает запросы от HAProxy.
  • В конфигурационном файле NGINX на ноде Валарм выполните настройку модуля NGINX ngx_http_realip_module. Например:

    ...
    location / {
        wallarm_mode block;
    
        proxy_pass http://<APPLICATION_IP>;        
        set_real_ip_from <HAPROXY_IP1>;
        set_real_ip_from <HAPROXY_IP2>;
        real_ip_header X-Client-IP;
    }
    ...
    
    • <APPLICATION_IP> — IP‑адрес защищаемого приложения, на который оно принимает запросы от ноды.
    • <HAPROXY_IP1> и <HAPROXY_IP2> — IP‑адреса прокси‑серверов, с которых они отправляют запросы на ноду Валарм.