По следам статьи с сайта — https://www.umgum.com/letsencrypt-wildcard-bind9
Я только актуализировал информацию и оставил только один DNS.
Для автоматического получения wildcard сертификата используемый ACME-клиент (в данном случае Certbot) запрашивает у сервера Let’s Encrypt уникальную строку-идентификатор, которую любым способом необходимо разместить в специальной TXT-записи нижеследующего формата, чтобы проверяющий сервер Let’s Encrypt мог считать её и удостовериться, что мы владеем или управляем указанным DNS-сервером:
_acme-challenge.example.net. 120 IN TXT "Sg0...oLc"
Все вышеуказанные действия подразумевают под собой ручное редактирование зоны, что в условиях наличия нескольких серверов DNS представляет большую трудоёмкость, да и ручное обновление сертификатов рано или поздно приведёт к истечению срока действия текущего.
Поэтому проще всего использовать дополнительно устанавливаемый certbot-плагин «dns-rfc2136«, автоматизирующий процедуры получения секретного ключа, публикующий его и удаляющий DNS-запись после завершения запроса, область действия которого, как правило, достаточно просто ограничивается настройками NS-сервера, как такового.
Плагин «dns-rfc2136» взаимодействует с DNS-сервером посредством протокола «Dynamic DNS (DDNS)» с подписанием команд посредством «Transaction SIGnature (TSIG)». Не все DNS-серверы поддерживают эту связку, но Bind9 в этом плане полностью функциональный.
Для начала подготовим необходимые файлы и настройки на DNS-сервере
ОС: Ubuntu
ПО: Certbot, bind9
Сгенерируем TSIG-ключ для подписания транзакций от ACME-приложений
tsig-keygen -a hmac-sha512 letsencrypt-example.net > /etc/bind/tsig.key
, где
tsig-keygen — утилита, входящая в состав bindutils при установке сервера bind9,
-a — тип алгоритма генерации,
hmac-sha512 — сам алгоритм,
letsencrypt-example.net — просто имя ключа. Его можно задать любым.
Сгенерированный ключ пишется в файл /etc/bind/tsig.key, содержимое которого примерно такое
key "letsencrypt-example.net" { algorithm hmac-sha512; secret "INVc+PYj...sF/USw=="; };
Защищаем файл от просмотра другими пользователями
chown bind:bind /etc/bind/tsig.key chmod 640 /etc/bind/tsig.key
Включаем файл ключа в конфигурацию Bind9. Главное, чтобы ключ был описан вне пределов параметра options . Лучше описать его в файле named.conf
nano /etc/bind/named.conf
... include "/etc/bind/tsig.key"; ...
Использование протокола DDNS, посредством которым Certbot подключается и оперирует сущностями Bind9 проявляет в работе последнего неприятную особенность — при внесении изменений в доменную зону таковые вначале записываются в автоматически создаваемый файл журнала транзакций «*.jnl», которые минут через пятнадцать вливаются в оригинальный конфигурационный файл зоны, перезаписывая его с форматированием возможно кардинально отличающимся от исходного. Это неприемлемо в случае поддержания DNS-сервиса ручными правками, так что для тех доменов, для которых нужно запрашивать wildcard-сертификаты «Let`s Encrypt», будет лучше создавать выделенные для ACME-взаимодействий конфигурационные файлы доменной зоны:
В файле описания местоположения доменных зон пишем
nano /etc/bind/named.conf.local
... // Выделенная для взаимодействия с сервисами "Let`s Encrypt" доменная зона zone "_acme-challenge.example.net" IN { type master; file "/var/lib/bind/db._acme-challenge.example.net"; check-names ignore; // Разрешаем предъявителю TSIG-ключа вносить изменения строго определённого характера update-policy { grant letsencrypt-example.net name _acme-challenge.example.net. TXT; }; }; ...
, где
указывается файл отделённой зоны для продления сертификатов. Файл располагается не там, где основное описание доменных зон, а по адресу /var/lib/bind, потому что в Ubuntu из-за политики AppArmor, указанной в файле /etc/apparmor.d/usr.sbin.named описано, что для исполняемого файла named запрещено писать в /etc/bind/, но можно в /var/lib/bind/
В поле update-policy указывается, что только ключ с именем letsencrypt-example.net может менять TXT записи в зоне _acme-challenge.
В файл отделённой доменной зоны помещаются стандартные записи
nano /var/lib/bind/db._acme-challenge.example.net
$TTL 3600 _acme-challenge.example.net. IN SOA ns.example.net. root.example.net. ( 2022121501 ; Serial 900 ; Refresh 60 ; Retry 86400 ; Expire 900 ) ; Negative Cache TTL @ IN NS ns.example.net.
Проверяем файл зоны
named-checkconf /etc/bind/named.conf named-checkzone _acme-challenge.example.net /var/lib/bind/db._acme-challenge.example.net zone _acme-challenge.example.net/IN: loaded serial 2022121525 OK
systemctl restart bind9
Теперь когда на DNS-сервере подготовлены файлы зоны, ключа и указана новая зона, можно приступить к настройке на стороне сервера, где установлен Certbot.
Устанавливаем плагин certbot-dns-rfc2136
apt install python3-certbot-dns-rfc2136
Настраиваем плагин.
Подготовим TSIG ключ, который был сгенерирован на DNS-сервере
nano /etc/letsencrypt/ns.example.net-rfc2136.ini
# (обязательно указывать IP-адрес, а не FQDN целевого NS-сервера!) dns_rfc2136_server = 192.168.1.1 dns_rfc2136_name = letsencrypt-example.net dns_rfc2136_secret = INVc+PY...LsF/USw== dns_rfc2136_algorithm = HMAC-SHA512
,где
dns_rfc2136_server — IP сервера, на котором установлен Bind9,
dns_rfc2136_name — имя ключа, который указывался в файле tsig.key,
dns_rfc2136_secret — секрет, который так же указывался в файле ключа tsig.key.
dns_rfc2136_algorithm — алгоритм шифрования ключа.
Защищаем файл настройки от просмотра другими пользователями.
chmod 640 /etc/letsencrypt/ns.example.net-rfc2136.ini
Проверяем, что certbot корректно отрабатывает
Запускаем его с параметром —dry-run
certbot certonly --dry-run --dns-rfc2136 --force-renewal \ --dns-rfc2136-propagation-seconds 10 \ --dns-rfc2136-credentials /etc/letsencrypt/ns.example.net-rfc2136.ini \ --server https://acme-v02.api.letsencrypt.org/directory --email hostmaster@example.net \ --agree-tos --no-eff-email -d "example.net" -d "*.example.net"
, где —dns-rfc2136 — тип аутентификации через плагин dns-rfc2136,
—dns-rfc2136-propagation-seconds — количество секунд для ожидания создания и появления TXT записей, чтобы сервер Let’s Encrypt смог их увидеть,
—dns-rfc2136-credentials — ini файл настроек
Когда пробный запуск увенчается успехом, можно запустить команду без ключа —dry-run
certbot certonly --dns-rfc2136 --force-renewal --dns-rfc2136-propagation-seconds 10 \ --dns-rfc2136-credentials /etc/letsencrypt/ns.example.net-rfc2136.ini \ --server https://acme-v02.api.letsencrypt.org/directory --email hostmaster@example.net \ --agree-tos --no-eff-email -d "example.net" -d "*.example.net"
Команда запишет необходимые настройки в файл /etc/letsencrypt/renewal/example.net.conf и получит новые сертификаты.
Для последующего продления можно использовать команду certbot renew
Полученные сертификаты можно использовать с любимым веб-сервером. Ну и занести в крон. Или в таймеры systemd. Кому как нравится.
Список использованных источников: