Получение LetsEncrypt wildcard сертификата

По следам статьи с сайта — 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. Кому как нравится.

Список использованных источников:

Подписаться
Уведомить о
guest

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии