Данный туториал является компиляцией информации по выпуску wildcart сертификата от let`s encrypt, с полезными дополнениями, без которых выпуск сертификата оказывается затруднительным. В статье используется bind9 - dns сервер и предполагается что вы уже делегировали ваш домен на свои DNS сервера.

Ссылки на исходные статьи: статья 1, статья 2


Для создания wildcart сертификата от 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 серверу на котором не будет необходимой записи и валидация владения доменом будет провалена.

Комментарии (1)


  1. Anonym
    06.07.2025 16:23

    А можно просто взять acme.sh