Nginx real_ip: получить IP клиента за прокси

Категория: Nginx · Обновлено:

Если перед Nginx стоит балансировщик, CDN или другой прокси, $remote_addr показывает адрес прокси, а не клиента. Модуль realip подменяет его адресом из доверенного заголовка. После этого логи, rate limit и приложение видят настоящий IP, но только при правильной настройке доверенных сетей.

Взять IP из X-Forwarded-For

Текст
server {
    listen 80;

    set_real_ip_from 10.0.0.0/8;
    set_real_ip_from 172.16.0.0/12;
    set_real_ip_from 192.168.0.0/16;

    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

    location / {
        proxy_pass http://backend;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

set_real_ip_from перечисляет только те сети, от которых вы действительно принимаете трафик. Если добавить 0.0.0.0/0, любой клиент сможет подставить чужой IP в заголовок и обойти rate limit или подделать аудит. Для Docker-сети укажите её подсеть, для Cloudflare — актуальные диапазоны из официального списка.

real_ip_recursive on проходит по цепочке X-Forwarded-For справа налево и пропускает доверенные адреса, пока не найдёт клиентский. Без рекурсии берётся первый адрес из заголовка, который может быть подставлен клиентом. Для Cloudflare используйте CF-Connecting-IP, для AWS ALB — X-Forwarded-For; проверьте, какой заголовок гарантирует ваш провайдер.

После замены $remote_addr в логах появится клиентский адрес, а $proxy_add_x_forwarded_for добавит его в цепочку для бэкенда. Приложение должно доверять только Nginx и не принимать X-Forwarded-For напрямую из интернета. Для IPv6 добавьте соответствующие префиксы и проверьте, что заголовок не смешивает IPv4 и IPv6.

Модуль ngx_http_realip_module входит в стандартные сборки Nginx; проверьте nginx -V. Не включайте real_ip_header proxy_protocol, если PROXY protocol не настроен на балансировщике: соединения будут отклоняться.

Документация: ngx_http_realip_module, Cloudflare IP ranges.