Hlavní navigace

Nástroj acme-dns: pohodlné získávání certifikátu pomocí DNS

HTTPS certifikáty od Let's Encrypt je možné získávat dvěma způsoby: pomocí HTTP a DNS. Pokud chcete wildcardy, zbývá vám pouze druhá možnost. S pohodlným generováním vám pomůže nástroj acme-dns.
Věroš Kaplan 23. 6. 2020
Doba čtení: 6 minut

Sdílet

Co je acme-dns

Nástroj acme-dns je specializovaný DNS server, určený k pohodlnému ověřování DNS-01 challenges ze standardu ACME. Ten používá především certifikační autorita Let's Encrypt.

Server acme-dns zjednodušuje generování certifikátů včetně wildcard a podporují ho různé nástroje pro generování certifikátů – ze známých například acme.sh, traefik nebo v Kubernetes cert-manager.

Proč použít acme-dns?

Tento odstavec může spěchající čtenář, který hledá rychlý návod copy-and-paste, v klidu přeskočit. Setkáme se zase u nadpisu: „Jak acme-dns použít“, ano?

Challenge DNS-01 od uživatele žádajícího o vystavení certifikátu očekává, že dokáže vložit TXT záznam _acme-challenge do DNS zóny, pro kterou vyžaduje certifikát. Při vystavování certifikátu pro example.com tedy autorita hledá TXT záznam _acme-challenge.example.com. Dotyčný záznam by měl obsahovat náhodný řetězec, který nám autorita poslala, čímž prokážeme, že doménu ovládáme a jsme oprávněni pro ni požadovat certifikát. Vytvoření TXT záznamu je možné zařídit mnoha různými způsoby, pro Bind a Knot DNS to popsali Ondřej CaletkaPetrem Krčmářemčlánku na Rootu.

Nevýhodou konfigurace v původním článku popsané je, že proces žádající o certifikát musí mít oprávnění zasahovat do DNS zóny, což není vždy technicky možné.

Alternativní řešení se zástupnou (proxy) zónou popsal v češtině Dan Ohnesorgjiném článku na Root.cz. V angličtině ho popsal na blogu EFF v zápisku Securing the Automation of ACME DNS Joona Hoikkala (autor acme-dns) a použil acme-dns.

Řešení spočívá v tom, že DNS jméno _acme-challenge.example.com  delegujeme na DNS jméno, které směřuje na jiný DNS server, který dynamické změny podporuje. Obvykle je toto jméno ve speciální DNS zóně – té se říká zástupná zóna (proxy).

Acme-dns se používá právě pro obsluhu této zástupné zóny a nabízí k tomu pohodlné HTTP API. Pomocí API je možné vkládat TXT záznamy, které tam potom Let's Encrypt může hledat. Jiné než TXT dotazy acme-dns zamítne.

Protože je acme-dns open-source, můžeme ho provozovat na vlastní infrastruktuře, což autoři i doporučují. Pro lenochy je ale dostupná i veřejná instance, která běží na adrese auth.acme-dns.io.

Jak acme-dns použít?

Ukázka: Chceme zřídit wildcard certifikát například pro jména: koren.cz a *.koren.cz a použijeme zmíněnou veřejnou instanci acme-dns.

Nejprve se na acme-dns zaregistrujeme. To provedeme pomocí HTTP POST požadavku na URL  /register/:

 $ curl -XPOST https://auth.acme-dns.io/register

Nameserver v acme-dns  vytvoří samostatnou subdoménu. V HTTP odpovědi pak dostaneme JSON se jménem domény a přihlašovací údaje potřebné ke změně DNS záznamů. Např.

   { "username":"4a9b69a2-bb8d-4cda-b2e3-fd1a265c3b04",
     "password":"aer7eL0ooch6Dohg6Uo0xaY8hokoorohmie7ohga",
     "fulldomain":"b1efaf61-e641-4b2c-9168-b8adc2ca0801.auth.acme-dns.io",
     "subdomain":"b1efaf61-e641-4b2c-9168-b8adc2ca0801",
     "allowfrom":[]
   }

Tahle část se provádí pouze při prvním generování certifikátu. Jméno uživatele, heslo a jméno domény si schováme.

Interně si acme-dns vytvoří v databázi dva prázdné TXT záznamy, které bude později měnit podle požadavků na API.

Získali jsme vlastní DNS doménu b1efaf61-e641-4b2c-9168-b8adc2ca0801.auth.acme-dns.io. Můžeme si ručně vyzkoušet, že nastavení TXT záznamu pomocí HTTP API funguje:

    # export config variables
    export ACMEDNS_UPDATE_URL="https://auth.acme-dns.io"
    export ACMEDNS_USERNAME="4a9b69a2-bb8d-4cda-b2e3-fd1a265c3b04"
    export ACMEDNS_PASSWORD="aer7eL0ooch6Dohg6Uo0xaY8hokoorohmie7ohga"
    export ACMEDNS_SUBDOMAIN="b1efaf61-e641-4b2c-9168-b8adc2ca0801"
    # generate random token
    export TOKEN=__this_is_very_random_token_______nbusr123_

     curl -XPOST \
         -H "X-Api-User: ${ACMEDNS_USERNAME}" \
         -H "X-Api-Key: ${ACMEDNS_PASSWORD}" \
         -H 'content-type: application/json' \
         -d "{ \"subdomain\": \"${ACMEDNS_SUBDOMAIN}\", \"txt\": \"${ACMDNS_TOKEN}\" }" \
         ${ACMEDNS_UPDATE_URL}/update

Ověřit, že TXT záznam se povedlo vložit, můžeme např. příkazem dig

dig ${ACMEDNS_SUBDOMAIN}.auth.acme-dns.io txt

Pokud acme-dns věříme, můžeme ověření v tomto kroku přeskočit. Štouralové na vlastní infrastruktuře se naopak mohou podívat, že v databázi acme-dns je opravdu vložený nový záznam.

Máme tedy k dispozici DNS záznam b1efaf61-e641-4b2c-9168-b8adc2ca0801.auth.acme-dns.io a je potřeba upravit DNS záznam _acme-challenge.koren.cz tak, aby směroval na ten zástupný záznam.

Přidáme do nameserveru, obsluhujícím zónu koren.cz nový CNAME záznam:

_acme-challenge.koren.cz. 300  IN  CNAME   b1efaf61-e641-4b2c-9168-b8adc2ca0801.auth.acme-dns.io.

Můžeme opět ověřit, že uvidíme náhodný token zadaný v předchozím kroku.

$ dig _acme-challenge.koren.cz txt

Přípravná práce je hotová, můžeme si vyžádat certifikát, v případěacme.sh například pomocí:

# export config variables
   export ACMEDNS_UPDATE_URL="https://auth.acme-dns.io/update"
   export ACMEDNS_USERNAME="4a9b69a2-bb8d-4cda-b2e3-fd1a265c3b04"
   export ACMEDNS_PASSWORD="aer7eL0ooch6Dohg6Uo0xaY8hokoorohmie7ohga"
   export ACMEDNS_SUBDOMAIN="b1efaf61-e641-4b2c-9168-b8adc2ca0801"
# ./acme.sh --issue --dns dns_acmedns -d *.koren.cz -d koren.cz

Pokud bude všechno v pořádku, acme.sh připraví soukromý klíč, žádost o certifikát a nechá ji ověřit od CA LetsEncrypt.

Při žádosti acme.sh vytvoří záznamy v připravené zástupné zóně, proběhne ověření ze strany Let's Encrypt a na lokální disk se uloží podepsané certifikáty.

Nainstalujeme vystavené certifikáty a máme hotovo. Při prodlužování certifikátu už má acme.sh poznamenáno, ve které zástupné zóně jsou DNS záznamy vedené, a použije přihlašovací údaje znovu.

Pozor: současná implementace acme.sh implementuje použití pouze jedné sady přihlašovacích údajů a jednoho acme-dns serveru.

Použití s cert-manager v Kubernetes

Pokud bychom chtěli acme-dns použít s Kubernetes a cert-managerem, stačí vytvořit v Kubernetes objekty typu Issuer nebo ClusterIssuer se solverem ACMEDNS. Solver acmedns z cert-manageru vyžaduje uložení jména a hesla pro acme-dns do Kubernetes objektu Secret. Pro každé jméno certifikátu můžeme zadat jiný acme-dns server.

Konfigurace acme-dns

Pro každou proxy zónu je potřeba vytvořit jednu registraci uživatele v acme-dns a pro každou registraci nám acme-dns vytvoří jednu zónu. Nic ale nebrání tomu, do jedné zástupné zóny delegovat více CNAME záznamů z „opravdových“ domén.

Pozor: acme-dns drží v databázi pouze dva poslední TXT záznamy pro každou zónu, pokud by došlo k souběhu při ověřování, mohlo by ověřování selhat.

Registrované účty a vytvořené domény se ukládají do databáze, kterou je potřeba chránit před ztrátou – přijdeme-li o seznam doménových jmen a přihlašovacích účtu, nebudou fungovat a neprodloužíme certifikáty.

Pro ukládání dat o registraci je dispozici sqlite nebo připojení do PosgreSQL. Typ a umístění databáze se zadává v konfiguračním souboru.

Kromě umístění databáze je v konfiguračním souboru je možné zadat i další běžné konfigurační volby, např. na kterých adresách má acme-dns poslouchat. HTTP endpoint je možné provozovat na HTTP i HTTPS, a i tahle volba se zadává do konfiguračního souboru.

Pokud neprovozujeme službu pro celý svět, obvykle nechceme, aby se na na naši soukromou instanci acme-dns mohli registrovat náhodní kolemjdoucí uživatelé. Po vytvoření všech potřebných registrací je možné acme-dns zakázat registraci nových uživatelů – volba v konfiguračním souboru se jmenuje disable_registration.

Podobně při registraci nového uživatele je možné omezit seznam IP adres, ze kterých bude možné volat požadavek /update na konkrétní zástupnou zónu. Stačí při registraci poslat JSON slovník s klíčem allowfrom. Např.

MIF obecny

$ curl -XPOST curl -XPOST https://auth.acme-dns.io/register \
    -d '{ "allowfrom": [ "91.213.160.188/32", "2001:67c:68::76/64"] }'

Rok bezproblémového provozu

acme-dns v tomto okamžiku používáme necelý rok a velmi nám zjednodušil správu wildcard certifikátů. Pro uživatele, kteří se nechtějí obtěžovat s nastavováním tradičního DNS serveru, to může být docela dobrá volba a zvážil bych jeho nasazení.

Za největší výhodu acme-dns považuji to, že dělá pouze jednu věc a snaží se ji dělat dobře.