Как запретить доступ к ресурсам на основе заголовков X-forwarded-for


13

Я пытаюсь ограничить доступ к ресурсам за Nginx на основе IP-адреса клиента, переданного в заголовках X-forwarded-for. Nginx работает в контейнере в кластере Kubernetes на облачной платформе Google, а реальные 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 Load Balancing, я обнаружил следующее: X-Forwarded-For: <unverified IP(s)>, <immediate client IP>, <global forwarding rule external IP>, <proxies running in GCP> (requests only) Запись <немедленный IP-адрес клиента> - это клиент, подключенный напрямую к балансировщику нагрузки.
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карту, где значение по умолчанию для $allow0. Если 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но это не имело никакого значения
p1hr

Вы имеете в виду, что ваш X-Forwarded-Forзаголовок имеет три отдельных адреса, то есть запрос поступает через несколько прокси? У вас есть другой заголовок, который вы можете использовать, который содержит только IP-адрес клиента?
Теро Килканен

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

FWIW, эта комбинация не работает для меня с AWS ALB. Что работало, так это использование директивы proxy внутри геоблока с тем же 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.