Достаточно часто нам приходится работать с SSL сертификатами. Давайте вспомним процесс создания и установки сертификата (в общем случае для большинства).
Найти провайдера (сайт на котором мы можем купить SSL).
Сгенерировать CSR.
Отправить его провайдеру.
Подтвердить владение доменом.
Получить сертификат.
Преобразовать сертификат в нужную форму (опционально). Например, из pem в PKCS #12.
Установить сертификат на веб сервер.
Относительно быстро, не сложно и понятно. Этот вариант вполне годится, если у нас есть максимум десяток проектов. А если их больше, и у них минимум по три окружения? Классический dev — staging — production. В этом случае стоит задуматься об автоматизации этого процесса. Предлагаю, немного углубиться в проблему и найти решение которое в дальнейшем минимизирует временные затраты на создание и обслуживание сертификатов. В статье будет присутствовать анализ проблемы и небольшое руководство к повторению.
Заранее оговорюсь: основная специализация нашей компании — .net, а соответственно IIS и прочие виндовые вытекающие. Поэтому, ACME клиент и все действия для него тоже будут описаны с точки зрения использования windows.
Для кого это актуально и некоторые исходные данные
Компания К в лице автора. URL (для примера): company.tld
Проект X — один из наших проектов, занимаясь которым я пришел к выводу что все таки нужно двигаться в сторону максимальной экономии времени при работе с сертификатами. У этого проекта есть четыре окружения: dev, test, staging и production. Dev и test находятся на нашей стороне, staging и production на клиентской.
Особенностью проекта является то, что у него есть большое количество модулей, которые доступны как поддомены.
Для production используется купленный wildcard сертификат, тут вопросов не возникает. Но он покрывает только первый уровень поддомена. Соответственно, если есть сертификат для *.projectX.tld — то для staging.projectX.tld он работать будет, а вот для module1.staging.projectX.tld уже нет. А покупать отдельный как-то не хочется.
И это только на примере одного проекта одной компании. А проект, естественно, не один.
Общие для всех причины заняться решением этого вопроса выглядят примерно так:
Облегчить процесс выпуска и обслуживания SSL для внутренних нужд проектов и компании в целом.
Централизованное хранение записей о сертификатах, которое частично решает проблему подтверждения домена с помощью DNS и последующего автоматического обновления, а также решает вопрос доверия клиента. Все же, больше доверия вызывает CNAME на сервер компании партнера/исполнителя, чем на сторонний ресурс.
Ну, и наконец, в этом случае фраза “лучше иметь чем не иметь” подходит отлично.
Выбор провайдера SSL и подготовительные шаги
Из доступных вариантов бесплатных SSL сертификатов рассматривались cloudflare и letsencrypt. DNS для этого (и некоторых других проектов) как располагается на cloudflare, но я не сторонник использования их сертификатов. Поэтому, было решено использовать letsencrypt.
Для создания wildcard SSL сертификата нужно подтвердить владение доменом. Эта процедура предполагает создание некоторой DNS записи (TXT или CNAME), с последующей ее проверкой при выпуске сертификата. В Linux есть утилита — certbot, которая позволяет частично (или полностью для некоторых DNS провайдеров) автоматизировать этот процесс. Для Windows же из найденных и проверенных вариантов ACME клиентов я остановился на WinACME.
А запись для домена создана, переходим к созданию сертификата:
Нас интересует последний вывод, а именно — доступные варианты подтверждения владения доменом для выпуска wildcard сертификата:
Создание DNS записей вручную (автоматическое обновление не поддерживается)
Создание DNS записей с помощью acme-dns сервера (подробнее можно почитать aquí.
Создание DNS записей с помощью собственного скрипта (аналог плагина cloudflare для certbot).
На первый взгляд, третий пункт вполне подходит, но если DNS провайдер не поддерживает этот функционал? А нам необходим общий случай. А общий случай — это CNAME записи, уж их то все поддерживают. Следовательно, останавливаемся на пункте 2, и идем настраивать свой ACME-DNS сервер.
Настройка ACME-DNS сервера и процесс выпуска сертификата
Для примера, я создал домен 2nd.pp.ua, и в дальнейшем буду использовать его.
Обязательным требованием для корректной работы сервера является создание NS и А записи для его домена. И первый неприятный момент с которым я столкнулся — cloudflare (по крайней мере в режиме бесплатного использования) не позволяет одновременно создать NS и A запись для одного и того же хоста. Не то чтобы это было проблемой, но в bind это можно. Саппорт ответил, что их панель так делать не позволяет. Не беда, создадим две записи:
acmens.2nd.pp.ua. IN A 35.237.128.147
acme.2nd.pp.ua. IN NS acmens.2nd.pp.ua.
На данном этапе у нас должен резолвиться хост acmens.2nd.pp.ua.
$ ping acmens.2nd.pp.ua
PING acmens.2nd.pp.ua (35.237.128.147) 56(84) bytes of data
Sinó acme.2nd.pp.ua резолвиться не будет, так как DNS сервер который его обслуживает еще не запущен.
Записи созданы, переходим к настройке и запуску ACME-DNS сервера. Жить он у меня будет на ubuntu server в docker контейнере, но запустить его можно везде где есть golang. Windows тоже вполне подойдет, но я все же предпочитаю Linux сервер.
Создаем необходимые директории и файлы:
$ mkdir config
$ mkdir data
$ touch config/config.cfg
Воспользуемся vim вашим любимым текстовым редактором и вставим в config.cfg образец configuració.
Для успешной работы достаточно подправить секции general и api:
На вопрос о ссылке на ACME-DNS сервер вводим в ответ URL созданного сервера (https). URL of the acme-dns server: https://acme.2nd.pp.ua
В отвер клиент выдает запись которую надо добавить в существующий DNS сервер (процедура единоразовая):
[INFO] Creating new acme-dns registration for domain 1nd.pp.ua
Domain: 1nd.pp.ua
Record: _acme-challenge.1nd.pp.ua
Type: CNAME
Content: c82a88a5-499f-464f-96e4-be7f606a3b47.acme.2nd.pp.ua.
Note: Some DNS control panels add the final dot automatically.
Only one is required.
Создаем необходимую запись, и убеждаемся что она создалась корректно:
Подтверждаем что мы создали нужную запись в winacme, и продолжаем процесс создания сертификата:
Как использовать certbot в качестве клиента описано aquí.
На этом процесс создания сертификата закончен, можно устанавливать его на веб-сервер и использовать. Если при создании сертификата создать также и задание в планировщике, то в дальнейшем процесс обновления сертификата будет происходить автоматически.