Продолжаем ковырять nginx и перекладывать на него функции с apache. В общем-то, у апача я давно не использую описанную здесь функцию, поэтому и забыл написать.
Формально, в nginx существует 2 способа ограничить доступ по ip. Первый — вполне привычные директивы — deny/allow. Второй — очень удобный для ограничения доступа в куче мест — geo переменные.
С deny/allow всё понятно, использовать их можно-нужно так же, как в любом другом веб-сервере:
1 2 3 4 |
deny 192.168.0.1; allow 192.168.0.1/24; allow 8.8.8.8; deny all; |
Эти строчки можно вписать почти в любой кусок конфига — начиная с http {} (тогда правила распространятся на весь сервер) и заканчивая отдельным location {}.
Второй способ уже интереснее и не встречается в apache. Как вы знаете, в nginx можно очень удобно работать с любыми переменными. А в переменные писать что угодно. Так вот — почему бы не делать что-либо в зависимости от того, какой IP адрес у посетителя? Прелесть такого варианта в том, что мы можем отдавать не 403ю ошибку, как в первом способе, а 404ю. Или редиректить на другой сайт. Или ещё-что нибудь… ну и так далее.
Собственно говоря, выглядит это так. Пишем в секцию http {} (для того, чтобы эту переменную мы могли использовать в любом server {} ):
1 2 3 4 5 6 7 8 9 10 11 |
geo $accessvar { default 0; # 1 = бухгалтеры 192.168.1.0/24 1; # 2 = манагеры 192.168.2.0/24 2; # 3 = веб-серверы 1.1.1.1 3; 2.2.2.2 3; 4.4.4.4 3; } |
Что мы в итоге написали. Если кто-то придет из подсети 192.168.1.0/24 — то переменная $accessvar выставляется в 1. Если из 192.168.2.0/24 — то в 2. Если пришла машина с IP адресом 1.1.1.1/2.2.2.2/4.4.4.4 — то переменная выставляется в 3. Если какой-то другой адрес — то 0.
При помощи if-ов мы можем юзать эти штуки уже как угодно. Например, у нас есть сайт internal.company.name для сотрудников (и для серверов, чтобы они забирали оттуда какую-либо информацию для обновления сайтов). И сайт compmany.com, на который должны попадать посетители.
Случайных посетителей сайта internal будем редиректить на правильный сайт:
1 2 3 4 5 6 7 8 |
server { ... if ($accessvar = 0) { rewrite ^/(.*) http://company.name permanent; } ... } |
Это, кстати, спасет и от надоедливых ботов, которые игнорируют robots.txt.
Далее. У нас есть 3 location:
/buh — сюда нам нужно пускать только бухгалтеров (ну там морда “1С:Підприємство”, например)
/manager — сюда только менеджеров
/export — сюда только серверы.
Представляете, какой вам ад пришлось бы разводить в конфигах, чтобы добиться этого с access/deny )? А тут вам нужно только поддерживать актуальный список адресов в одном месте. Можно сочетать с VPN, чтобы адреса точно нужные были =)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
server { ... location /buh { if ($accessvar != 1) { return 404; } location /manager{ if ($accessvar != 2) { return 404; } location /export { if ($accessvar != 3) { return 404; } ... } |
Ну и не забываем порестартить nginx:
1 |
/etc/init.d/nginx restart |
Помните, deny/access работает быстрее, но обладает очень узким функционалом. Но от ddos’a оно не спасет тоже — от ддоса лучше защищаться файрволлом. Поэтому переменные geo имеют право на существование. При этом они куда более удобны при правильном использовании. Кстати, можно создавать сразу именованные переменные — buh, manager, server, например =)
Джерело: https://debian.pro/726
Внятная статья. Все понятно объяснено без воды, а главное – работает! Спасибо!