Хоч 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; } # ... }
Це працює :)