Назад | Перейти на главную страницу

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

Я пытаюсь ограничить доступ к ресурсам за Nginx на основе IP-адреса клиента, переданного в заголовках X-forwarded-for. Nginx работает в контейнере в кластере Kubernetes на облачной платформе Google, и реальные IP-адреса клиента передаются только в заголовке 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-адресов вручную не имеет большого смысла.

Любая помощь приветствуется

Используйте модуль RealIP, чтобы соблюдать значение X-Forwarded-For заголовок. Устанавливать set_real_ip_from на IP-адрес обратного прокси (текущее значение $remote_addr).

Например:

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

Теперь вы можете использовать $remote_addr и allow/deny директивы с использованием истинного IP-адреса клиента. Видеть этот документ для большего.

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

Между тем, что касается указания диапазонов IP-адресов, вы можете использовать http://nginx.org/en/docs/http/ngx_http_geo_module.html.

В geo модуль работает как map module, то есть переменной присваиваются значения в зависимости от значения 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 block, поскольку вам нужно определить диапазоны IP-адресов.

У меня это работает.

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