Данный туториал является компиляцией информации по выпуску wildcard сертификата от let`s encrypt, с полезными дополнениями, без которых выпуск сертификата оказывается затруднительным. В статье используется bind9 - dns сервер и предполагается что вы уже делегировали ваш домен на свои DNS сервера.
Ссылки на исходные статьи: статья 1, статья 2
Для создания wildcard сертификата от letsencrypt нужно использовать DNS модуль сертбота dns-rfc2136 (с помощью nginx такой сертификат создать невозможно). Но предварительно нужно настроить сам DNS сервер.
Настройка DNS сервера
Выпуск TSIG ключа
Для начала нужно выпустить tsig key, с помощью которого сертбот сможет авторизоваться на сервере и вносить изменения. Для упрощения можно воспринимать этот ключ как API key DNS сервера.
tsig-keygen -a hmac-sha512 <произвольное имя ключа> > /etc/bind/<файл куда будет сохранен ключ>
в результате появится файл с таким содержимым
key <имя ключа которое задали выше> { algorithm hmac-sha512; secret <здесь будет секрет>; };
Выдаем права на файл только пользователю bind.
Далее файл с ключом необходимо добавить в конфигурацию сервера. Это можно сделать добавив include <путь до файла ключа> в файл named.conf
Создание новой подзоны
Сертбот для работы с зоной использует протокол DDNS, который сохраняет изменения в jnl файлы. Данный протокол позволяет автоматически увеличивать serial зоны при внесении изменений что позволяет корректно работать механизму обновления зон на slave серверах. Однако если зона управляется динамически, в нее нельзя вносить изменения вручную, так механизм динамического обновления может сломаться. Чтобы оставить возможность ручного обновления зоны и при этом дать certbot-у корректно вносить новые TXT записи с подтверждением владением домена, создадим новую подзону для конретной записи. Имя подзоны начинается с _acme-challenge , например _acme-challenge.example.com .
Для создания подзоны в named.conf.local создаем новую запись вида
//описание подзоны zone "_acme-challenge.example.com" { type master; file "master/файл с зоной"; allow-transfer { <ip слейв серверов>}; also-notify { <ip слейв серверов> }; notify yes; check-names ignore; //выдаем права update-policy { grant <имя tsig ключа> subdomain _acme-challenge.example.com. TXT; }; }; //здесь указываем каким клиентам можно пользоваться tsig ключом, //нужно указать IP на котором будет работать certbot server 127.0.0.1 { keys { <имя tsig ключа>; }; };
Далее создаем файл зоны с примерно таким содержанием
$ORIGIN . $TTL 3600 ; 1 hour _acme-challenge.example.com IN SOA ns2.example.com. root.example.com. ( 2022121535 ; serial 900 ; refresh (15 minutes) 60 ; retry (1 minute) 86400 ; expire (1 day) 900 ; minimum (15 minutes) ) NS ns2.example.com.
выдаем права на файл пользователю bind и перезагружаем сервер.
После перезагрузки нужно выполнить команду разморозки, которая включит механизм динамического обновления.
rndc thaw _acme-challenge.example.com
после этого нельзя вносить ручные правки в файл подзоны!
Проверки работоспособности
Для проверки работоспособности создадим новый файл checkns.txt
server 127.0.0.1 zone _acme-challenge.example.com update add _acme-challenge.example.com. 600 IN TXT "test" send
Далее выполним команду
nsupdate -v -k <путь до TSIG ключа> checkns.txt
После этого с помощью команды
dig TXT _acme-challenge.example.com @<ip наших DNS>
проверяем есть ли TXT запись с содержанием "test", запись должна появится на обоих серверах! Если запись присутствует то механизм изменения зоны с помощью TSIG работает и можно переходить к настройке certbot, однако чтобы не мешать сертботу необходимо сначала удалить тестовую TXT, это можно сделать заменив 'add' в файле checkns.txt на 'delete' и запустить команду еще раз
Настройка certbot
Прежде всего устанавливаем модуль DNS для certbot
apt install python3-certbot-dns-rfc2136
далее создаем файл конфига выпуска сертифика в /etc/letsecnrypt/ с таким содержанием
dns_rfc2136_server = <ip dns сервера> dns_rfc2136_name = <имя зоны для которой выпускается сертификат> dns_rfc2136_secret = <значение TSIG ключа (без кавычек!)> dns_rfc2136_algorithm = HMAC-SHA512 (алгоритм писать большими буквами)
запускаем certbot командой
certbot -v certonly --dns-rfc2136 --force-renewal --dns-rfc2136-propagation-seconds 120 --dns-rfc2136-credentials /etc/letsencrypt/ns.example.com-rfc2136.ini --server https://acme-v02.api.letsencrypt.org/directory --email hostmaster@example.com --agree-tos --no-eff-email -d "example.com" -d "*.example.com"
ключ --dns-rfc2136-propagation-seconds 120 указывает сколько времени пройдет между добавлением TXT записи и проверкой этой записи серверами let`s encrypt.
Если в процессе выпуска вы все равно получаете ошибку валидации, то стоит проверить точно ли slave сервера успевают получить обновления. Если механизм обновления зоны не работает, а сертификат нужно выпустить скорее, то за время указанное в dns-rfc2136-propagation-seconds, нужно успеть выполнить ручную переотправку зоны
rndc retransfer _acme-challenge.example.com
Однако, стоит помнить что в случае ручной переотправки зоны, возникнут проблемы при автоматическом обновлении сертификата сертботом, так как проверяющий сервер let`s encrypt может обратиться к slave серверу на котором не будет необходимой записи и валидация владения доменом будет провалена.
