====== Nginx ====== ===== Сведения ===== Эффективное использование ресурсов, отзывчив под нагрузкой.\\ Используется как веб так и прокси сервер.\\ Спроектирован на базе асинхронных неблокирующих event-driver алгоритмов, сервер однопоточный и не создает процессы под каждое соединение, использование ресурсов относительно равномерно. === Динамический контент === Nginx не имеет возможности самостоятельно обрабатывать запросы к динамическому контенту (например php), для этого он передает запрос внешнему процессу (например [[:linux:php|php-fpm]]) и ожидает результата. \\ На каждый запрос создается отдельное соединение с процессом. (плюс в экономии на статических запросах).\\ Взаимодействие может быть по одному из следующих протоколов: http, FastCGI, SCGI, uWSGI, memcache.\\ === Интерпретация запросов === В отличии от сервера [[:linux:apache|Apache]], Nginx интерпретирует запросы в первую очередь как URL а не как пути в файловой системе.\\ Во многом из-за своего Альтер Эго в роли прокси сервера, из-за чего и не реализует поддержку файлов .thaccess. === Модули === В отличии от [[:linux:apache|Apache]], в Nginx модули не являются динамическими, а должны компилироваться с ядром сервера. === Совместное использование с Apache === Очень частая практика использования обоих серверов вместе, Nginx ставится в качестве реверс-прокси, т.е. фронтенд а [[:linux:apache|Apache]] бэкенд.\\ Nginx самостоятельно обслуживает статический контент а динамический передает [[:linux:apache|Apache]].\\ в такой конфигурации можно ставить несколько бэкендов, таким образом хорошо масштабировать систему. ===== Установка ===== Подключаем репозиторий:\\ # echo "deb http://nginx.org/packages/debian `lsb_release -cs` nginx" | tee /etc/apt/sources.list.d/nginx.list Импортируем ключ для него: # curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add - Устанавливаем: # apt update && apt install nginx Проверяем/включаем запуск/автозапуск # systemctl start/enable nginx ===== Конфигурация ===== Проверка конфигурации: # nginx -t Вывести полный конфиг на экран: # nginx -T Применение новой конфигурации без перезагрузки сервера: # nginx -s reload Информация о версии и модулях: # nginx -v ==== Виртуальные хосты ==== Виртуальный хост - это конфиг, который описывает настройку одного домена, для удобства каждый виртуальный хост в отдельном конфиге, но можно это делать и в общем.\\ Конфиги с виртуальными хостами расположены в **/etc/nginx/conf.d/**\\ Виртуальные хосты наследуют параметры из основного файла конфигурации - **/etc/nginx/nginx.conf**, эти параметры могут быть переопределены в каждом виртуальном хосте. Наследуются все явно не указанные параметры.\\ ==== Location ==== **В виртуальных хостах** управляем настройками в зависимости от домена, **а тут** в зависимости от пути запроса.\\ Location можно задавать **префиксной строкой** или **регулярным выражением** (используются модификаторы: * **~** - учитывается регистр * **~*** - не учитывается)\\ Сначала проверяются **префиксные строки**, совпадения запоминаются, затем **регулярные выражения**, в порядке перечисления, если совпадает, то исполняется, если нет, то исполняется запомненный ранее префикс.\\ Так же, можно использовать префикс **=**, он означает точное совпадение запроса и заданного location. После совпадения, остальные проверки прекращаются.\\ ** Пример: ** Укажем максимальный срок хранения картинок в кэше и отключим логирование: location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico|swf|ttf|svg)$ { access_log off; expires 1y; } ** Пример: ** Запретим исполнение скриптов в перечисленных директориях: location ~* /(images|cache|media|logs|tmp)/.*.(php|pl|py|jsp|asp|sh|cgi)$ { return 404; } ==== Работа с php-fpm ==== Устанавливаем и настраиваем [[:linux:php|php-fpm]].\\ Далее, достаточно только указать в виртуальном хосте **Location** для php: location ~* \.php$ { fastcgi_pass unix:/run/php/php7.1-fpm.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; } ** Расширенный пример: ** location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param HTTPS on; # включать, если сайт по https работает fastcgi_intercept_errors on; fastcgi_ignore_client_abort off; fastcgi_connect_timeout 60; fastcgi_send_timeout 180; fastcgi_read_timeout 180; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; } ==== Настройка SSL сертификата ==== FIXME☝ ==== Прокси ==== Проксирование происходит с помощью блока Location, и директивы **proxy_pass**.\\ **Пример: ** Все запросы содержащие **/forum/** будут направлены на отдельный сервер location /forum/ { proxy_pass http://192.168.13.31; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_redirect default; }
:!: Пример с заббиксом По умолчанию apache заббикса слушает 80, переводим его на другой, например 8080, так же задаем локальный адрес для прослушивания\\ Nginx может по дефолту занять 8080, чекаем этот момент\\ Далее в nginx редирект с 80 на 8080\\ server { listen 80; server_name zabbix.mydomain.ru; root /usr/share/nginx/html; index index.html index.htm; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header Proxy-IP $remote_addr; } } Обработка https, прием и редирект 443, редиректим на 8080\\ server { listen 443 ssl http2; server_name zabbix.mydomain.ru; root /usr/share/nginx/html; index index.html index.htm; ssl on; ssl_certificate /etc/zabbix/zabbix_ssl/Zabbix.crt; ssl_certificate_key /etc/zabbix/zabbix_ssl/Zabbix.key; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header Proxy-IP $remote_addr; } } Далее меняем редирект с 80го, теперь не на 8080 а на 443, 8080 закрыт извне, т.к. заббикс слушает только локалхост\\ Перевод можно такой, перенаправляет вообще все запросы на защищенный порт\\ server { listen 80 default_server; server_name _; return 301 https://$host$request_uri; }
==== Связка с Apache ==== Сначала настраиваем [[:linux:apache|Apache]] как обычно, только указываем ему нестандартный порт, например 8080.\\ Далее в настройках виртуального хоста настраиваем Location.\\ ** Пример: ** Перенаправление всего динамического контента, тут **2 блока Location**: *Статика, которую возвращает сам nginx *Все остальные запросы, передаются Apache server { listen 80; server_name example.com www.example.com; location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico|woff|woff2|swf|ttf|svg|html|txt)$ { root /var/www/example.com/public; expires 1y; } location / { proxy_pass http://127.0.0.1:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 120; proxy_send_timeout 120; proxy_read_timeout 180; } } ** Пример: ** Два бекенда upstream backend { server 192.168.0.10:8080; server 192.168.0.11:8080; } server { listen 80; server_name example.com www.example.com; location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico|woff|woff2|swf|ttf|svg|html|txt)$ { root /var/www/example.com/public; expires 1y; } location / { proxy_pass http://127.0.0.1:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 120; proxy_send_timeout 120; proxy_read_timeout 180; } } Тут стоит уделить внимание расположению в сети общих ресурсов этих серверов, таких как DB, FTP и пр.\\ ==== Context ==== Конфиг содержит древовидную структуру, определен наборами фигурных скобок, эти области называются контекстами. Контексты вкладываются друг в друга, заданные директивы наследуют вложенными контекстами, могут переопределяться\\ === Main === Контекст **Main** базовый, глобальный, по умолчанию присутствует всегда, директива вне контекстов, содержится в контексте main\\ === Events === Находится в main, определяет глобальные параметры, влияющие на то как Nginx обрабатывает соединения. В конфете может быть только один контекст Events\\ Как правило метод для обработки соединения выбирается автоматически, платформа выбирает наиболее эффективный из доступных\\ === Http === Содержит все директивы и другие контексты, необходимые для обработки соединений HTTP или HTTPS\\ Так же является дочерним от main, одноранговые с events, не вкладываются друг в друга\\ Содержит значения по умолчанию для каждого виртуального сервера, определенного внутри\\ === Server === Обычно объявляется внутри http, может быть объявлен несколько раз. Виртуальный хост, набор параметров для обработки запросов, разные хосты для разных запросов например\\ Главные директивы для выбора вирт хоста: * "listen" - комбинация ip и порта, которую прослушивает данный блок * "server_name" - так же используется для выбора, если есть несколько блоков в одинаковыми "listen" то будет проверяться заголовок запроса "Host" и на основании этого делаться выбор === Location === Выбирается исходя из клиентского запроса, алгоритмом сопоставления\\ Так же, их может быть несколько, могут быть вложены друг в друга (что тоже может быть полезно). Определение находится в строке заголовка\\ Блоки "location" дополнительно делят обработку запросов внутри блока "server", на основании "url" запроса\\ === upstream === Используется для определения пула серверов для проксирования. Находится в блоке "http" (только ли ?)\\ Затем контекст "Upstream" может ссылаться на имя в пределах блоков "server" или "location" для передачи запросов определенного типа в пул серверов. Внутри пула используется выбор хоста (round-robin), таким образом происходит балансировка нагрузки\\ === Другие === **if** \\ Позволяет настроить условное ветвление\\ **limit_exept** \\ Позволяет задать ограничения на использование HTTP-методов, можно разрешать определенным адресам например\\ ===== Управление ===== ==== Мониторинг ==== Для настройки мониторинга необходимо внести изменения в конфиг **nginx.conf**.\\ После этого сервер сам предоставляет кое какие данные с помощью **ngx_http_stub_status_module**.\\ Добавляем в секцию **http**: server { listen 127.0.0.1:80; server_name status.localhost; keepalive_timeout 0; allow 127.0.0.1; deny all; location /server-status { stub_status on; } access_log off; } После перезапуска, данные доступны (только с локального сервера, как указанно выше), командой: # curl http://localhost/server-status * **Active connections** - количество активных клиентских соединений. * **accepts** - число принятых клиентских соединений. * **handled** - число обработанных соединений. * **requests** - число клиентских запросов. * **Reading** - число соединений, в которых nginx в настоящий момент читает заголовок запроса. * **Writing** - число соединений, в которых nginx в настоящий момент отвечает клиенту. * **Waiting** - число бездействующих клиентских соединений в ожидании запроса. ==== Журналы ==== Настройка журналов указана в основном конфиге **/etc/nginx/nginx.conf**, так же может быть переопределена в виртуальных хостах.\\ Основной синтаксис: **`type_log` `path_log_file` `format_log`;**\\ Может быть включен в любой блок конфига, либо во все (**http**, **server** или **location**).\\ Даже рекомендуется делать отдельные файлы для каждого блока.\\ По умолчанию располагаются в **/var/log/nginx/** === Журнал доступа === В журнал доступа (**access_log**) регистрирует каждый запрос клиента.\\ http { access_log /var/log/nginx/access.log; server { server_name domain.ru access_log /var/log/nginx/domain.access.log; } } Если формат не указан явно, используется формат по умолчанию: log_format combined '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; Журнал можно отключить: access_log off; === Журнал ошибок === error_log log_file log_level Третий параметр указывает уровень протоколирования (каждый уровень включает в себя все нижестоящие):\\ * **debug** – отладка сообщений. * **info** – информационные сообщения. * **notice** – Уведомления. * **warn** – Предупреждения. * **error** – Ошибки при обработке запроса (**по умолчанию**). * **crit** – Критические вопросы. Требует быстрых действий. * **alert** – Оповещения. Действие должно быть принято немедленно. * **emerg** – Чрезвычайная ситуация. Система находится в нерабочем состоянии.