Несколько сертификатов на Nginx

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


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


Несколько сертификатов на Nginx

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

Приступим!

Особенности работы SSL/TLS

Тут я не планирую рассказывать про асимметричные алгоритмы и принципы шифрования. Поговорим о том, как взаимодействуют TLS и HTTP.

Инкапсуляция

Когда вы вбиваете в браузере имя сайта или переходите по ссылке/закладке, в работу включается множество протоколов различных уровней. Между уровнями протоколы обычно никак не связаны и даже не знают о существовании друг друга. И это правильно. Представьте, если бы протоколы уровня Application (например веб-браузер) начали переживать что же происходит на транспортном уровне с TCP.

Озвученный выше момент очень важен для понимания принципа работы HTTPS в целом (и далеко не только его). Дело в том, что при обращении к какому-либо веб-ресурсу, сначала в ход пойдут протоколы всех нижестоящих уровней по очереди с самого низкого и только в самом конце начнут отправляться данные HTTP. Этот процесс называется инкапсуляцией и наиболее точно его механизм работы изображен на картинке ниже 1:

Примечание: не поленитесь и зайдите на сайт, ссылку на который я дал выше перед картинкой. Мало того, что там наглядно продемонстрировано как работает инкапсуляция, так это ещё и сделано на примере HTTPS!

Хоть и в сетевой модели TCP/IP протоколы TLS и HTTP принадлежат одному уровню (Application), модель OSI/ISO размещает их на разных уровнях (HTTP — Application, TLS — Presentation).

Было

Когда клиент подключается к веб-ресурсу с использованием TLS, выполняется процесс согласования и установки защищенного соединения. Это называется SSL handshake. Коротко и в человекопонятном виде эта процедура изображена на картинке ниже 2:

https://quickkirukkalgal.blogspot.com/p/multiple-certs-on-one-vip.html

Данные передаются в незащищенном виде, но это лишь служебная информация. Как можно заметить, адрес веб-сайта передается уже непосредственно внутри данных протокола HTTP. Таким образом, напрашивается интересный вывод — на сервере должен быть один сертификат, иначе для определенного доменного имени TLS может использовать неподходящий сертификат.

Такая проблема действительно существовала. Решений было два и оба в лоб:

  1. Засунуть все используемые доменные имена в один сертификат. Крайне неудобный вариант. И он тем больше неудобен, чем больше доменов второго уровня в нем бы использовалось;
  2. Для каждого доменного имени (или набора имен) использовать отдельный адрес. Если для IPv6 это был очень даже неплохой способ, то для IPv4 это уже не подходило в виду исчерпания пула адресов.

Очевидно, что оба варианта очень неудобны.

Стало

Решение проблемы было найдено очень удобное и вместе с тем простое — можно передавать имя веб-ресурса внутри протокола TLS. В этом случае веб-сервер заранее выберет нужный сертификат и установит защищенное соединение именно с его помощью. Механизм этот называется SNI (Server Name Indication — расширение протокола TLS). Процесс установки соединения TLS и начала передачи данных HTTP принял следующий вид:

https://quickkirukkalgal.blogspot.com/p/multiple-certs-on-one-vip.html

Таким образом стало возможно размещать на одном адресе множество доменов с разными сертификатами.

Настройка Nginx

Из теоретического блока выше мы выяснили, что процесс передачи доменного имени веб-ресурса, с которым клиент хочет установить связь, выполняется на этапе установки защищенного сеанса TLS. Уже после этого идет передача полезных данных HTTP. Следовательно, нужно указывать связку домен(ы)-сертификат в одном блоке. Прослушиваемый адрес веб-ресурса мы указываем в секции server {}. Соответственно, там же и должен быть прописан нужный сертификат и его закрытый ключ.

В общем виде этот участок конфигурации может выглядеть так:

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

Но перед реальными изменениями сделайте бэкап конфига, чтобы быстро вернуться к рабочему состоянию, если что-то пойдет не так:

Примечание: если вдруг команда выглядит страшно, то поясню. Конструкция {src,dest} — brace expansion — в данном случае задает имена исходного и целевого файла для команды cp. Конструкция $(date +»%m-%d-%y») выводит текущую дату в формате DD-MM-YY. Итого, целевой файл будет иметь имя например nginx.conf.backup27-02-19.

После изменения конфигурации не забудьте рестартануть демон:

На этом все. Успехов!

comments powered by HyperComments
Яндекс.Метрика