Hlavní navigace

Certifikáty Let's Encrypt se skriptem Dehydrated

Dan Ohnesorg

Pokud nasazujete certifikáty od autority Let's Encrypt, můžete si vybrat z celé řady klientů, kteří implementují ACME protokol a tedy dokáží zajistit vystavení certifikátu. Já jsem si vybral Dehydrated.

Na Root.cz se již psalo o populárním klientu acme.sh, ale není to jediná alternativa a já jsem si oblíbil jinou. Jmenuje se Dehydrated. Je v zásadě skoro stejný, ale podle mě je přehlednější. Má na jednom místě seznam všech spravovaných certifikátů, co řádek to jeden certifikát, na řádku může být libovolný počet sekundárních jmen do certifikátu.

$ cat /etc/dehydrated/domains.txt
root.cz www.root.cz f.root.cz blog.root.cz

Instalujeme

Instalace je klasická a jednoduchá, v Debian backports jsou k dispozici balíčky, ale protože projekt se velmi rychle vyvíjí, preferuji naklonování git repozitáře:

$ git clone  https://github.com/lukas2511/dehydrated

Samotný skript dehydrated nakopíruji do /usr/local/bin, ukázkové konfigurační soubory z adresáře docs/examples/ do /etc/dehydrated. Jedná se o jednoduchý shellový skript, který potřebuje jen curl a openssl. Ukázkový konfigurační soubor je komentovaný, pro běžné užití je potřeba nastavit čtyři parametry:

BASEDIR=/etc/dehydrated
WELLKNOWN="/var/www/dehydrated/.well-known/acme-challenge/"
CONTACT_EMAIL=*@*.cz
HOOK=/etc/dehydrated/hook.sh

Význam je asi jasný, první udává cestu, ve které se hledá zbytek konfigurace, druhý adresář, kam se ukládají ověřovací hashe, třetí parametr email, na který budete dostávat případná upozornění na blížící se expiraci. Poslední parametr označuje soubor, který obsahuje funkce volané v jednotlivých momentech vystavení certifikátu.

Prvním krokem po instalaci je vytvoření účtu a souhlas s licencí. Zavoláme

$ /usr/local/bin/dehydrated --register --accept-terms

a je hotovo. Účet je potřeba pro případnou revokaci certifikátu.

Vystavujeme

Od této chvíle je možné vystavovat certifikáty. K vystavení certifikátu je potřeba ověřit, že můžete manipulovat s doménou, pro kterou žádáte o certifikát, Dehydrated podporuje dvě metody ověřování. První, kterou Let's Encrypt implementoval, přes vystavení hashe v dohodnuté cestě na webovém serveru. O něco mladší cesta vede přes založení DNS jména. Já používám jen tu HTTP verzi, DNS je relativně pomalé, i při používání notify nějakou dobu trvá, než sekundární nameservery potřebné TXT záznamy propagují.

Nastavení HTTP je ideální udělat pro celý server najednou (pokud tedy spravujete všechny virtuály), stačí do konfigurace Apache či jiného www serveru přidat vzorový konfigurační soubor:

Alias /.well-known/ /var/www/dehydrated/.well-known/

<Directory /var/www/dehydrated>
        Options None
        AllowOverride None

        # Apache 2.x
        <IfModule !mod_authz_core.c>
                Order allow,deny
                Allow from all
        </IfModule>

        # Apache 2.4
        <IfModule mod_authz_core.c>
                Require all granted
        </IfModule>
</Directory>

Pro zajímavost – v čem je moje konfigurace jiná. Protože většinou nemáme servery veřejně dostupné přímo z internetu, je před nimi load balancer. Ten je nastaven tak, že cestu .well-known posílá na zvláštní backend, kde se spravují certifikáty. Druhou možností by bylo certifikační výzvy ukládat na sdílené úložiště, aby odpovědět mohly všechny backendy, ale mít na to jeden vyhrazený virtuál je praktičtější. Na něm je certifikát připraven a potom přes hook skript poslán na loadbalancery a nasazen.

Vystavení samo o sobě může být problém, pokud přesměrováváte všechny požadavky na SSL spojení. Let's Encrypt by sice stáhl certifikační hash i přes HTTPS, ale vyžaduje platný SSL certifikát a ten, pokud se jedná o nový certifikát, asi nemáte (nebo dokonce potřebujete vystavit certifikát místo expirovaného). Přesměrování na HTTPS nastavuji takto:

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
RewriteRule ^(.*) https://%{HTTP_HOST}/$1 [R=301,L]

Tedy přesměruji všechny požadavky, kromě toho stažení certifikačního hashe.

Poslední úprava je nastavení práv k certifikátům. Výchozí stav u nově vytvořeného certifikátu je, že jediný kdo jej může číst je jeho vlastník. To je nepraktické při použití certifikátu pro Postfix, Cyrus nebo Jabber server, obecně pro programy, které načítají certifikát pod neprivilegovaným uživatelem (u Apache to nevadí, protože certifikát načte ještě když běží s rootovskými právy). To lze řešit speciální skupinou, jejímiž členy jsou neprivilegované účty aplikací a v rámci hooku nastavím práva čtení pro skupinu a skupinu certifikátu změním na tuto sdílenou skupinu.

Nasazujeme

Pro úpravy práv a nasazení certifikátu se používají funkce definované v skriptu hook.sh (resp. v takovém, který je v konfiguraci uveden jako parametr proměnné HOOK), většinou budete potřebovat modifikovat jen funkci deploy_cert, která je zavolána, až když je certifikát vystaven. Např. můžete potřebovat mít certifikát spolu s privátním klíčem v jednom souboru, to zajistíte takto:

cat $KEYFILE $FULLCHAINFILE > /etc/dehydrated/certs/${DOMAIN}/fullcert.pem

Po dokončení konfigurace si můžeme vystavit certifikáty uvedené v souboru  domains.txt

$ dehydrated -c -f /etc/dehydrated/config

Tedy spuštěním skriptu a uvedením cesty ke konfiguračnímu souboru. Vystavené certifikáty naleznete ve výchozím nastavení v podadresáři certs, v našem případě v /etc/dehydrated/certs, kde jsou pro každý řádek z domains.txt  vytvořeny adresáře a v adresáři jsou symlinky:

  • privkey.pem – privátní klíč
  • cert.pem – samotný certifikát
  • chain.pem – mezilehlé certifikáty
  • fullchain.pem – mezilehlé certifikáty a samotný certifikát v jednom souboru

Odkazují vždy na aktuálně platný certifikát. Tato jména je tedy možné uvést do konfiguračních souborů jednotlivých aplikací.

Posledním krokem instalace je nasazení skriptu do cronu, kdy se Dehydrated spouští s přidáním parametru -c aby věděl, že běží z cronu.

Hlídáme

Samotné vystavení certifikátu je snadné, ale celé nasazení v komplexní infrastruktuře je už složitější a půlroční zkušenosti říkají, že je i na úkor spolehlivosti. Klasická metoda s wildcard certifikáty s platností dva roky nevyžadovala žádné zvláštní kontroly, kromě testu po nasazení certifkátu. Jejich nahrazení zhruba 200 certifikáty, které se samy obnovují, což sem tam nedopadne, vyžaduje daleko více testů na to, zda všechno probíhá hladce. Např. zda se aplikace po nasazení nových certifikátů skutečně reloadly a reálně je používají.

Další problém nastane, pokud jedno z SNI jmen přestane směřovat na server. Potom totiž není možné certifikát prodloužit, resp. je nutné před prodloužením zrušené jméno odstranit z konfigurace.

Aby se nám nestalo, že zůstaneme bez certifikátů, testujeme jejich platnost přes check_http v Nagiosu, test může vypadat např. takto:

check_http -H www.root.cz --sni -C 10,2

Tento konkrétní test ohlásí varování při platnosti kratší než 10 dnů a kritický stav při platnosti kratší než 2 dny. Opět to, že přibude do Nagiosu 200 testů navíc, není zadarmo a rozhodně doporučuji definovat závislosti služeb, jinak při selhání serveru nastane záplava notifikací.

Na druhou stranu bezpečnost nikdy nebyla zadarmo a ochrana soukromí uživatelů za trochu nepohodlí stojí.

Našli jste v článku chybu?
18. 3. 2017 17:15
Overovanie platnosti (neregistrovaný)

V článku sa nespomenula pomerne zaujímavá vlastnosť Dehydrated (inak pôvodne sa to volalo letsencrypt.sh). A to parameter cron. V praxi Dehydrated overuje či je nutné vyžiadať nový certifikát, alebo je stále v platnosti pôvodný. Takže je možne pridať denný cron job na kontrolu platnosti a prípadnú aktualizáciu certifikátov, bez toho aby ste nejakým spôsobom zaťažovali letsencrypt autoritu. Spúštať kontrolu denne, vám zvýši šancu, že certifikát neexpiruje v prípade ojedinelej chyby na strane lets…

16. 3. 2017 9:12

Certbot je přímo referenční klient od Let's Encrypt. Je to to, co se dříve jmenovalo letsencrypt.