🔐 Wildcard от Let's Encrypt через Certbot

02.05.2022

Возникла необходимость выпустить Wildcard сертификат Let's Encrypt на все поддомены. Wildcard потому что поддоменов может быть много, а лишний раз заказывать сертификат (и продлевать его) не очень хочется, проще один заказать и продлить ... но это не про Yandex Connect (PDD).

В базовом варианте достаточно использовать Certbot для работы с сертификатами на веб-сервере. Но по ходу решения поставленной задачи я познакомился с Acme.sh, который из коробки умеет работать с Yandex API.

Ручной выпуск Wildcard от Let's Encrypt

Wildcard от Let's Encrypt требует подтверждения через TXT запись в DNS домена. Это значит что надо:

  • запустить Certbot чтобы он выдал TXT запись для вставки в DNS
  • руками добавить запись в DNS
  • продолжить выпуск сертификата после обновления сервера DNS
  • повторить процедуру через 3 месяца (такой срок имеют сертификаты от от Let's Encrypt)
•••
bash
$ sudo certbot certonly \ --agree-tos \ --email box@domain.zone \ --server https://acme-v02.api.letsencrypt.org/directory -d *.byurrer.ru \ --manual \ --preferred-challenges dns-01

После ввода всяких подтверждений Certbot выдаст что-то подобное:

•••
bash
Please deploy a DNS TXT record under the name _acme-challenge.byurrer.ru with the following value: 1dLFl8nzgBT5mP0sP4uInlH3Ow2a1jIeJkKcHKNy0eg Before continuing, verify the record is deployed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Press Enter to Continue

Certbot не отдаст управление и будет ждать ввода Enter для продолжения. В это время нужно добавить запись в DNS и подождать пока DNS сервер обновится, после чего можно продолжать.

Узнать обновление DNS можно так:

•••
bash
$ dig -t txt _acme-challenge.byurrer.ru ... _acme-challenge.byurrer.ru. 3600 IN TXT "1dLFl8nzgBT5mP0sP4uInlH3Ow2a1jIeJkKcHKNy0eg" ...

Запись появилась, продолжаем.

Автоматизация выпуска Wildcard от Let's Encrypt

Делать такую ручную процедуру каждые 3 месяца утомительно (ага, скажи это шахтерам), поэтому надо автоматизировать.

Certbot поддерживает хуки:

  • --manual-auth-hook - путь или команда для выполнения сценария аутентификации
  • --manual-cleanup-hook - путь или команда для выполнения сценария очистки
При помощи хуков можно автоматизировать выпуск Wildcard от Let's Encrypt если DNS хостинг предоставляет API.

Для DNS на серверах Yandex есть API для DNS, а на GitHub можно найти такой репозиторий с bash скриптами.

Теперь начнем:

  • клонируем репозитрий
  • создаем токен для управления DNS (это должен делать владелец, а не админ, в терминах Yandex), ссылку можно найти здесь
  • вставляем API токен в config.sh
Однако, немного подробнее про DNS у Yandex ...

Во время ожидая обновления можно проверить DNS запись обратившись к DNS серверу напрямую, в разные моменты времени результаты будут разные, значит у Yandex Connect несколько серверов с несинхронным обновлением, и придется ждать их полной синхронизации.

Опытным путем удалось выяснить: время обновления DNS на Yandex Connect составляет несколько часов, я остановился на 4. Но указанный выше репозиторий содержит задержку только на 5 секунд, из-за чего данные на DNS сервере не успеют обновиться и процедура выпуска сертификата закончится провалом.

Для исправления в файле authenticator.sh в конце ставим:

•••
bash
sleep 4h;

А теперь можно попробовать запустить Certbot и проверить автоматический выпуск Wildcard сертификата:

•••
bash
$ sudo certbot certonly \ --force-renew \ --agree-tos \ --email box@domain.zone \ --server https://acme-v02.api.letsencrypt.org/directory -d *.byurrer.ru \ --manual \ --preferred-challenges dns-01 \ --manual-auth-hook ./certbot-dns-pddyandex/authenticator.sh \ --manual-cleanup-hook ./certbot-dns-pddyandex/cleanup.sh

Через 4 часа Certbot сообщит об успешном выпуске Wildcard сертификата.