В этой статье я расскажу о получении wildcard SSL сертификата Let’s Encript при помощи скрипта acme.sh, и сервера bind. Также покажу как настроить автоматическое обновление сертификатов.
Надо сказать, что ранее на своих серверах я использовал для этих целей certbot, который просто устанавливал при помощи пакетного менеджера. Но так как разработчики certbot приняли решение распространять его в виде snap-пакета, а у меня демон snapd полностью из системы выпилен, то пришлось искать альтернативные решения. Об одном из них — acme.sh, я и хочу рассказать.
Оглавление
Настройка BIND
Итак, друзья, давайте мы займемся настройкой возможности динамического обновления сервера DNS bind (о его настройке я уже писал ранее). Во-первых, для этого нам необходимо создать ключи TSIG.
Чтобы создать ключ tsig и файл конфигурации зоны для bind вы можете выполнить shell-скрипт, которым я пользуюсь для экономии времени.
#!/usr/bin/env bash domain='domain.tld' tsig-keygen -a HMAC-SHA512 acme.$domain > acme.$domain.key cat <<EOF > acme.$domain.conf zone "acme.$domain" IN { type master; file "/var/lib/bind/acme.$domain"; allow-query { any; }; update-policy { grant "acme.$domain" name _acme-challenge.acme.$domain. txt; }; }; EOF cat acme.$domain.key >> acme.$domain.conf
В результате его выполнения вы получите два файла: acme.domain.tld.conf — файл конфигурации зоны и acme.domain.tld.key — файлы tsig-ключа. Конфигурационный файл зоны нужно добавить в конфигурационный файл bind /etc/bind/named.conf.local.
В целях безопасности мы не будем добавлять разрешение на обновление основной зоны нашего домена, а добавим еще одну техническую зону для ответа на вызовы dns-01 ACME и уже для нее включим динамические обновления. Ну а в основной зоне мы просто создадим запись CNAME для challenge-записи, которая будет указывать на техническую зону:
; Алиас для записи dns-01 challenge. _acme-challenge CNAME _acme-challenge.acme.domain.tld.
В итоге нам, конечно, необходимо убедиться, что динамические обновления работают. Это можно сделать с помощью утилиты nsupdate. Давайте добавим запись TXT в нашей зоне acme.domain.tld проверим ее добавление.
$ nsupdate -k /etc/bind/acme.domain.tld.key -v > debug yes > server domain.tld > zone acme.domain.tld. > update add test.acme.domain.tld. 86400 TXT "text" > show Outgoing update query: ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 0 ;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0 ;; ZONE SECTION: ;acme.domain.tld. IN SOA ;; UPDATE SECTION: test.acme.domain.tld. 86400 IN TXT "text" > send Sending update to ::1#53 Outgoing update query: ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 46815 ;; flags:; ZONE: 1, PREREQ: 0, UPDATE: 1, ADDITIONAL: 1 ;; ZONE SECTION: ;acme.domain.tld. IN SOA ;; UPDATE SECTION: test.acme.domain.tld. 86400 IN TXT "text" ;; TSIG PSEUDOSECTION: acme.domain.tld. 0 ANY TSIG hmac-sha512. 1636652685 300 64 acIwDVA9B0WS+koh9/OWNOHbIRnONkmGN/d6zVbY8bVAcoxyDDIJvGi8 1NP6uaWzubn4iITO2qHLAo5t/RO2KQ== 46815 NOERROR 0 Reply from update query: ;; ->>HEADER<<- opcode: UPDATE, status: REFUSED, id: 46815 ;; flags: qr; ZONE: 1, PREREQ: 0, UPDATE: 0, ADDITIONAL: 1 ;; ZONE SECTION: ;acme.domain.tld. IN SOA ;; TSIG PSEUDOSECTION: acme.domain.tld. 0 ANY TSIG hmac-sha512. 1636652685 300 64 pkodEyw4PIiR8qTy9Gnmjg/MKDGW245CcMUShfRYlDy7/gXSSvsEeCJN 5h56SMRjctB5fPsXY04mGbsqcM9A1w== 46815 NOERROR 0 > quit $ dig +short -t txt test.acme.domain.tld "text"
После проверки не забудьте удалить TXT запись из зоны (update delete test.acme.domain.tld.
).
Установка acme.sh
Если у вас все получилось, то можно приступать к установке shell-скрипта acme.sh. Я предпочитаю способ установки при помощи git (на странице скрипта в github есть и другие способы).
sudo -s cd /tmp git clone https://github.com/acmesh-official/acme.sh.git cd acme.sh ./acme.sh --install --cert-home '/etc/letsencript' --email 'account@email.com' cd .. rm -rf acme.sh
Итак, скрипт по умолчанию будет установлен в ~/.acme.sh. Кроме этого будет добавлена задача обновления сертификатов в crontab. Вы можете посмотреть ее при помощи crontab -e.
Получение сертификатов
Ну что же, почти все готово. Чтобы получить сертификаты Let’s Encript при помощи скрипта acme.sh мы будем использовать плагин dns_nsupdate для внесения требуемых записей в зону, обслуживаемую bind. Для выпуска сертификата можно воспользоваться следующим скриптом:
#!/usr/bin/env bash NSUPDATE_SERVER='ns.domain.tld' export NSUPDATE_SERVER NSUPDATE_KEY='/etc/bind/acme.domain.tld.key' export NSUPDATE_KEY . "/root/.acme.sh/acme.sh.env" /root/.acme.sh/acme.sh --set-default-ca --server letsencrypt /root/.acme.sh/acme.sh --issue -d 'domain.tld' -d '*.domain.tld' --challenge-alias acme.domain.tld --dns dns_nsupdate --renew-hook '/root/.acme.sh/renew-hook.sh'
Если все прошло успешно, то выпущенные сертификаты можно будет найти в каталоге, который вы указали в параметре --cert-home
при установке скрипта ( по умолчанию ~/.acme.sh/domain.tld ). Ну а содержимое скрипта, которое будет выполнено после обновления сертификатов предлагаю вам написать самостоятельно. Обычно — это просто перезапуск сервисов, которые используют выпущенные сертификаты.
На этом статья об автоматизации получения SSL сертификатов Let’s Encrypt с помощью acme.sh и bind завершена. Как обычно я жду ваши вопросы и замечания в комментариях. Удачи!
Если указывать:
update-policy {
grant «acme.$domain» name _acme-challenge.acme.$domain. txt;
То update add test.acme.domain.tld. 86400 TXT «text» не отработает
Надо тогда на _acme-challenge.acme и проверять