Як заборонити доступ до ресурсів на основі заголовків X-forwarded-for


13

Я намагаюся обмежити доступ до ресурсів Nginx на основі IP-адреси клієнта, переданого в заголовках X-forwarded-for. Nginx працює в контейнері на кластері Kubernetes на платформі Google Cloud, і справжні ips клієнта передаються лише в заголовку x-forwarded-for

Поки що мені вдалося зробити це для одного IP з наступним кодом:

set $allow false;
if ($http_x_forwarded_for ~* 123.233.233.123) {
    set $allow true;
}
if ($http_x_forward_for ~* 10.20.30.40) {
    set $allow false;
}
if ($allow = false) {
    return 403;
}

Але як я можу це зробити для цілого діапазону IP-адрес? Вказувати сотні IP-адрес вручну не має особливого сенсу.

Вся допомога вдячна

Відповіді:


11

Використовуйте модуль RealIP, щоб відзначити значення X-Forwarded-Forзаголовка. Встановіть set_real_ip_fromIP-адресу зворотного проксі-сервера (поточне значення $remote_addr).

Наприклад:

server {
    ...
    real_ip_header X-Forwarded-For;
    set_real_ip_from 10.1.2.3;
    ...
}

Тепер ви маєте можливість використовувати $remote_addrта allow/ denyдирективи, використовуючи справжню IP-адресу клієнта. Докладніше дивіться цей документ .


тому я спробував наступне безрезультатно, чи я плутаю це? location / { real_ip_header X-Forwarded-For; set_real_ip_from 10.0.0.0/8; real_ip_recursive on; allow xxx.xxx.xxx.xxx;
p1hr

Переглянувши документи з балансування завантаження Google, я виявив наступне: X-Forwarded-For: <unverified IP(s)>, <immediate client IP>, <global forwarding rule external IP>, <proxies running in GCP> (requests only) <Запис <безпосередній клієнт> це клієнт, який підключився безпосередньо до балансира навантаження.
p1hr

1
Для цього на роботу, вам необхідно визначити діапазони адрес для <global forwarding rule external IP>і <proxies running in GCP>і додати set_real_ip_fromзаяви , що охоплюють всі з них.
Річард Сміт

<global forwarding rule external IP>це зовнішній ip мого сервісу, в GCP немає інших проксі, у моїх журналах nginx я бачу запити у такому форматі, [31/Jul/2017:20:05:46 +0000] "GET / HTTP/1.1" 403 169 "-" "curl/7.54.0" "aaa.aaa.aaa.aaa, bbb.bbb.bbb.bbb, ccc.ccc.ccc.ccc"де ccc.ccc.ccc.ccc - глобальне правило пересилання, bbb.bbb.bbb.bbb - безпосередній клієнт ip - відповідає тому, що я бачу на whatsmyip.org. Ви можете порадити, як витягти цю частину?
p1hr

1
Гаразд, зараз я заплутався. Вам потрібно set_real_ip_fromдля всіх адрес праворуч від тієї, яку ви хочете дозволити / заборонити. Як зазначено в real_ip_recursiveрозділі.
Річард Сміт

5

Відповідь Річарда вже містила інформацію про те, як найкраще дістати реальну IP-адресу до nginx.

Тим часом, що стосується питання про визначення діапазонів IP, ви можете скористатись http://nginx.org/en/docs/http/ngx_http_geo_module.html .

У geoмодуль працює , як mapмодуль, тобто змінна отримує присвоюватися значення в залежності від значення IP - адреси.

Приклад:

geo $allow {
    default 0;
    192.168.168.0/24 1;
}

server {
    real_ip_header X-Forwarded-For;
    set_real_ip_from 10.1.2.3;

    if ($allow = 0) {
        return 403;
    }
}

Тут ми призначаємо geoкарту, де значенням за замовчуванням $allowє 0. Якщо IP-адреса знаходиться в підмережі 192.168.168.0/24, то $allowотримає значення 1, і запит дозволений.

У geoблоці може бути стільки рядків, скільки потрібно для визначення діапазонів IP.


Дякую! що, здається, працює дуже добре, останнє, з чим я стикаюся, це те, що client_ip від X-forwarded-for. На даний момент з 3-х ip-адрес, які були передані, використовується останній. Я додав real_ip_recursive on;нижче, set_real_ip_fromале це нічого не
змінило

Ви маєте на увазі, що ваш X-Forwarded-Forзаголовок має три окремі адреси, тобто запит надходить через декілька проксі-серверів? У вас є якийсь інший заголовок, який ви можете використовувати, який містить лише клієнтський IP?
Tero Kilkanen

Кожен проксі в ланцюжку додасть до X-Forwarded-Forзаголовка свою IP-адресу . Крім додавання real_ip_recursive onвам також потрібно додати set_real_ip_fromдирективи для IP-адреси кожного довіреного сервера у вашій ланцюзі проксі-серверів. Потім Nginx буде переробляти кожну з цих директив і повертати клієнтський IP як перше значення, яке воно потрапляє в X-Forwarded-Forзаголовок, яке не відповідає жодному із заданих вами set_real_ip_fromзначень
miknik

FWIW, ця комбінація не працювала для мене з AWS ALB. Що працювало, використовуючи директиву проксі всередині геоблоку, з тим самим ip, що і set_real_ip - nginx.org/en/docs/http/ngx_http_geo_module.html
talonx

3

Зробили ці роботи для мене.

geo $remote_addr $giveaccess {
      proxy 172.0.0.0/8; <-- Private IP range here
      default 0;
      11.22.33.44 1; <-- Allowed IP here
    }


server{
##
    location ^~ /secure_url_here {
        if ($giveaccess = 0){
          return 403; 
        }
        try_files $uri $uri/ /index.php?$args; <-- Add this line specific for your CMS, if required.
    }

Посилання: http://nginx.org/en/docs/http/ngx_http_geo_module.html

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.