Безопасность nginx: как улучшить конфигурацию вашего сервера

Настройка обратного прокси на Nginx

Под обратным проксированием обычно понимается процесс, в котором сервер, получающий запрос от клиента, не обрабатывает его полностью самостоятельно, а частично или целиком отправляет этот запрос для обработки другим (upstream) серверам. Иными словами, он не перенаправляет клиента, а самостоятельно отправляет запрос и возвращает полученный ответ обратно клиенту.

Настройте обратный прокси example.org, взаимодействующий с внутренним HTTP-сервисом, использующим порт 8080:

/etc/nginx/sites-enables/example.org.conf

server {
  listen 80;
  server_name www.example.org example.org;
  access_log /var/log/nginx/proxy.log;

  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Nginx-Proxy true;

    proxy_redirect off;
  }
}

Правильный сертификат

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

  1. Сертификат должен быть выпущен доверенным центром.
  2. Сертификат должен быть выдан для домена, к которому идет подключение.

Доверенный центр

Есть список центров сертификации, внесенные в общий реестр доверенных узлов, которые могут выпускать ключи безопасности. Данным центрам по умолчанию доверяют все основные операционные системы.

Для получения сертификата от правильного центра, необходимо за него заплатить или получить бесплатно от Let’s Encrypt. Купить сертификат можно у большинства хостеров или регистраторов доменных имен. Для получения бесплатного сертификата можно воспользоваться инструкцией Получение бесплатного SSL сертификата Let’s Encrypt.

И наоборот, сертификат может быть выпущен не доверенным центром или локально на компьютере (самоподписанный). В таком случае мы получим ошибку при проверке подлинности.

Сертификат для домена

Заказывая сертификат, мы обязательно указываем, для какого доменного имени его будем использовать. Это обязательное требование. Например, если мы хотим настроить SSL-подключение к узлу security.dmosk.ru, то необходимо указывать именно это имя при заказе ключа безопасности. В противном случае, браузер будет выдавать нам ошибку, что сертификат выдан для другого узла.

Также мы можем заказать сертификат типа wildcard — он применим к домену и все его поддоменам. Например, в нашем случае мы можем заказать ключ для *.dmosk.ru — он будет применять для любого доменного имени 3-го уровня с корнем dmosk.ru.

Основы конфигурации NGINX

Общий конфигурационный файл NGINX выглядит следующим образом:

Все настройки называются директивами и представляют собой пары key-value. Директива с фигурными скобками называется контекстом. Вот список основных контекстов:

  • global — общие настройки,
  • events — настройки обработки событий воркер-процессами,
  • http — настройки http- и https-соединений,
  • server — настройки виртуальных серверов,
  • location — настройки обработки и поиска идентификатора запроса.

Например, клиент делает запрос по URL http://www.example.com/blog. Протокол и доменное имя определяют, какой контекст server будет выбран, а идентификатор запроса (URI) определяет, какой контекст location будет использован.

Особого внимания требует директива include. Указанное значение для этой директивы — это регулярное выражение, которое описывает файлы в директории с расширением .conf. NGINX при старте найдёт все файлы, подходящие под регулярное выражение, и вставит их содержимое в то место, где указана директива include. Это даёт возможность разложить конфигурацию NGINX по отдельным файлам.

Сжатие

Это один из самых эффективных методов ускорить ответ от вашего веб-сервера nginx.

Пример настроенного nginx.conf:

http {
    …
    gzip                on;
    gzip_min_length     1000;
    gzip_proxied        expired no-cache no-store private auth;
    gzip_types          text/plain text/css text/javascript application/javascript application/x-javascript text/xml application/xml application/xml+rss application/json;
    gzip_disable        «msie6»;
    …

gzip включает сжатие.

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

gzip_proxied перечисляет параметры проксированных запросов, для которых будет разрешено сжатие.

gzip_types по умолчанию включено сжатие для ответов типа текст. В данном параметре можно перечислить все необходимые типы ответов.

gzip_disable запрещает для перечисленных параметров заголовка User-Agent сжатие. В данном примере для Internet Explorer 6 сжатие применяться не будет (данный браузер не умеет принимать сжатые ответы).

Другие способы

Открой файл /etc/sysctl.conf и помести в него следующие строки:

Поместив корневой каталог Web-сервера в выделенный раздел и запретив на нем размещение любых исполняемых файлов и файлов-устройств, ты обезопасишь остальную часть системы от тех, кто сможет получить доступ к корню Web-сервера. При этом запись в файле /etc/fstab должна иметь примерно такой вид:

Помести nginx в chroot/jail-окружение

Любая современная *nix-система позволяет запереть приложение в изолированной среде исполнения. В Linux для этого можно использовать технологии KVM, Xen, OpenVZ и VServer, во FreeBSD – Jail, в Solaris – Zones. Если ни одна из этих технологий не доступна, ты можешь поместить nginx в классический chroot, который хоть и намного более хрупок, но большинство взломщиков остановить сможет.

Установи правила SELinux для защиты nginx

Хорошей альтернативой изолированным средам исполнения являются локальные системы обнаружения и предотвращения вторжений, такие как SELinux или AppArmor. Будучи правильно настроенными, они смогут предотвратить попытки взлома Web-сервера. По дефолту ни одна из них не настроена для работы в связке с nginx, однако в рамках проекта SELinuxNginx (http://sf.net/projects/selinuxnginx/) были созданы правила для SELinux, которые может использовать любой желающий. Остается только скачать и установить:

Настрой брандмауэр

Обычно nginx устанавливают на выделенных машинах, готовых к высокой нагрузке, поэтому зачастую он остается единственным сетевым сервисом, работающим на сервере. Чтобы обезопасить сервер, достаточно создать совсем небольшой набор правил, которые будут открывать 80, 110 и 143-й порты (если, конечно, nginx должен работать еще и как IMAP/POP3-прокси) и закрывать от внешнего мира все остальное.

Ограничь количество соединений с помощью брандмауэра

Для не слишком нагруженного Web-сайта хорошей идеей будет ограничить количество попыток соединений с одного IP-адреса в минуту. Это сможет уберечь тебя от некоторых типов DoS-атак и брутфорса. В Linux это можно сделать с помощью стандартного iptables/netfilter-модуля state:

Правила урезают лимит на количество подключений с одного IP в минуту до 15. То же можно сделать и с помощью pf:

Кроме лимита на количество последовательных подключений (15 в минуту), данное правило устанавливает дополнительный лимит на количество одновременных подключений равный 100.

Настрой PHP

Если ты используешь nginx в связке с PHP, не забудь настроить и его. Вот как должен выглядеть конфигурационный файл /etc/php/php.ini защищенного сервера:

Установка

Пакет nginx доступен в прекомпилированном виде для любого дистрибутива. Однако собрав сервер самостоятельно, ты сможешь сделать его более компактным и надежным, а также получишь возможность изменить строку приветствия Web-сервера, чтобы отбить несмышленых скрипт-кидди.

Измени строку приветствия Web-сервера

Скачай исходники nginx, открой файл src/http/ngx_http_header_filter_module.c и найди следующие две строки:

static char ngx_http_server_string[] = «Server: nginx» CRLF; static char ngx_http_server_full_string[] = «Server: » NGINX_VER CRLF;

Замени их на что-то вроде этого:

static char ngx_http_server_string[] = «Server: ] = «Server: ][ Web Server» CRLF;

Удали все неиспользуемые тобой nginx-модули

Некоторая часть модулей nginx подключается к Web-серверу прямо во время компиляции, и любой из них таит в себе потенциальную опасность. Возможно, в будущем в одном из них будет найдена уязвимость, и твой сервер окажется под угрозой. Отключив ненужные модули, ты сможешь значительно снизить риск возникновения такой ситуации.

Выполни сборку с помощью следующих команд:

# ./configure —without-http_autoindex_module —without-http_ssi_module # make # make install

Так ты получишь nginx с заранее отключенными (и в большинстве случаев бесполезными) модулями SSI (Server Side Includes) и Autoindex. Чтобы узнать, какие модули можно безболезненно выбросить из Web-сервера, запусти скрипт configure с флагом ‘—help’.

Пример настроенного файла конфигурации

В итоге, у нас получиться что-то на подобие:

worker_processes  auto;
worker_priority     -2;
events {
    worker_connections  2048;
    multi_accept on;
    use epoll;
}
http {
    include mime.types;
    default_type application/octet-stream;
    keepalive_timeout          45;
    reset_timedout_connection  on;
    client_body_timeout        35;
    send_timeout               30;
    sendfile      on;
    aio           on;
    tcp_nopush    on;
    open_file_cache max=100000 inactive=20s;
    open_file_cache_valid 45s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    access_log off;
    error_log /var/log/nginx-error.log crit;
    gzip                on;
    gzip_min_length     1000;
    gzip_proxied        expired no-cache no-store private auth;
    gzip_types          text/plain text/css text/javascript application/javascript application/x-javascript text/xml application/xml application/xml+rss application/json;
    gzip_disable        «msie6»;
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

* обратите внимание, что в Linux в events use задается epoll, во FreeBSD — kqueue

Как работает балансировка нагрузки NGINX

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

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

Однако это не всегда так просто. Многие веб-приложения требуют некоторой формы постоянство сеансаЭто означает, что пользователь должен обращаться к одному и тому же серверу в течение всего сеанса. Например, корзина покупок может храниться локально на одном сервере приложений, и если пользователь переключает серверы в середине сеанса, приложение может отключиться. Конечно, многие из этих сценариев могут быть исправлены с помощью лучшей инфраструктуры приложений и централизованных хранилищ данных, но многим людям требуется постоянство сеансов.

В NGINX набор серверов, на которые вы маршрутизируете, называется вверх по течениюи настроен как перечисляемый список адресов:

upstream backend {
    server backend1.example.com weight=5;
    server backend2.example.com;
}

Эти вверх по течению есть много вариантов; здесь мы установили вес, который будет отдавать приоритет этому серверу чаще (особенно полезно, если у вас разные размеры). Вы также можете установить максимальное количество подключений и различные таймауты. Если вы используете NGINX PlusВы также можете настроить проверку работоспособности, чтобы соединения не перенаправлялись на нездоровые серверы.

Самая основная форма сохранения сеанса — использование хэша IP. NGINX будет использовать IP для идентификации пользователей, а затем убедиться, что эти пользователи не переключают серверы в середине сеанса:

upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
}

IP-хеш требуется для приложений на основе сокетов и всего, что требует постоянного хранения. Если вы не хотите использовать IP-адрес, вы можете настроить этот хеш:

upstream backend {
    hash $scheme$request_uri consistent;
    server backend1.example.com;
    server backend2.example.com;
}

Если вам не нужен какой-либо тип сохранения сеанса, вы можете сделать циклический выбор немного более разумным, выбрав, какой сервер имеет наименьшее количество подключений:

upstream backend {
    least_conn;
    server backend1.example.com;
    server backend2.example.com;
}

Или, в зависимости от того, какой из них в данный момент отвечает быстрее всего:

upstream backend {
    least_time (header | last_byte);
    server backend1.example.com;
    server backend2.example.com;
}

, но IP-хеширование будет работать для большинства приложений.

Шаг 8. Настройте Nginx для включения заголовков безопасности

Чтобы дополнительно защитить свой веб-сервер nginx, вы можете добавить несколько различных заголовков HTTP. Вот некоторые из вариантов, которые мы рекомендуем.

X-Frame-Options

Заголовок HTTP-ответа X-Frame-Options, используется чтобы указать, разрешено ли браузеру отображать страницу в frame или iframe . Это может предотвратить атаки с помощью clickjacking. Поэтому мы рекомендуем вам включить эту опцию для вашего сервера nginx.

Для этого добавьте следующий параметр в файл конфигурации nginx в разделе server:

Strict-Transport-Security

HTTP Strict Transport Security (HSTS) — это метод, используемый веб-сайтами для объявления того, что доступ к ним должен осуществляться только через безопасное соединение (HTTPS). Если веб-сайт объявляет политику HSTS, браузер должен отклонить все HTTP-соединения и запретить пользователям принимать незащищенные SSL-сертификаты. Чтобы добавить заголовок HSTS на ваш сервер nginx, вы можете добавить следующую директиву в ваш раздел сервера:

CSP and X-XSS-Protection

Политика безопасности контента (CSP) защищает ваш веб-сервер от определенных типов атак, включая атаки с использованием Cross-site Scripting (XSS) и атаки с использованием data injection

Вы можете реализовать CSP, добавив следующий пример заголовка Content-Security-Policy (обратите внимание, что фактический заголовок должен быть настроен в соответствии с вашими уникальными требованиями):. Заголовок HTTP X-XSS-Protection поддерживается IE и Safari и не требуется для современных браузеров, если у вас есть строгая политика безопасности содержимого

Однако, чтобы предотвратить XSS в случае более старых браузеров (которые еще не поддерживают CSP), вы можете добавить заголовок X-XSS Protection в раздел вашего сервера:

Заголовок HTTP X-XSS-Protection поддерживается IE и Safari и не требуется для современных браузеров, если у вас есть строгая политика безопасности содержимого. Однако, чтобы предотвратить XSS в случае более старых браузеров (которые еще не поддерживают CSP), вы можете добавить заголовок X-XSS Protection в раздел вашего сервера:

Передача запросов на PHP

Если Nginx перенаправляет все запросы, заканчивающиеся на , напрямую на интерпретатор PHP, то для злоумышленников открываются возможности для выполнения стороннего кода. PHP по умолчанию пытается догадаться, куда должен вести неправильный запрос. Так что в первую очередь необходимо подправить , указав:

cgi.fix_pathinfo=0

#Интерпретатор будет обрабатывать только корректные запросы

Обратите внимание на правильную конфигурацию Nginx:

# Перенаправляет запросы только для указанных файлов
location ~* (file_a|file_b|file_c)\.php$ {
    fastcgi_pass backend;
    # 
}

 # Отключить выполнение скриптов в пользовательских загрузках
location /uploaddir {
    location ~ \.php$ {return 403;}
    # 
}

 # Фильтрация при помощи try_files
location ~* \.php$ {
    try_files $uri =404;
    fastcgi_pass backend;
    # 
}

 # Использует вложенное расположение для фильтрации
location ~* \.php$ {
    location ~ \..*/.*\.php$ {return 404;}
    fastcgi_pass backend;
    # 
}

# Параметры можно комбинировать

Путь FastCGI

Неправильное указание путей размещения скриптов FastCGI часть приводит к ошибке “Primary script unknown”, которая легко решается.

Перезапись (rewrite)

Используйте переменную  для изменения URI запроса:

rewrite ^ http://somesite.com$request_uri? permanent;

# Или так
return 301 http://somesite.com$request_uri;

# Перенаправляет на страницу 301

Проксирование

Не перенаправляйте все запросы на PHP в таком виде:

server {
    server_name _;
    root /var/www/site;
    location / {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/tmp/phpcgi.socket;
    }
}

Используйте все те же директиву try_files:

server {
    server_name _;
    root /var/www/site;
    location / {
        try_files $uri $uri/ @proxy;
    }
    location @proxy {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/tmp/phpcgi.socket;
    }
}

Или так:

server {
    server_name _;
    root /var/www/site;
    location / {
        try_files $uri $uri/ /index.php;
    }
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/tmp/phpcgi.socket;
    }
}

Настройка в zabbix мониторинга nginx

В прошлой редакции этой статьи дальше шло описание скрипта, который будет парсить вывод nginx-status и передавать данные в zabbix. Сейчас все можно сделать гораздо проще и удобнее. На агенте не надо ничего настраивать. Все выполняется исключительно в шаблоне. То есть вам достаточно загрузить готовый шаблон для мониторинга nginx на zabbix сервер, прикрепить его к хосту и все будет работать.

Это удобный подход, который избавляет от необходимости настраивать агентов. Теперь все выполняется с сервера. Минус этого подхода только в том, что возрастает нагрузка на сервер мониторинга. Это плата за удобство и централизацию. Имейте это ввиду. Если у вас большая инсталляция мониторинга и есть средства автоматизации типа ansible, возможно вам имеет смысл по старинке парсить данные скриптом. Но в общем случае я рекомендую делать так, как я расскажу далее.

Суть мониторинга Nginx будет сводиться к тому, что мы через агента станем забирать страницу http://localhost/nginx-status на сервер. Там с помощью регулярных выражений и зависимых элементов данных будем формировать нужные метрики.

Представляю вам готовый шаблон для мониторинга nginx. Скачиваем его zabbix-nginx-template.xml и открываем web интерфейс zabbix сервера. Идем в раздел Configuration -> Templates и жмем Import:

Выбираем файл и снова нажимаем Import:

Шаблон я подготовил сам на основе своих представлений о том, что нужно мониторить. Проверил и экспортировал его с версии 4.2 Регулярные выражения для парсинга html страницы статуса подсмотрел тут — https://github.com/AlexGluck/ZBX_NGINX. К представленному шаблону я добавил некоторые итемы и переделал все триггеры. Плюс убрал макросы. Не вижу в них в данном случае смысла.

В шаблоне 11 итемов, описание которых я привел ранее.

Подробнее остановимся на триггерах. Их 5 штук.

  1. Many active connections — срабатывает если среднее количество соединений за последние 10 минут больше в 3 раза, чем среднее количество за интервал на 10 минут ранее.
  2. many requests и too many requests — срабатывают, когда среднее количество запросов за последние 10 минут больше в 3 и 6 раз соответственно, чем на 10 минут ранее.
  3. nginx is not running — тут все просто. Если не запущен ни один процесс nginx, шлем уведомление.
  4. nginx is slow to respond — срабатывает если время выполнения запроса на получение страницы со статусом за последние 10 минут больше предыдущих 10 минут в 2 раза.

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

Более надежно могут сработать триггеры, где явно указаны лимиты в конкретных значениях. Но такой подход требует ручной калибровки на каждом проекте в отдельности. Надо смотреть средние значения метрик и выставлять лимиты в зависимости от них. Если проект будет расти, то лимиты постоянно придется менять. Это тоже не очень удобно и не универсально.

Я в итоге остановился на анализе средних значений, не используя конкретных лимитов. Как поступать вам, решайте отдельно, в зависимости от ситуации. Если у вас один проект, которому вы уделяете много внимания, то ставьте лимиты руками на основе анализа средних параметров. Если работаете на потоке с множеством проектов, то можно использовать мой вариант, он более универсален и не требует ручной правки.

Единственное, коэффициенты можно поправить, если будут ложные срабатывания. Но я обычно этот момент решаю через отложенные уведомления. Если чувствительность триггера очень высокая и есть кратковременные ложные срабатывания, меня они не беспокоят из-за 5-ти минутной задержки уведомлений. Зато при разборе инцидентов, эти кратковременные срабатывания помогают оценить ситуацию в целом.

С мониторингом nginx почти все готово. Теперь нам нужно прицепить добавленный шаблон к web серверу, который мы мониторим и дождаться поступления данных. Проверить их можно в Monitoring -> Latest Data:

В шаблоне есть несколько графиков. Не буду о них рассказывать, так как последнее время практически не пользуюсь графиками. Вместо этого собираю дашборды. Это более удобно и информативно. Жаль, что дашборды нельзя к шаблонам прикреплять. Очень хлопотно каждый раз вручную их составлять и тратить время. В конце покажу пример дашборда, который я использую для мониторинга web сервера.

На этом настройка мониторинга nginx закончена, можно пользоваться.

nginx

nginx  — это HTTP-сервер и обратный прокси-сервер,
почтовый прокси-сервер,
а также TCP/UDP прокси-сервер общего назначения,
изначально написанный Игорем Сысоевым.
Уже длительное время он обслуживает
серверы многих высоконагруженных российских сайтов, таких как
Яндекс,
Mail.Ru,
и
Рамблер.
Согласно статистике Netcraft nginx обслуживал или проксировал
22.57%
самых нагруженных сайтов в июле 2021 года.
Вот некоторые примеры успешного внедрения nginx (тексты на английском языке):
Dropbox,
Netflix,
Wordpress.com,
FastMail.FM.

Исходные тексты и документация распространяются под
BSD-подобной лицензией из 2 пунктов.

Коммерческая поддержка осуществляется компанией
Nginx, Inc.

  • Обслуживание статических запросов,
    индексных
    файлов,
    автоматическое
    создание списка файлов,
    ;
  • Акселерированное
    обратное проксирование с кэшированием,
    распределение нагрузки
    и отказоустойчивость;
  • Акселерированная поддержка
    FastCGI,
    uwsgi,
    SCGI и
    memcached
    серверов с кэшированием,
    распределение нагрузки
    и отказоустойчивость;
  • Модульность, фильтры, в том числе
    сжатие (gzip),
    byte-ranges (докачка),
    chunked ответы,
    XSLT-фильтр,
    SSI-фильтр,
    преобразование
    изображений;
    несколько подзапросов на одной странице, обрабатываемые в SSI-фильтре
    через прокси или FastCGI/uwsgi/SCGI, выполняются параллельно;
  • Поддержка SSL и
    расширения TLS SNI;
  • Поддержка HTTP/2
    с приоритизацией на основе весов и зависимостей.
  • Виртуальные серверы,
    определяемые по IP-адресу и имени;
  • Поддержка

    и pipelined соединений;

  • ,
    ,
    ,
    запись в syslog;
  • для ошибок 3xx-5xx;
  • rewrite-модуль:
    изменение URI
    с помощью регулярных выражений;
  • в зависимости от
    адреса клиента;
  • Ограничение доступа в зависимости от
    адреса клиента,
    по паролю
    (HTTP Basic аутентификация) и по
    результату
    подзапроса;
  • Проверка HTTP referer;
  • Методы
    PUT, DELETE, MKCOL, COPY и MOVE;
  • FLV
    и
    MP4
    стриминг;
  • ;
  • Ограничение числа одновременных
    соединений и
    запросов
    с одного адреса;
  • Геолокация по IP-адресу;
  • A/B-тестирование;
  • Зеркалирование запросов;
  • Встроенный Perl;
  • сценарный язык njs.
  • Перенаправление пользователя на
    IMAP-
    или
    POP3-сервер
    с использованием внешнего HTTP-сервера
    аутентификации;
  • Проверка пользователя с помощью внешнего HTTP-сервера
    аутентификации
    и перенаправление соединения на внутренний
    SMTP-сервер;
  • Методы аутентификации:

    • :
      USER/PASS, APOP, AUTH LOGIN/PLAIN/CRAM-MD5;
    • :
      LOGIN, AUTH LOGIN/PLAIN/CRAM-MD5;
    • :
      AUTH LOGIN/PLAIN/CRAM-MD5;
  • Поддержка SSL;
  • Поддержка
    .
  • Проксирование
    TCP и UDP;
  • Поддержка SSL и
    расширения TLS
    SNI
    для TCP;
  • Распределение нагрузки
    и отказоустойчивость;
  • Ограничение доступа в зависимости от
    адреса клиента;
  • Выполнение разных функций в зависимости от
    адреса клиента;
  • Ограничение числа одновременных
    соединений
    с одного адреса;
  • ,
    ,
    ,
    запись в syslog;
  • Геолокация по IP-адресу;
  • A/B-тестирование;
  • сценарный язык njs.
  • Один главный и несколько рабочих процессов, рабочие процессы работают под
    непривилегированным пользователем;
  • Гибкость конфигурации;
  • и без перерыва в обслуживании клиентов;

  • Поддержка
    kqueue (FreeBSD 4.1+),
    epoll (Linux 2.6+),
    /dev/poll (Solaris 7 11/99+),
    event ports (Solaris 10),
    select и poll;
  • Использование возможностей, предоставляемых kqueue, таких как
    EV_CLEAR, EV_DISABLE (для временного выключения события),
    NOTE_LOWAT, EV_EOF, число доступных данных, коды ошибок;
  • Использование возможностей, предоставляемых epoll, таких как
    EPOLLRDHUP (Linux 2.6.17+, glibc 2.8+) и
    EPOLLEXCLUSIVE (Linux 4.5+, glibc 2.24+);
  • Поддержка sendfile (FreeBSD 3.1+, Linux 2.2+, macOS 10.5+),
    sendfile64 (Linux 2.4.21+) и sendfilev (Solaris 8 7/01+);
  • Поддержка
    (FreeBSD 4.3+, Linux 2.6.22+);
  • Поддержка

    (FreeBSD 4.4+, Linux 2.4+, Solaris 2.6+, macOS);

  • accept-фильтров (FreeBSD 4.1+, NetBSD 5.0+) и TCP_DEFER_ACCEPT (Linux 2.4+);

  • На 10 000 неактивных HTTP keep-alive соединений расходуется
    около 2.5M памяти;
  • Минимум операций копирования данных.
  • FreeBSD 3 — 12 / i386;
    FreeBSD 5 — 12 / amd64;
    FreeBSD 11 / ppc;
    FreeBSD 12 / ppc64;
  • Linux 2.2 — 4 / i386;
    Linux 2.6 — 5 / amd64;
    Linux 3 — 4 / armv6l, armv7l, aarch64, ppc64le;
  • Solaris 9 / i386, sun4u;
    Solaris 10 / i386, amd64, sun4v;
    Solaris 11 / x86;
  • AIX 7.1 / powerpc;
  • HP-UX 11.31 / ia64;
  • macOS / ppc, i386, x86_64;
  • Windows XP,
    Windows Server 2003,
    Windows 7,
    Windows 10.

Блок http

Блок http содержит директивы управления веб-трафиком. Они часто называются универсальными, потому что используются для конфигурации всех веб-сайтов, содержащихся на сервере. Полный список всех доступных директив и их параметров для этого блока можно посмотреть в документации Nginx. В можно увидить примерно следующий блок http

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user  "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}

В рассмотренном примере заданы следующие директивы:

include – указывает расположение дополнительных файлов конфигурацииdefault_type – задает MIME-тип ответов по умолчаниюlog_format – задает поля, которые будут сохраняться в логе сервераaccess_log – путь к файлу лога доступа к серверуsendfile – прямая передача данных без буферизации, используется для ускорения работы сервераtcp_nopush – настройка формирования TCP-пакетов, ускоряющая работу сервера (в данном случае закомментировано)keepalive_timeout – максимальное время поддержания соединения, если пользователь ничего не запрашиваетgzip – включение компрессии (в данном случае закомментировано)

  • Как уже было сказано, блок http содержит директиву include, которая указывает расположение файлов конфигурации Nginx.
    Если установка выполнялась из официального репозитория Nginx, эта строка, как и в рассмотренном примере, будет иметь вид . У каждого веб-сайта на вашем сервере в этой директории должен быть свой файл конфигурации с именем формата example.com.conf. Для отключенных сайтов (не отображаемых Nginx) он может быть переименован в формате example.com.conf.disabled.
  • При установке из репозиториев Debian или Ubuntu данная строка будет иметь вид . Директория содержит символические ссылки на файлы конфигурации, которые хранятся в . Отключение сайта осуществляется удалением символической ссылки на sites-enabled.
  • В зависимости от источника установки в или есть пример файла конфигурации.

Устранение проблем

В случае проблем следующие команды помогут найти ошибки.

Проверка конфигурации

Проверьте, что запущенная конфигурация nginx не содержит ошибок.

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

При запуске nginx с параметром будет произведена проверка синтаксиса файла конфигурации без запуска самого демона nginx. Используйте параметр и полный путь до файла, чтобы протестировать файлы находящиеся по нестандартному пути.

Проверка запущенных процессов

Проверьте, запущены ли процессы nginx:

  PID TTY      STAT   TIME COMMAND
26092 ?        Ss     0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
26093 ?        S      0:00 nginx: worker proces

Проверка адреса привязки и портов

Проверьте, что демон nginx прослушивает правильный TCP-порт (например, 80 для HTTP или 443 для HTTPS):

tcp        0      0 127.0.0.1:80            0.0.0.0:*               LISTEN      0          12336835   -26092/nginx: master

Итоги

Здесь собраны графики, отображающие изменение характеристик сервисов в зависимости от нагрузки. При просмотре графиков стоит учитывать, что не все сервисы ответили на 100% запросов.

График 5.1 95% перцентиль времени ответа

График 5.2 95% перцентиль времени ответа (без php-fpm)

График 5.3 Максимальная нагрузка процессора

График 5.4 Максимальное потребление памяти

Оптимальным решением (без изменения кода), на мой взгляд, является менеджер процессов Nginx Unit. Он показывает хорошие результаты в скорости ответа и имеет поддержку компании.

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

UPD
Для тестов 1000/10000 rps добавлен сервис php-fpm-80
Для него использовалась конфигурация php-fpm:

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Техноарена
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: