Как стать автором
Обновить

На пути к автоматизации выпуска SSL

Время на прочтение5 мин
Количество просмотров9.3K

Достаточно часто нам приходится работать с 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 на клиентской.


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


То-есть, имеем следующую картину:


Dev Test Staging Production
projectX.dev.company.tld projectX.test.company.tld staging.projectX.tld projectX.tld
module1.projectX.dev.company.tld module1.projectX.test.company.tld module1.staging.projectX.tld module1.projectX.tld
module2.projectX.dev.company.tld module2.projectX.test.company.tld module2.staging.projectX.tld module2.projectX.tld
... ... ... ...
moduleN.projectX.dev.company.tld moduleN.projectX.test.company.tld moduleN.staging.projectX.tld moduleN.projectX.tld

Для production используется купленный wildcard сертификат, тут вопросов не возникает. Но он покрывает только первый уровень поддомена. Соответственно, если есть сертификат для *.projectX.tld — то для staging.projectX.tld он работать будет, а вот для module1.staging.projectX.tld уже нет. А покупать отдельный как-то не хочется.


И это только на примере одного проекта одной компании. А проект, естественно, не один.


Общие для всех причины заняться решением этого вопроса выглядят примерно так:


  • Относительно недавно Google предложили уменьшить максимальный срок действия SSL сертификатов. Со всеми вытекающими.
  • Облегчить процесс выпуска и обслуживания SSL для внутренних нужд проектов и компании в целом.
  • Централизованное хранение записей о сертификатах, которое частично решает проблему подтверждения домена с помощью DNS и последующего автоматического обновления, а также решает вопрос доверия клиента. Все же, больше доверия вызывает CNAME на сервер компании партнера/исполнителя, чем на сторонний ресурс.
  • Ну, и наконец, в этом случае фраза “лучше иметь чем не иметь” подходит отлично.

Выбор провайдера SSL и подготовительные шаги


Из доступных вариантов бесплатных SSL сертификатов рассматривались cloudflare и letsencrypt. DNS для этого (и некоторых других проектов) как располагается на cloudflare, но я не сторонник использования их сертификатов. Поэтому, было решено использовать letsencrypt.
Для создания wildcard SSL сертификата нужно подтвердить владение доменом. Эта процедура предполагает создание некоторой DNS записи (TXT или CNAME), с последующей ее проверкой при выпуске сертификата. В Linux есть утилита — certbot, которая позволяет частично (или полностью для некоторых DNS провайдеров) автоматизировать этот процесс. Для Windows же из найденных и проверенных вариантов ACME клиентов я остановился на WinACME.


А запись для домена создана, переходим к созданию сертификата:


image


Нас интересует последний вывод, а именно — доступные варианты подтверждения владения доменом для выпуска wildcard сертификата:


  1. Создание DNS записей вручную (автоматическое обновление не поддерживается)
  2. Создание DNS записей с помощью acme-dns сервера (подробнее можно почитать тут.
  3. Создание 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

А вот acme.2nd.pp.ua резолвиться не будет, так как DNS сервер который его обслуживает еще не запущен.


Записи созданы, переходим к настройке и запуску ACME-DNS сервера. Жить он у меня будет на ubuntu server в docker контейнере, но запустить его можно везде где есть golang. Windows тоже вполне подойдет, но я все же предпочитаю Linux сервер.


Создаем необходимые директории и файлы:


$ mkdir config
$ mkdir data
$ touch config/config.cfg

Воспользуемся vim вашим любимым текстовым редактором и вставим в config.cfg образец конфигурации.


Для успешной работы достаточно подправить секции general и api:


[general]
listen = "0.0.0.0:53"
protocol = "both"
domain = "acme.2nd.pp.ua"
nsname = "acmens.2nd.pp.ua" 
nsadmin = "admin.2nd.pp.ua" 
records = 
    "acme.2nd.pp.ua. A 35.237.128.147",
    "acme.2nd.pp.ua. NS acmens.2nd.pp.ua.",                                                                                                                                                                                                  ]
...
[api]
...
tls = "letsencrypt"
…

Также, по желанию, создадим docker-compose файл в основной директории сервиса:


version: '3.7'
services:
  acmedns:
    image: joohoi/acme-dns:latest
    ports:
      - "443:443"
      - "53:53"
      - "53:53/udp"
      - "80:80"
    volumes:
      - ./config:/etc/acme-dns:ro
      - ./data:/var/lib/acme-dns

Готово. Можно запускать.


$ docker-compose up -d

На данном этапе должен начать резолвиться хост acme.2nd.pp.ua, и появиться 404 на https://acme.2nd.pp.ua


$ ping acme.2nd.pp.ua
PING acme.2nd.pp.ua (35.237.128.147) 56(84) bytes of data.

$ curl https://acme.2nd.pp.ua
404 page not found

Если этого не появилось — docker logs -f <container_name> в помощь, благо, логи вполне читабельные.


Можем приступать к созданию сертификата. Открываем powershell от имени администратора и запускаем winacme. Нас интересуют выборы:


  • M: Create new certificate (full options)
  • 2: Manual input
  • 2: [dns-01] Create verification records with acme-dns (https://github.com/joohoi/acme-dns)
  • На вопрос о ссылке на 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.

image


Создаем необходимую запись, и убеждаемся что она создалась корректно:


image


$ dig CNAME _acme-challenge.1nd.pp.ua +short
c82a88a5-499f-464f-96e4-be7f606a3b47.acme.2nd.pp.ua.

Подтверждаем что мы создали нужную запись в winacme, и продолжаем процесс создания сертификата:


image


Как использовать certbot в качестве клиента описано тут.


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

Теги:
Хабы:
Всего голосов 3: ↑2 и ↓1+4
Комментарии8

Публикации

Истории

Работа

Ближайшие события

2 – 18 декабря
Yandex DataLens Festival 2024
МоскваОнлайн
11 – 13 декабря
Международная конференция по AI/ML «AI Journey»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань