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

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

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

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

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

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

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

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.

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

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

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

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 страны которые необходимо заблокировать:

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

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

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

location ^~ /codes/ {
   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/codes.log   download;
      }

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

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:

htpasswd -b passwords NewUser NewPassword

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

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

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

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

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, чтобы усложнить жизнь ломателям.

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

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

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

log_format error401  '$remote_addr - $remote_user [$time_local] '
   '$status "$request"';