nginx: додаткові умови до обмеження по geoip

Posted on

Хоч nginx не має вкладених ifʼів та складних умов (test1 and/or test2) — ми можемо комбінувати різні умови в одну змінну, потім її використовувати.

Наприклад, типова конфігурація:

map $geoip2_data_country_iso_code $allowed_country {
  default no;
  UA      yes;
}

#...

location /restricted-area {
  if ($allowed_country = no) {
    return 403;
  }
  # ...
}

Тут ми забороняємо доступ звідусіль крім України.

Ситуація 1. Припустимо, ми хочемо також дозволити доступ з окремих міст Європи. Тоді ми доповнюємо цю конфігурацію таким чином:

map $geoip2_data_country_iso_code $allowed_country {
  default no;
  UA      yes;
}

map $geoip2_data_city_name $allowed_city {
  default $allowed_country;
  Krakow  yes;
  Gdansk  yes;
}

#...

location /restricted-area {
  if ($allowed_city = no) {
    return 403;
  }
  # ...
}

Ситуація 2. Скажімо, ми хочемо додати не кілька міст, а кілька діапазонів адрес не з України.

Для цього ми можемо використовувати модуль ngx_http_geo_module. Цей модуль може присвоювати значення змінній залежно від $remote_addr, наприклад:

geo $allowed_source {
  default    no;
  # Our friend somewhere in Mars:
  1.2.3.0/24 yes;
  # Another stranger:
  4.5.6.0/24 yes;
}

Проте ми не можемо в ньому написати default $allowed_country, як у першій ситуації, бо рядок $allowed_country буде сприйнято як рядок, і в написаній у блоці location умові він не дорівнює no, отже, доступ матимуть геть усі (звичайно, можна інкаше порівнювати значення змінної, але ця конфігурація все одно робить не те, що ми хочемо).

Але натомість ми можемо зробити навпаки, використати $allowed_source для визначення $allowed_country:

geo $allowed_source {
  default no;
  # Our friend somewhere in Mars:
  1.2.3.0/24 yes;
  # Another stranger:
  4.5.6.0/24 yes;
}

map $geoip2_data_country_iso_code $allowed_country {
  default $allowed_source;
  UA      yes;
}

#...

location /restricted-area {
  if ($allowed_country = no) {
    return 403;
  }
  # ...
}

Це працює :)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.