Блокировка доступа к NGINX

Блокировка доступа к NGINX

Roman Bogachev VMware Specialist | Drone Pilot | Traveler

Способы ограничения доступа к ресурсу в NGINX

Блокировка по User Agent`у

Я использую эту технику, прежде всего, для защиты от роботов, которые игнорируют настройки в моем файле robots.txt.

1
2
3
4
if ($http_user_agent ~ "Windows 95|Windows 98|xpymep|TurnitinBot|sindice|Purebot|libwww-perl")  {                                                                
return 403;
break;
}

Я выбрал для блокирования libwww-Perl, потому что в последние несколько лет, я не видел ни GET или POST по libwww-Perl, вероятно пробовали использовать какую-то уязвимость ПО.

Блокировка по IP-адресу

1
2
3
4
5
6
7
8
9
10
11
12
deny 85.17.26.68;     # spam
deny 85.17.230.23; # spam
deny 173.234.11.105; # junk referrers
deny 173.234.31.9; # junk referrers
deny 173.234.38.25; # spam
deny 173.234.153.30; # junk referrers
deny 173.234.153.106; # spam
deny 173.234.175.68; # spam
deny 190.152.223.27; # junk referrers
deny 195.191.54.90; # odd behaviour, Mozilla, doesnt fetch js/css. Ended up doing a POST, prob a spambot
deny 195.229.241.174; # spammy comments
deny 210.212.194.60; # junk referrers + spam

Блокировка по запросу

Кроме того, можно заблокировать доступ на основе информации которая отправляется в заголовках HTTP.

1
2
3
if ($http_referer ~* (viagra|sex|porn|) ) {
return 403;
}

Я использую ключ ~* для того чтобы предотвратить запрос GET по указанным словам во всей строке.

Блокировка по подсети

1
2
3
deny 69.28.58.0/24;   # spam
deny 79.142.64.0/20; # spam
deny 80.67.0.0/20; # spam

Блокировка по геолокации

Мы можем заблокировать целые страны, основанные на данных GeoIP предоставляемых MaxMind.
Необходимо, чтобы NGINX имел модуль GeoIP.
Во-первых, вы должны обозначить NGINX где база данных GeoIP находится в файловой системе.
Вы можете сделать это внутри HTTP {};
Конфигурация блока:

geoip_country /etc/nginx/GeoIP.dat;

Теперь сообщаем NGINX страны которые необходимо заблокировать:

1
2
3
if ($geoip_country_code ~ (BR|CN|KR|RU) ) {
return 403;
}

Блокировка по паролю

В конфигурационном файле, в папке, которую хотим закрыть надо только указать файл, где хранятся пароли. Вот два примера для закрытия папки с файлами:

1
2
3
4
5
6
7
8
location ^~ /files/ {
root /path/to/server;
autoindex on;
autoindex_exact_size off;
auth_basic "Hello, please login";
auth_basic_user_file /usr/nginx/passwords;
access_log /usr/nginx/logs/files.log download;
}

либо админки с ограничением по IP-адресу:

1
2
3
4
5
6
7
8
9
10
location ^~ /admin/ {
fastcgi_pass unix:/home/project/server.sock;
include conf/fastcgi.conf;
allow 11.11.0.0/16;
allow 22.22.22.22;
deny all;
auth_basic "Hello, Admin, please login";
auth_basic_user_file /usr/nginx/adminpassword;
access_log /usr/nginx/logs/admin.log main;
}

Добавить пользователя можно с помощью стандартной утилиты от apache:

1
htpasswd -b passwords NewUser NewPassword

В файле запись с зашифрованным паролем имеет вид NewUser:P47ghZ4kloG78: #Your Can Comment Here

Защиту от перебора паролей можно организовать одновременно двумя методами, основанными на использовании iptables:

  • Блокирование IP на время, если количество запросов в секунду превышает какое-либо разумное количество
  • Вести лог неудачных попыток подбора пароля и скриптом раз в минуту проверять лог и заносить IP адреса в iptables

Для первого варианта достаточно создать правила:

1
2
3
4
5
6
iptables -A INPUT -p tcp --syn --dport 80 -i eth0 -m state --state NEW
-m recent --name bhttp --set
iptables -A INPUT -p tcp --syn --dport 80 -i eth0 -m state --state NEW
-m recent --name bhttp --update --seconds 120
--hitcount 360 -j DROP
iptables -A INPUT -p tcp --syn --dport 80 -i eth0 -j ACCEPT

Можно вместо DROP использовать TARPIT, чтобы усложнить жизнь ломателям.

Для второго варианта надо добавить в конфиг:

1
2
3
4
location /401.html {
root /usr/nginx;
access_log /usr/nginx/logs/denied.log error401;
}

Формат error401, у меня например такой:

1
2
log_format error401  '$remote_addr - $remote_user [$time_local] '
'$status "$request"';
On this page