Ограничения и лимиты в NGINX

Термины по теме: NGINX, веб-сервер

Размер загружаемого файла

По умолчанию nginx разрешает загружать файла размером не более 2 Мб. Для большинства веб-проектов, этого недостаточно.

Для изменения лимита необходимо добавить директиву client_max_body_size. При этом, она может быть настроена на уровне всего веб-сервера, конкретного сайта или location. При этом, больший приоритет отдается последнему.

Рассмотрим примеры.

а) Для всех сайтов настраиваем секцию http (как правило, файл /etc/nginx/nginx.conf):

http {
    …
    client_max_body_size 10m;
    …
}

* такая настройка имеет наименьший приоритет. Настройки для server и location будут переопределять значение.

б) Для конкретного сайта редактируем секцию server:

server {
    listen 80;
    server_name example.dmosk.ru;
    client_max_body_size 50m;
}

* средний приоритет.

в) Для конкретного адреса обращения к ресурсу:

server {
    location /upload {
        client_max_body_size 20m;
    }
    
    location /api {
        client_max_body_size 5m;
    }
}

После внесения необходимых изменений перезапускаем NGINX:

nginx -t && nginx -s reload

Доступ с определенных IP-адресов

Данная возможность обеспечивается модулем ngx_http_access_module. Как правило, он входит в стандартную установку.

В настройке виртуального домена:

location / {
    deny  192.168.0.15;
    allow 192.168.0.0/24;
    allow 2001:0ab3::/32;
    deny  all;
}

* в данном примере мы разрешаем доступ для всех компьютеров сети 192.168.0.0/24 (за исключением 192.168.0.15) и компьютеру с адресом ipv6 2001:0ab3::. Остальным доступ запрещен. 

Если мы хотим сделать ограничение не для конкретного сайта, а для всего nginx (всех сайтов), то прописываем настройки в общем конфигурационном файле секции http:

vi /etc/nginx/nginx.conf

http {
    …
    deny  192.168.0.15;
    allow 192.168.0.0/24;
    allow 2001:0ab3::/32;
    deny  all;
    …
}

После перезапускаем NGINX:

nginx -t && nginx -s reload

Ограничение доступа к определенной папке

Стоит отметить, что блокировать доступ по IP-адресу можно не только ко всему сайту, но и к определенным директориям, например:

location /install {
    allow 192.168.0.15;
    deny  all;
}

* в данном примере мы запрещаем доступ к папке install, но разрешаем устройству 192.168.0.15.

Разрешить только локальные запросы

Самый правильный способ, настроить, чтобы NGINX слушал только на локальном адреса, например, listen 127.0.0.1:80;

Но если такой метод, по каким-либо причинам нам не подходит, делаем так:

location / {
    allow 127.0.0.1;
    deny  all;
}

Действие с IP по условию

В зависимости от определенного IP-адреса NGINX может выполнять различные действия, а не только запрет доступа. Например, перенаправление:

location / {
    …
    if ($remote_addr != 127.0.0.1) {
        return 301 https://$host$request_uri;
    }
    …
}

* в данном примере мы перенаправляем всех посетителей по пути https://$host$request_uri, кроме запросов с IP-адреса 127.0.0.1.

Директива if нежелательна в nginx. Она приводит к тому, что веб-серверу нужно каждый раз проверять условие. Это понижает производительность.

Также if в nginx работает не так, как в обычных языках программирования. В контексте location она может вызывать неочевидные побочные эффекты.

Используйте его только тогда, когда другие варианты не подходят.

Указать список адресов в отдельном файле

При работе с большим списком адресов, удобнее их сохранить в отдельном файле и подключать данный файл в нужной части конфигурации.

Предположим, у нас есть список IP-адресов для блокировки. Создадим файл:

vi /etc/nginx/blacklist.conf

deny 1.1.1.1/32;
deny 2.2.2.2/30;
deny 3.3.3.3/28;
deny 4.4.4.4/24;
allow all;

* в данном примере мы хотим блокировать 4 подсети. Остальным сетям мы разрешаем доступ.

Теперь в конфигурационном файле nginx подключим данный файл:

server {
    …
    include /etc/nginx/blacklist.conf;
    ….
}

* обратите внимание, что мы создали список доступа на уровке секции server. Также мы можем сделать подключение для location или http.

Не забываем проверить корректность конфигурации и применить ее:

nginx -t && nginx -s reload

Доступ по паролю

Мы можем разрешить доступ по паролю ко всему сайту или конкретной странице (URL). Конфигурирование включает два процесса:

  1. Настройка NGINX.
  2. Создание файла с паролем.

Рассмотрим их по отдельности.

Конфигурация NGINX

В конфигурационном файле …

а) для установки пароля на весь сайт:

server {
    ….
    auth_basic "HTTP Basic Authentication";
    auth_basic_user_file /etc/nginx/htpasswd;
    ….
}

б) для установки пароля на конкретную страницу:

server {
    ….
    location = /page7 {
        auth_basic "HTTP Basic Authentication";
        auth_basic_user_file /etc/nginx/htpasswd;
    }
    ….
}

в) для установки пароля на все вложенные страницы по URL /page7:

server {
    ….
    location /page7/ {
        auth_basic "HTTP Basic Authentication";
        auth_basic_user_file /etc/nginx/htpasswd;
    }
    ….
}

* где auth_basic указывает веб-серверу использовать обычную аутентификацию по логину и паролю; auth_basic_user_file задает путь хранения файла с паролями.

г) также может потребоваться исключить авторизацию для некоторых вложенных скриптов. Это делается с помощью location и указания auth_basic off, например:

    location /page7/ {
        auth_basic "HTTP Basic Authentication";
        auth_basic_user_file /etc/nginx/htpasswd;
        location ~ .(js|css|ttf|woff|woff2|otf)$ {
            auth_basic off;
        }
    }

* в данном примере мы запрашиваем авторизацию для страниц, которые начинаются на /page7/, но кроме файлов, которые заканчиваются на js, css, ttf, woff, woff2, otf.

д) еще один вариант, конда нам нужно требовать аутентификацию для всех, кроме некоторых IP-адресов:

server {
    ….
    satisfy any;
    allow 192.168.12.0/24;
    deny all;

    auth_basic "HTTP Basic Authentication";
    auth_basic_user_file /etc/nginx/htpasswd;
    ….
}

* в данном примере:

  • satisfy — со значением any разрешает доступ, если его разрешит allow или auth_basic.
  • allow — разрешает доступ для определенного адреса или подсети.
  • deny — запрещает доступ.
  • auth_basic — включает аутентификацию.

Создание файла с паролем

Для создания безопасного пароля необходимо использовать утилиту htpasswd. Для этого ее нужно устрановить.

а) Для систем на базе DEB (Ubuntu / Debian / Astra Linux):

apt update

apt install apache2-utils

б) Для систем на базе RPM (Rocky Linux / РЕД ОС):

dnf install httpd-tools

После настройки конфигурационного файла NGINX, генерируем хеш для пароля.

Вводим команду:

htpasswd -nB test

* после ввода Enter необходимо дважды ввести желаемый пароль — на экран будет выведен логин + хэш. Данную стороку необходимо скопировать в буфер обмена.
** данная команда создаст 
bcrypt-хеш, который, на момент обновления инструкции, является наиболее безопасным алгоритмом.

Если после добавления bcrypt-хеша Nginx выдает Error 500 или "Internal Server Error" в логах (ошибка crypt_r() failed), значит, ваша текущая сборка Nginx или версия ОС не поддерживает этот алгоритм.

В этом случае можно использовать алгоритм md5:

htpasswd -nm test

Создаем файл с пользователями и паролями:

vi /etc/nginx/htpasswd

test:$2y$05$OltlKwE85Me77Ihv0JUdtu3EuunPSnMe7csll2AQVWYOgcjjuaPnu

* где test — логин; $2y$05$OltlKwE85Me77Ihv0JUdtu3EuunPSnMe7csll2AQVWYOgcjjuaPnu — хэш пароля алгоритма bcrypt (Blowfish).
** для создания связки логина пароля также можно воспользоваться online генераторами, например, на gensio.ru.

Хорошей идеей будет ограничить доступ к файлу:

chmod 600 /etc/nginx/htpasswd

chown nginx:nginx /etc/nginx/htpasswd

После перезапускаем NGINX:

nginx -t && nginx -s reload

Лимит скорости

location / {
    limit_rate 1000k;
}

* в данном примере мы огрраничили пропускную способность одного соединения до, примерно, 8 мбит.

location / {
    limit_rate_after 10m;
    limit_rate 1000k;
}

* также ограничиваем скорость до 8 мбит, но после первых 10 Мб загрузки.

Ограничение количества запросов с одного ip

http {
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;
    limit_req_zone $binary_remote_addr zone=dynamic:10m rate=5r/s;
    …
    server {
        …
        location / {
            limit_conn perip 10;
            limit_conn perserver 100;
            limit_req zone=dynamic burst=10 nodelay;
        }
    }
}

* в данном примере мы создаем 3 зоны, размер каждой зоны — 10Мб; на один IP разрешено 10 подключений, но не больше 5 в секунду (rate=5r/s); общее число разрешенных соединений с сервером — 100.

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *