Что такое Nginx
Nginx (NGINX, Engine-X, «Энжин-кс») — это бесплатный веб- и почтовый прокси-сервер с непоточной (асинхронной) архитектурой и открытым кодом.
Разработку Nginx начал в 2002 году Игорь Сысоев для Rambler. А в 2004 году он стал доступен широкому кругу пользователей . С 2011 года серверное ПО начала выпускать уже собственная фирма Игоря, которая спустя 2 года запустила расширенную платную версию продукта (Nginx Plus). Весной 2019 года Nginx была выкуплена крупным американским девелопером F5 Networks.
Nginx работает на ОС Unix-типа и был успешно протестирован на OpenBSD, FreeBSD, Linux, Mac OS X, Solaris. На ОС Windows он стал доступен после выпуска бинарной сборки 0,7.52.
На данный момент функционалом пользуются такие известные платформы: Rambler, Begun, Yandex, SourceForge.net, WordPress.com, vkontakte.ru. Статистика показывает, что Nginx используют 22,3 млн веб-сайтов и 2,03 млн дополнительных активных сайтов.
Пример использования Nginx Rewrite $ 1, $ 2, ..
Ниже приведен пример директивы Nginx Rewrite:
rewrite ^(/data/.*)/andreyex/(\w+)\.?.*$ $1/linux/$2.html last;
Например:
- url/data/distro/andreyex/test.php перепишет в виде url/data/distro/linux/test.html
- В этом примере, когда вы вызываете оригинальный URL с test.php из браузера, он будет переписан на основе вышеприведенного правила перезаписи и будет указывать страницу test.html из /data/distro/linux/
В приведенном выше правила перезаписи:
$ 1 и $ 2 будет фиксировать соответствующие строки из исходного URL, которые не изменяется
$ 1 в замещающей строке заместит находится внутри 1-й скобки () в reg-ехе. В нашем примере, $1 в /data/
Точно так же $ 2 заместит находится внутри 2 скобки () в reg-ехе. Таким образом, $ 2 в (\w+), так что любое слово, которое приходит после /andreyex/ в оригинальном URL. В нашем примере, $ 2 является test
last – этот флаг убедиться, чтобы остановить поиск директивы Rewrite в текущем местоположении или блоке и использовать измененный URI (т.е. переписан URI) и искать новое место для любых дальнейших директив Rewrite.
*$ – Указывает на расширение в исходном URL
Обратите внимание, что здесь, расширение от исходного URL будет заменено на .html в URL путем Rewrite. Таким образом, даже если вы вызываете .php в оригинальном URL, он будет показывать только файл .html в переписанной URL.
В то время как правила перезаписи Nginx делают подобные вещи, как Apache, есть еще много различий в плане того, как вы пишете правило перезаписи в Nginx.
Nginx
Какие проблемы мы хотим решить с помощью Nginx:
- Единая точка входа. Нам не нужно помнить и держать в многочисленных конфигурационных файлах разные IP-адреса и порты для каждого экземпляра сервиса — достаточно знать только IP-адрес нашего Nginx-сервера. К тому же, вся информация о местонахождении сервисов (IP и порт) находится в одном месте, что облегчает поддержание актуального состояния всей нашей микросервисной экосистемы.
- Балансировка нагрузки. Указывая несколько экземпляров каждого нашего сервиса, мы можем распределить нагрузку, например, по алгоритму round-robin.
- Failover. Мы можем перестать использовать экземпляры сервисов, которые в данный момент работают некорректно, — timeout или статус-код ответа нас не устраивают.
Допустим, у нас есть сервис, трафик на который мы хотим направлять через Nginx. Для примера мы опустим большинство параметров настроек самого Nginx и сконцентрируемся на части, касающейся проксирования запросов. В таком случае наш конфиг будет иметь вид:
http { include mime.types; default_type application/octet-stream; upstream service1 { keepalive 512; // для каждого экземпляра сервиса мы указываем адрес, // разрешенное количество неудачных запросов и время, // в течение которого этот экземпляр сервиса не будет принимать запросы //после достижения максимального количества неудачных запросов server 10.0.0.1:5000 max_fails=5 fail_timeout=1m; server 10.0.0.2:5000 max_fails=5 fail_timeout=1m; } server { listen 80; //перечень условий, по которым запрос будет передан к следующему экземпляру сервиса в рамках upstream proxy_next_upstream error timeout invalid_header http_500 http_503; server_name localhost; location ~* ^/service1/(.*) { set $path /$1$is_args$args; proxy_pass http://service1$path; proxy_pass_request_headers on; } } }
Пока все довольно компактно, но что будет, когда мы начнем масштабировать систему, вводя все новые и новые сервисы? Давайте посмотрим на наш новый конфиг:
http { include mime.types; default_type application/octet-stream; upstream service1 { keepalive 512; server 10.0.0.1:5000 max_fails=5 fail_timeout=1m; server 10.0.0.2:5000 max_fails=5 fail_timeout=1m; } upstream service2 { keepalive 512; server 10.0.0.3:5000 max_fails=5 fail_timeout=1m; server 10.0.0.4:5000 max_fails=5 fail_timeout=1m; } upstream service3 { keepalive 512; server 10.0.0.5:5000 max_fails=5 fail_timeout=1m; server 10.0.0.6:5000 max_fails=5 fail_timeout=1m; } ... ... ... upstream service100 { keepalive 512; server 10.0.0.199:5000 max_fails=5 fail_timeout=1m; server 10.0.0.200:5000 max_fails=5 fail_timeout=1m; } server { listen 80; proxy_next_upstream error timeout invalid_header http_500 http_503; server_name localhost; location ~* ^/service1/(.*) { set $path /$1$is_args$args; proxy_pass http://service1$path; proxy_pass_request_headers on; } location ~* ^/service2/(.*) { set $path /$1$is_args$args; proxy_pass http://service2$path; proxy_pass_request_headers on; } location ~* ^/service3/(.*) { set $path /$1$is_args$args; proxy_pass http://service3$path; proxy_pass_request_headers on; } ... ... ... location ~* ^/service100/(.*) { set $path /$1$is_args$args; proxy_pass http://service100$path; proxy_pass_request_headers on; } } }
Когда у нас десятки сервисов, то вместо простого и лаконичного конфигурационного файла мы получаем условно бесконечный набор похожих между собой конструкций. Теперь этот конфиг будет крайне трудно как читать, так и модифицировать.
Можно попробовать разделить один большой конфиг на набор мелких, но это не решает главную проблему масштабирования системы, ведь все изменения мы должны будем делать вручную и далеко не самым удобным способом.
Единственный логичный выход из ситуации — автоматизация процесса внесения изменений в конфиг Nginx. Но для этого нужно где-то хранить данные обо всех наших сервисах.
Prerequisites
Перед установкой Ansible ознакомьтесь с требованиями к управляющему узлу.Перед использованием Ansible ознакомьтесь с требованиями к управляемым узлам (конечным устройствам,которые вы хотите автоматизировать).Управляющие узлы и управляемые узлы имеют разные минимальные требования.
Требования к узлам управления
Для вашего управляющего узла (машины, на которой работает Ansible) вы можете использовать любую машину с установленным Python 2 (версия 2.7) или Python 3 (версия 3.5 и выше). ansible-core 2.11 и Ansible 4.0.0 сделают Python 3.8 мягкой зависимостью для управляющего узла, но будут работать с вышеупомянутыми требованиями. Для работы ansible-core 2.12 и Ansible 5.0.0 на управляющем узле требуется Python 3.8 или новее. Начиная с ansible-core 2.11, проект будет упакован только для Python 3.8 и новее. Сюда входят Red Hat, Debian, CentOS, macOS, любые BSD и так далее. Windows не поддерживается для управляющего узла, подробнее об этом читайте в блоге Мэтта Дэвиса .
Warning
Обратите внимание,что некоторые плагины,работающие на узле управления,имеют дополнительные требования.Эти требования должны быть перечислены в документации к плагину. При выборе узла управления помните,что любая система управления выигрывает,если она работает рядом с управляемыми машинами.Если вы используете Ansible для управления машинами в облаке,рассмотрите возможность использования машины внутри этого облака в качестве узла управления.В большинстве случаев Ansible будет работать лучше с машины в облаке,чем с машины в открытом Интернете
При выборе узла управления помните,что любая система управления выигрывает,если она работает рядом с управляемыми машинами.Если вы используете Ansible для управления машинами в облаке,рассмотрите возможность использования машины внутри этого облака в качестве узла управления.В большинстве случаев Ansible будет работать лучше с машины в облаке,чем с машины в открытом Интернете.
Warning
Ansible 2.11 сделает Python 3.8 мягкой зависимостью для узла управления,но будет функционировать с вышеупомянутыми требованиями.Ansible 2.12 потребует Python 3.8 или новее для работы на узле управления.Начиная с Ansible 2.11,проект будет упакован только для Python 3.8 и новее.
Управляемые требования к узлам
Хотя вам не нужен демон на ваших управляемых узлах, вам нужен способ для Ansible общаться с ними. Для большинства управляемых узлов Ansible устанавливает соединение по SSH и передает модули с помощью SFTP. Если SSH работает, но SFTP недоступен на некоторых из ваших управляемых узлов, вы можете переключиться на SCP в . Для любого компьютера или устройства, на котором может работать Python, вам также понадобится Python 2 (версия 2.6 или новее) или Python 3 (версия 3.5 или новее).
Warning
Обратите внимание, что к некоторым модулям предъявляются дополнительные требования, которые необходимо удовлетворить на «целевой» машине (управляемом узле). Эти требования должны быть перечислены в документации модуля
Note
- Если у вас включен SELinux на удаленных узлах, вы также захотите установить на них libselinux-python перед использованием каких-либо функций, связанных с копированием / файлом / шаблоном в Ansible. Вы можете использовать или в Ansible, чтобы установить этот пакет в удаленных системах, в которых его нет.
- По умолчанию, прежде чем первый модуль Python в playbook запускается на хосте, Ansible пытается найти подходящий интерпретатор Python на этом хосте. Вы можете переопределить поведение обнаружения, установив для переменной инвентаря конкретный интерпретатор и другими способами. См. Подробности в разделе « .
-
Ansible’s , and the , do not depend on a client side install of Python to run. Technically, you can use Ansible to install a compatible version of Python using the , which then allows you to use everything else. For example, if you need to bootstrap Python 2 onto a RHEL-based system, you can install it as follows:
$ ansible myhost
Шаг 3. Контроль ресурсов и ограничения
Чтобы предотвратить потенциальные DoS-атаки на nginx, вы можете установить ограничения на размер буфера для всех клиентов. Вы можете сделать это в файле конфигурации nginx, используя следующие директивы:
- client_body_buffer_size – используйте эту директиву, чтобы указать размер буфера тела запроса клиента. Значение по умолчанию — 8 КБ или 16 КБ, но рекомендуется установить его равным 1 КБ: client_body_buffer_size 1k.
- client_header_buffer_size – используйте эту директиву, чтобы указать размер буфера заголовка для заголовка запроса клиента. Размер буфера 1k подходит для большинства запросов.
- client_max_body_size – используйте эту директиву, чтобы указать максимально допустимый размер тела для клиентского запроса. Директивы 1k должно быть достаточно, но вам нужно увеличить ее, если вы получаете загрузку файлов методом POST.
- large_client_header_buffers – используйте эту директиву, чтобы указать максимальное количество и размер буферов, которые будут использоваться для чтения больших заголовков клиентских запросов. Директива large_client_header_buffers 2 1k устанавливает максимальное количество буферов в 2, каждый с максимальным размером 1k. Эта директива будет принимать URI данных размером 2 КБ.
Примечание. Некоторые источники предполагают, что установка таких ограничений может предотвратить потенциальные атаки переполнения буфера, если такие уязвимости обнаружены в nginx.
Добавление бэкендов
Для того, чтобы начать балансировать нагрузку, необходимо добавить бэкенды в настройки nginx. Для примера, я возьму отдельный виртуальный хост. Идем в его конфиг и в самое начало добавляем три бэкенда через директиву upstream.
upstream cache-api { server 10.32.18.6:8080; server 10.32.18.7:8080; server 10.32.18.8:8080; }
Сейчас я не касаюсь вопросов тонкой настройки балансировки. Будем идти от простого к сложному. На текущий момент мы добавили три сервера, на которые будет распределяться нагрузка. Далее в настройках виртуального хоста добавляем location, запросы к которому будем равномерно распределять.
location / { proxy_pass http://cache-api/; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; }
Этого минимального набора настроек достаточно, чтобы nginx начал равномерно распределять запросы между двумя серверами. Но в реальной ситуации требуется более детальная настройка балансировщика. Для этого используются следующие параметры:
weight | Задает вес сервера, по умолчанию 1. Чем больше вес сервера, тем пропорционально больше запросов он будет принимать от балансировщика. |
max_conns | Ограничивает максимальное число одновременных активных соединений к проксируемому серверу Значение по умолчанию равно 0 и означает, что ограничения нет. |
max_fails | Задаёт число неудачных попыток работы с сервером, которые должны произойти в течение времени, заданного параметром fail_timeout, чтобы сервер считался недоступным на период времени, также заданный параметром fail_timeout. Дефолтное значение — 1. |
fail_timeout | Задаёт время, в течение которого должно произойти заданное число неудачных попыток работы с сервером для того, чтобы сервер считался недоступным и время, в течение которого сервер будет считаться недоступным. По умолчанию параметр равен 10 секундам. |
backup | Помечает сервер как запасной сервер. На него будут передаваться запросы в случае, если не работают основные серверы. |
down | Помечает сервер как постоянно недоступный. |
Подробнее об этом написано в официальной документации, в описании модуля ngx_http_upstream_module. К примеру, конфиг бэкендов для балансировки может быть таким.
server 10.32.18.6:8080 max_fails=2 fail_timeout=10s; server 10.32.18.7:8080 max_fails=2 fail_timeout=10s; server 10.32.18.8:8080 max_fails=2 fail_timeout=10s;
С такими настройками после двух неудачных попыток соединения в течении 10 секунд, бэкенд будет выведен из работы на те же 10 секунд.
Общие правила определения контекстов
Теперь вы знакомы с самыми популярными контекстами Nginx. В этом разделе вы найдете несколько полезных рекомендаций по работе с контекстами.
Применяйте директивы в наиболее широком контексте
Многие директивы действительны в нескольких контекстах. Например, существует множество директив, которые могут находиться в контексте http, server или location. Это дает вам гибкость при настройке этих директив.
Однако обычно лучше объявлять директивы в контексте наиболее высокого уровня из доступных, и при необходимости переопределять их в более узких контекстах. Это возможно благодаря модели наследования, которую реализует Nginx. Существует много причин использовать эту стратегию.
Прежде всего, объявление директивы в широком контексте позволяет избежать ее избыточного повторения в контекстах того же уровня. В приведенном ниже примере каждый блок location объявляет один и тот же document root:
Можно переместить это определение в контекст server или http:
В большинстве случаев наиболее уместным будет серверный уровень, но объявление директивы на более высоком уровне имеет свои преимущества. Это не только уменьшает количество повторений этой директивы в коде, но также позволяет передавать значение по умолчанию всем дочерним элементам (что предотвращает ошибки, которые связаны с тем, что вы забыли определить директиву на более низком уровне)
Это очень важно для объемных конфигураций
Используйте несколько контекстов одного уровня вместо логических контекстов
Чтобы обрабатывать запросы по-разному в зависимости от наличия информации в запросе клиента, многие пользователи часто внедряют контекст if. Ранее вы уже рассмотрели несколько его недостатков.
Во-первых, директива if часто возвращает результаты, которые не соответствуют ожиданиям администратора. Хотя обработка одного и того же ввода всегда приведет к одному и тому же результату, способ интерпретации среды Nginx может значительно отличаться.
Во-вторых, для многих из этих целей есть специальные оптимизированные директивы. Nginx уже использует хорошо документированный алгоритм выбора для таких вещей, как выбор блоков server и location. Поэтому, если это возможно, лучше всего попытаться переместить различные конфигурации в отдельные блоки, чтобы этот алгоритм мог обработать логику выбора.
Например, вместо преобразования запроса пользователя в нужный формат путем перезаписи нужно попытаться настроить два блока для запросов, один из которых представляет желаемый метод, а другой обрабатывает перенаправления (возможно, переписывает их) и передает в правильный блок.
В результате файл проще читать и поддерживать.
Правильные запросы не подвергаются дополнительной обработке, и во многих случаях неправильные запросы можно обработать с помощью перенаправления, а не перезаписи. Это уменьшает расход ресурсов.
Выбор одного условия!..
Люди (и животные) принимают какие-либо решения всю жизнь, от малозначимых («стоит ли мне съесть одну печеньку или две?») до жизнеопределяющих («стоит ли мне остаться дома и работать на ферме отца или переехать в другую страну и изучать астрофизику?»)
Операторы условия в JavaScript позволяют нам указать разного рода действия в зависимости от выбранного пользователем или системой ответа (например одна печенька или две) и связать его с действием (результатом), например, результатом «съесть одну печеньку» будет «все ещё буду чувствовать себя голодным», а результатом «съесть две печеньки» будет «буду чувствовать себя сытым, но мама меня поругает за то, что я съел все сладости».
Настройка Nginx
Конфиг Nginx, в примере порт 8300:
- fcgi.conf
-
server { server_name _; listen 8300; error_log /var/log/nginx/8300-error.log error; access_log /var/log/nginx/8300.log combined; proxy_connect_timeout 600; proxy_send_timeout 600; proxy_read_timeout 600; send_timeout 600; # Для данного location будем использовать только FastCGI location ^~ /cgi/ { gzip off; root /var/www; fastcgi_pass unix:/var/run/fcgiwrap.socket; # Эту часть можно вынести в отдельный файл и делать include fastcgi_params; 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 SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; # According to RFC3875 (https://tools.ietf.org/html/rfc3875#section-4.1.14) in SERVER_NAME # we should put actual hostname user came to. For nginx it is in $host # This will allow to run multihost instances fastcgi_param SERVER_NAME $host; } }
4. Настройка PageSpeed
Google Pagespeed — это модуль Nginx, который выполняет различные оптимизации для того, чтобы страницы грузились быстрее, веб-сервер работал эффективнее, а пользователи не чувствовали дискомфорта. Сюда входит кэширование, оптимизация html кода, оптимизация картинок, объединение javascript и css кода и многое другое. Все это выполняется на уровне Nginx, поэтому эффективнее, чем если бы вы это делали в php. Но тут есть один недостаток, модуль удаляет заголовок Last Modified.
Дело в том, что PageSpeed устанавливает очень долгий строк кэширования для всех файлов, а в имя файла добавляет его хэш. Так скорость загрузки ресурсов выходит намного выше, поскольку браузер будет запрашивать файлы только с новым хэшем, а LastModified удаляется чтобы пользователи смогли увидеть изменения в случае если какой-либо файл будет изменен. А теперь рассмотрим как установить модуль. Нам придется собрать его из исходных кодов.
Сначала установите инструменты для сборки, очень важно, если не установите, потом получите ошибку и не будете знать что делать:
Скачайте и распакуйте исходники Nginx для вашей версии, например, 1.13.3:
Настройка сервера nginx не включает пере сборку и замену программы из репозитория, мы просто используем эти исходники для сборки модуля. Скачайте и распакуйте исходники PageSpeed:
Скачайте и распакуйте библиотеку оптимизации PageSpeed в папку с исходниками модуля:
Скачайте и распакуйте исходники OpenSSL 1.02:
Теперь нам нужно собрать модуль. Сначала смотрим опции, с которыми собран текущий Nginx:
А теперь переходим в папку с Nginx, подставляем все полученные опции, опцию —add-dynamic-module для PageSpeed, OpenSSL и пробуем собрать:
Если все было сделано правильно, то на выходе вы получите модуль ngx_pagespeed.so в папке obj, его нужно скопировать в папку /etc/nginx/modules:
Создаем папку для кэша:
Теперь добавьте такую строчку для включения модуля в /etc/nginx/nginx.conf:
Затем, в секцию сервер достаточно добавить:
Теперь вам достаточно перезапустить nginx чтобы изменения вступили в силу:
Шаг 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 в раздел вашего сервера:
Практическое упражнение: простой календарь
В данном примере вы поможете нам закончить простое приложение календаря. Код включает:
- Элемент , позволяющий пользователю выбирать разные месяцы.
- Обработчик событий для обнаружения изменения значения, выбранного в меню .
- Функция , рисующая календарь и отображающая правильный месяц в элементе <h1> (en-US).
Вы должны написать условную конструкцию в функции обработчика , сразу после комментария . Конструкция должна:
- Проверить выбранный месяц (хранящийся в переменной . Это будет значение элемента после изменения значения, например, «Январь».)
- Задать переменную, скажем, , равную количеству дней в выбранном месяце. Для этого нужно будет проверить количество дней в каждом месяце. Високосный год можно не учитывать.
Советы:
- Советуем использовать логический оператор OR для группировки нескольких месяцев в рамках одного условия; многие месяцы имеют одинаковое количество дней.
- Подумайте, какое количество дней в месяце встречается чаще всего и используйте его в качестве варианта по умолчанию.
Если допустили ошибку, используйте кнопку «Сброс», чтобы вернуться к исходному виду примера. Если у вас совсем ничего не получается, нажмите «Показать решение».
В HTML коде внутри названия месяцев введены на русском языке. Соответственно ссылки на них из вашего скрипта так же на русском. Не забываем про синтаксис. (прим. — ConstantineZz)
Использование всей цепочки сертификатов
Применяя сертификат в NGINX, необходимо загрузить не только сертификат для домена, но и для всех центров сертификации — как основного, так и промежуточных. В противном случае, мы получим ошибку This server’s certificate chain is incomplete. Grade capped to B:
В случае покупки сертификата, нам отправляют все ключи в отдельных файлах. Цепочка сертификатов, как правило, идет в файле chain. Мы должны скопировать последовательность в данном файле и добавить ее к содержимому в файле с сертификатом домена — получиться файл, содержащий как последовательность для домена, так и всех центров. Назвать его можно fullchain.pem.
В случае получение бесплатного сертификата от Let’s Encrypt, мы получаем 4 файла, один из которых называется fullchain.pem — именно он и содержит все необходимые последовательности.
И так, при настройке виртуального домена в NGINX, необходимо указать путь до файла, содержащего в себе все ключи, например:
server {
listen 443;
server_name security.dmosk.ru;
ssl on;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/cert.key;
…
}
* в данном примере мы настраиваем NGINX для домена security.dmosk.ru; обратите внимание, что мы указали путь до файла fullchain.pem, в котором должны находиться последовательности, как для домена, так и центров сертификации. Не забываем перезапустить nginx:
Не забываем перезапустить nginx:
systemctl restart nginx