Ice Bear SoftZískání a obnova certifikátů od Let's Encrypt

Na této stránce najdete postup, jak získat a obnovovat automaticky certfikáty společnosti Let's Encrypt. Stránka obsahuje též stručný úvod do šifrování a je doplněna instrukcemi pro konfiguraci serveru Apache.

Návod je napsán pro uživatele operačního systému Linux a byl ověřen na distribuci Fedora počínaje verzí 23 a Raspbian GNU/Linux 8 (jessie). Autor doufá, že některé informace budou užitečné i pro uživatele jiných distribucí a operačních systémů.

1. Změny od minulé verze
2. Jemný úvod do kryptografie
  2.1. Co je asymetrická šifra?
  2.2. Co je hash?
  2.3. Co je digitální (elektronický) podpis?
  2.4. Prostředník
  2.5. Co obsahuje certifikát?
  2.6. Jak se vystavuje certifikát
  2.7. Ovlivňuje certifikát kvalitu šifrování a digitálního podpisu?
3. Nástroje
4. Použití ACME.sh
  4.1. Problém slepice a vejce
  4.2. Plánování
  4.3. Získání certifikátu
  4.4. Konfigurace Apache
  4.5. Obnova certifikátu jedné domény
  4.6. Obnova certifikátů více domén
  4.7. Závěrečné kroky
  4.8. Když věci nefungují
5. Co by ACME.sh měl dělat, ale nedělá
6. Použití v jiných operačních systémech
7. Download

1. Změny od minulé verze

Původní verze textu objasňovala získání a obnovu jediného certifikátu SAN. Tato verze upravuje metodiku tak, aby bylo možno získat a obnovit několik certifikátů, pokud jsou příslušné domény hostovány na jednom počítači.

 Začátek stránky 

2. Jemný úvod do kryptografie

Tato kapitola je podána velmi zjednodušeně a je určena čtenářům, kteří o kryptografii nic nevědí. Pokud máte s kryptografií nějaké zkušenosti, pokračujte ihned kapitolou Nástroje. Podrobnější informace o kryptografii najdete v angličtině na stránce Public key cryptography: What is it, how it work and how to use it in email and file encryption.

2.1. Co je asymetrická šifra?

Počítač nerozumí písmenům, zná jen číslice nulajedna, které jsou shlukovány do větších celků, které můžeme vyjádřit například dekadickými čísly. Písmenům pak můžeme přiřadit číselné hodnoty, aby s nimi počítač mohl nepřímo pracovat. V kódování ASCII máme přiřazení A=65, B=66, C=67, D=68, E=69 atd. Nyní předpokládejme, že máme posloupnost písmen, kterou chceme zašifrovat. Písmena jsou v počítači uložena jako čísla, proto je můžeme použít v matematické operaci. Pro jednoduchost bude tou operací přičtení konstantní hodnoty, například +1. Znakový řetězec ANO bude převeden na čísla, počítač s nimi provede matematickou operaci a výsledek bude znovu vyjádřen jako řetězec písmen. Přičtení +1 znamená následující písmeno v abecedě, takže zašifrovaný text bude BOP. Dešifrování pak provedeme stejnou operací, ale budeme přičítat hodnotu –1. Protože používáme stejnou operaci, ale jinou hodnotu (klíč), je tato šifra asymetrická.

Taková šifrovací metoda je však příliš jednoduchá a velmi snadno rozluštitelná, použili jsme ji pouze na vysvětlení principu. Skutečné asymetrické šifry používají složitější matematickou operaci a klíče jsou založeny na velkých prvočíslech. Existuje totiž způsob, jak vytvořit dvojici takových klíčů, ale ze znalosti jednoho klíče nelze vypočítat druhý klíč. Asymetrické šifře se proto říká též šifra s veřejným klíčem. Zprávu lze zašifrovat pomocí veřejného klíče, který bude běžně dostupný, ale dešifrovat ji může pouze ten, kdo má soukromý klíč. Pokud tedy chci, aby mi ostatní posílali zašifrované zprávy, stačí, když všichni budou moci získat můj veřejný klíč. Soukromý klíč je prostě soukromý a nikdo jiný ho za žádných okolností mít nesmí.

 Začátek stránky 

2.2. Co je hash?

Metody předávání zpráv jsou poruchové. Když přijmeme zprávu, nevíme, zda je celá, nevíme, zda nebyla poškozena nebo dokonce někým záměrně změněna. Není ekonomické, abychom stejnou zprávu přenášeli dvěma nezávislými způsoby a kontrolovali jejich shodu. Místo toho využijeme skutečnosti, že písmena jsou v počítači uložena jako čísla, takže z nich můžeme vypočítat kontrolní hodnotu, kterou použijeme pro ověření zprávy. Pro slovo ANO platí A=65, N=78, O=79, takže můžeme použít prostý součet, 65+78+79=222. Taková metoda nám však žádnou jistotu nedá, protože slovo ONA bude mít shodný kontrolní součet. V praxi se tedy používají jné metody, které zajistí, že k dané kontrolní hodnotě nelze vytvořit jinou smysluplnou zprávu se stejnou kontrolní hodnotou. Této kontrolní hodnotě se říká anglicky hash (výslovnost heš).

 Začátek stránky 

2.3. Co je digitální (elektronický) podpis?

Pomocí metod z předchozích kapitol umíme zprávu zašifrovat a umíme vypočítat její hash pro kontrolu integrity. Problém je v tom, že někdo může podstrčit falešnou zprávu, k níž vypočte správně hash. Při kontrole tedy nepoznáme, že je zpráva podvržena.

Pro vyřešení tohoto problému postoupíme o krok dále. Hash zašifrujeme privátním klíčem a přidáme ke zprávě. Příjemce si také vypočítá hash a kontrolní hodnotu dešifruje naším veřejným klíčem. Pokud se hodnoty shodují, je zpráva autentická. Takto vypočítaná hodnota se nazývá digitální (elektronický) podpis. K ověření podpisu tedy postačuje znalost veřejného klíče.

 Začátek stránky 

2.4. Prostředník

Centrální úložiště veřejných klíčů vypadá lákavě, ale jak si ukážeme později, neřeší zásadní problém. Jak tedy získáme veřejný klíč přítele, kterému chceme poslat šifrovanou zprávu? Prostě ho o veřejný klíč požádáme a on ho pošle. Pak máme jistotu, že si zprávu nikdo přečíst nemůže. Navíc je možno zprávu digitálně podepsat a veřejný klíč přiložit, takže přítel si může ověřit, že zpráva nebyla změněna.

Je to prosté, ale v praxi to nemůže fungovat. V digitálním světě nekomunikujeme přímo. Je to stejné, jako kdybychom někoho požádali, aby pro nás získal veřejný klíč přítele. Takový prostředník vygeneruje dvojici klíčů a jeden z nich předá jako veřejný klíč přítele. Pak sám toho přítele požádá o veřejný klíč. Pokud zpráva vždy prochází stejnou cestou, prostředník zprávu dešifruje, přečte a zašifruje skutečným veřejným klíčem. Obdobně může vygenerovat falešné klíče pro digitální podpis, aby mohl posílat podvržené zprávy. Existenci takového prostředníka nelze zjistit.

Situaci by pomohlo, kdybychom si veřejný klíč předali při osobním setkání, ale to není možné, zejména v případě, kdy jde o automatickou (strojovou) komunikaci. Řešením je tedy certifikát.

 Začátek stránky 

2.5. Co obsahuje certifikát?

Certifikát obsahuje veřejný klíč, identifikaci jeho majitele a dobu platnosti. Může obsahovat i další informace, ale to je pro náš jednoduchý výklad nepodstatné. Důležité je to, že certifikát je někým podepsán a obsahuje certifikát podepisující osoby. Můžeme si tedy ověřit pravost podpisu a víme, kdo certifikát podepsal. Je tím problém vyřešen? Není. Takový certifikát může vytvořit kdokoliv. Je tedy nutné, aby certifikát byl podepsán certifikační autoritou, u níž víme, že je vždy ověřována identita majitele.

Jedna certifikační autorita nemůže z kapacitních důvodů vystavit všechny certifikáty. Proto existuje řetěz certifikačních autorit. Certifikační autorita CA-0 ví, že certifikační autority CA-1 a CA-2 splňují všechny podmínky, takže jim vystaví certifikát s právem vystavovat certifikáty. Certifikační autorita CA-1 obdobně vystaví certifikáty pro certifikační autority CA-a, CA-b a CA-c. Když přítel pošle certifikát od certifikační autority CA-b a přiloží řetěz certifikátů certifikačních autorit, víme, že veřejný klíč v certifikátu je pravý.

 Začátek stránky 

2.6. Jak se vystavuje certifikát

Postup vystavení certifikátu zahrnuje několik kroků:

  1. Žadatel nejprve vygeneruje dvojici klíčů, soukromý a veřejný. K veřejnému klíči přidá svoji identifikaci a vše digitálně podepíše. Je tedy možno zkontrolovat, že žadatel vlastní odpovídající soukromý klíč. Soubor s těmito informacemi se nazývá žádost o podpis certifikátu (certificate signing request) a předává se certifikační autoritě.
  2. Certifikační autorita vhodným nezávislým způsobem ověří správnost údajů v žádosti.
  3. Certifikační autorita vystaví certifikát tím, že digitálně podepíše žádost.
 Začátek stránky 

2.7. Ovlivňuje certifikát kvalitu šifrování a digitálního podpisu?

Odpověď na otázku v nadpisu zní NE. Certifikát od důvěryhodné certifikační autority pouze zaručuje pravost veřejného klíče, nic méně, nic více. Certifikát vystavený důvěryhodnou certifikační autoritou se nazývá kvalifikovaný certifikát.

 Začátek stránky 

3. Nástroje

Doporučeným nástrojem pro práci s certifikáty je certbot. Program je psán v pythonu, který sice mám nainstalován, ale sám ho pro svoji práci nepoužívám a neumím. Bohužel certbot neoznámí dostatečně srozumitelně, co se mu nelíbí, takže se mi ho nepodařilo oživit.

Je nabízeno mnoho alternativních nástrojů. Z nabídky jsem si zvolil ten, který má minimální požadavky na další nástroje, a tím je ACME.sh napsaný kompletně v bashi. Tento nástroj fungoval bez problémů na první pokus, proto jsem další již nezkoušel.

 Začátek stránky 

4. Použití ACME.sh

Instalace ACME.sh je velmi jednoduchá, ale vlastní použití vyžaduje více kroků. Je nutno nakonfigurovat Apache tak, aby vše správně spolupracovalo. Důležité je i správné nastavení automatické obnovy certifikátu. Této problematice se věnuje následující text.

4.1. Problém slepice a vejce

Když prohlížeč navazuje šifrované spojení se serverem, nejprve musí získat z DNS jeho IP adresu. Pak si od serveru z té IP adresy vyžádá certifikát obsahující veřejný klíč. Pak už může zašifrovat požadavek na poslání konkrétní stránky z konkrétního serveru. To vše zní jednoduše až do chvíle, než si uvědomíme, že stejnou IP adresu může sdílet několik serverů s různými jmény. Jméno serveru, s nímž chceme komunikovat, sděluje prohlížeč až po nastavení šifrování, ale k šifrování je nutno znát jméno serveru předem, aby server věděl, který certifikát má poslat. Nastává tedy klasický problém slepice a vejce.

Existují dvě metody řešení, obě jsou závislé na nových rozšířeních šifrovacích protokolů. První metoda je Server Name Indication (SNI), což znamená, že jméno serveru je předáno hned při navazování spojení. Prohlížeč tedy dostane správný certifikát s veřejným klíčem. Výhodou je to, že každý virtuální server má vlastní certifikát. Nevýhodou je, že starší prohlížeče tuto metodu nepodporují. Druhou metodou je Subject Alternative Name (SubjectAltName, SAN). V tomto případě je certifikát pouze jeden, ale patří nejen hlavnímu serveru, ale i serverům s alternativními jmény. Je možno použít hvězdičku pro označení libovolného serveru v dané doméně, nebo seznam jmen. Ani tuto metodu nemusí podporovat staré prohlížeče. Pokud změníme seznam serverů, je nutno vystavit nový certifikát.

Internet Explorer 8 ve Windows XP nepodporuje SNI, ale podporuje SAN. Při první instalaci jsem tedy použil výhradně SAN. Později jsem potřeboval hostovat na stejném počítači dvě odlišné domény, a to se stejnou IP adresou. Použil jsem tedy SNI, přičemž každý z těch certifikátů používá SAN. Internet Explorer 11 ve Windows 7 tuto alternativu podporuje.

 Začátek stránky 

4.2. Plánování

Počáteční plánování je velmi důležité, protože nesprávným rozhodnutím získáte certifikát, který nebude možno automaticky obnovit. Špatným začátkem si tedy přivodíte řadu nepříjemností, které bude nutno později řešit. Doufám, že popis mých špatných rozhodnutí bude poučnější než suchý popis, jak vše nastavit.

Certifikát se vystavuje elektronicky bez osobního kontaktu. Certifikační autorita Let's Encrypt musí tedy použít jinou metodu ověření identity. Certifikát je určen pro server, jeho IP adresa je tedy nalezena v DNS. Certifikační autorita tedy skriptu acme.sh pošle náhodný, jednorázový kód, který si pak zpětně přečte s použitím informací, které najde v DNS. Certifikační autorita tedy ví, že skript má kontrolu nad serverem, pro nějž požaduje certifikát.

Skript nabízí několik metod ověření identity. Metodu založenou na DNS jsem odmítl. Ta požaduje vložení záznamu TXT do primárního jmenného serveru. Můj poskytovatel však nabízí pouze webové rozhraní, nenabízí API. Zbývají tedy následující možnosti:

  1. Standalone: Při této metodě není nutno mít funkční server. Přesněji řečeno, skript musí být sám schopen vytvořit vlastní server, který poslouchá buď na portu 80, nebo na portu 443. Pokud tedy již běží jiný webserver, je nutno jej dočasně vypnout.
  2. Webroot: Pro použití této metody je vyžadován funkční server a skript musí znát kořen adresářového stromu, z něhož jsou předávány statické stránky.
  3. Apache: Je požadován webserver Apache. Skript nainstaluje certifikát, upraví konfigurační soubory a restartuje server.

Skript si při prvním vystavení certifikátu vytvoří konfigurační soubor, do něhož mimo jiné zapíše, jaká metoda ověření identity byla použita. Stejnou metodu pak používá při obnově. Změna metody je možná, ale vyžaduje jisté úsilí. Je tedy lepší, pokud již od počátku přemýšlíte o automatické obnově a jejích případných úskalích.

Jeden z mých serverů není kriticky důležitý, proto jsem se rozhodl, že jej pro první vystavení certifikátu dočasně vypnu. Když se blížil konec platnosti certifikátu, skript chtěl při automatické obnově použít stejnou metodu, což nešlo, protože na obou portech poslouchal Apache. Místo automatické obnovy jsem tedy nechal ručně vystavit nový certifikát, ale tentokrát s metodou Webroot.

Metodu Apache jsem odmítl, neboť jsem plánoval nasazení několika virtuálních serverů s komplikovanou konfigurací, při níž v původních konfiguračních souborech téměř nezůstane na kameni kámen. Usoudil jsem, že si instalaci obnoveného certifikátu zařídím lépe, než by to zvládl skript, který neví nic o mých záměrech. Další text se proto bude věnovat pouze metodě Webroot.

 Začátek stránky 

4.3. Získání certifikátu

Nejsnadnějším způsobem je získání certifikátu v okamžiku, kdy máme funkční DNS, pro všechna jména lze získat IP adresu, ale Apache je stále ve výchozí konfiguraci. Pak máme jistotu, že adresář, který si ACME.sh vytvoří pro autorizaci, bude dostupný. Důležité je, že Let's Encrypt neověřuje IP adresu, ale všechna jména, přestože IP adresa je totožná. Ve výchozí konfiguraci Apache budou všechny požadavky obslouženy stejným serverem, což není na závadu. Naopak, ACME.sh vyžaduje, aby všechny virtuální servery měly pro účely ověření společný kořen dokumentů.

Později bude nutno zařídit, aby adresář, který ACME.sh používá k ověření, byl dostupný ze všech virtuálních serverů. Ten adresář je /.well-known/. Pokud chcete, aby nebyl na výchozím místě, vytvořte přesměrování hned příkazem v konfiguračním souboru:

Alias "/.well-known/" "/path/to/.well-known/"

Adresář /path/to musí existovat a musí mít právo pro zápis uživatelem, pod kterým běží Apache, tedy apache v systémech odvozených od distribuce Redhat, www-data v systémech odvozených z distribuce Debian. Pokud používáte SELinux, nezapomeňte nastavit správný kontext. A v konfiguraci Apache musíte povolit přístup příkazem:

Require all granted

Po nastavení je nutné restartovat Apache. Dále je vhodné do adresáře /.well-known/ vložit libovolný soubor a ověřit jeho dostupnost. Pak adresář smažeme.

Všechny virtuální servery mohou sdílet jeden adresář. Je tedy možno rezervovat jediný adresář /path/to a vložit stejnou direktivu Alias do všech sekcí VirtualHost.

Pokud již máte vlastní konfiguraci Apache, začněte s výše uvedeným přesměrováním a ověřte dostupnost ze všech virtuálních serverů. Pokud to nestačí, podívejte se do následující kapitoly a experimentujte. Dokud dostupnost ze všech virtuálních serverů nezajistíte, nepodaří se získat certifikát.

Pokud je adresář dostupný, můžeme přistoupit k získání certifikátu. Předpokládejme že chceme certifikát pro tyto domény SAN: my-domain.san, www.my-domain.san, preview.my-domain.san, subversion.my-domain.san. Certifikát vyžádáme jako root tímto příkazem:

acme.sh --issue -w $DOCUMENTROOT -d my-domain.san -d www.my-domain.san -d preview.my-domain.san -d subversion.my-domain.san

$DOCUMENTROOT je kořen stromu dokumentů, obvykle /var/www/html. Pokud jste provedli výše uvedené přesměrování, pak je tím kořenem /path/to.

Ověřování trvá nějakou dobu. Pokud proběhne úspěšně, v adresáři, kde se nachází ACME.sh, bude vytvořen adresář pojmenovaný po první doméně, tj. my-domain.san, v němž budou vloženy všechny potřebné soubory. Jejich instalaci si probereme později.

ACME.sh po úspěšném získání certifikátu zkusí zaregistrovat cron job pro obnovu certifikátu. Příkaz bude zapsán do crontab, který patří uživateli root. Současné distribuce však nemají cron, ale cronie, obvykle jen cronie-anacron. V tom případě příkaz crontab neexistuje a registrace selže, což nám nevadí. Pokud je však instalován cronie-noanacron (oba balíčky mohou být instalovány současně), registrace se podaří a my ten příkaz budeme muset smazat pomocí crontab -e.

Pokud hostujeme více domén, provedeme obdobný příkaz pro každou z nich. V podstatě je možno další doménu přidat později provedením odpovídajícího příkazu, pokud jsme již strukturu adresářů předem naplánovali. Příkaz pak může vypadat takto:

acme.sh --issue -w $DOCUMENTROOT -d other-domain.san -d www.other-domain.san -d bugzilla.other-domain.san
 Začátek stránky 

4.4. Konfigurace Apache

V předchozím kroku jsme vygenerovali soukromý klíč a získali certifikát. Dokumentace ACME.sh doporučuje, aby server nepoužíval přímo adresář, kam byly soubory uloženy, ale aby server používal kopie souborů. Abychom to měli jednodušší, překopírujeme celý adresář. Přesněji řečeno, zatím nebudeme kopírovat nic, ale budeme předpokládat, že nějakým dalším procesem kopie vznikne a vymyslíme umístění souborů. Můžeme tedy celý adresář zkopírovat např. do /etc/ssl/my-domain.san.

Jako startovací bod zvolíme konfiguraci dodávanou v distribuci. Potřebujeme vlastně jen malou úpravu, a tou je definice použitého klíče a certifikáty. Stačí tedy najít a upravit tři řádky:

SSLCertificateFile /etc/ssl/my-domain.san/my-domain.san.cer
SSLCertificateKeyFile /etc/ssl/my-domain.san/my-domain.san.key
SSLCertificateChainFile /etc/ssl/my-domain.san/fullchain.cer

Řekli jsme si, že všechny virtuální servery sdílejí klíč a certifikát. Museli bychom to tedy zapisovat znovu do konfigurace každého serveru, což je nepohodlné a navíc nepraktické, pokud bychom se v budoucnu rozhodli změnit umístění. Lze očekávat, že všechny servery budou mít stejné základní nastavení, bude se lišit jen kořen stromu dokumentů. Všechna společná nastavení tedy vložíme do samostatného souboru, který pak načteme příkazem:

Include conf.d/ssl.include

Celý konfigurační soubor virtuálního serveru tedy může vypadat takto:

<VirtualHost *:443>
ServerName preview.my-domain.san
DocumentRoot /var/www/preview

<Directory "/var/www/preview">
  Options Indexes IncludesNOEXEC
  AllowOverride FileInfo
  AuthUserFile /etc/httpd/auth/users
  AuthGroupFile /etc/httpd/auth/groups
  AuthType Basic
  AuthName "A realm for the virtual host"
  Require group allowed-user-group
</Directory>

ErrorLog logs/ssl_preview_error_log
TransferLog logs/ssl_preview_access_log
CustomLog logs/ssl_preview_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

Include conf.d/ssl.include
</VirtualHost>

Obvykle chceme mít stejný obsah na serveru se jménem s i bez www. V konfiguraci hlavního serveru tedy uvedeme:

ServerName www.my-domain.san
ServerAlias my-domain.san

Zde zatím není problém. Potíž je v tom, že na všechny virtuální servery s výjimkou hlavního chci přistupovat pouze protokolem https. V konfiguraci tedy bude přesměrování. Tím ale přijdeme o dostupnost adresáře /.well-known/. Přesměrování je tedy nutno udělat tak, aby zmíněný adresář byl stále dostupný na společném místě protokolem http. Protože nešifrované virtuální servery obsahují v podstatě jen přesměrování, mám všechny konfigurace včetně globálního nastavení ve společném souboru vhosts.conf, jehož část je uvedena níže:

# Basic important parameters
LimitRequestBody 134217728
SetEnv LC_CTYPE en_US.UTF-8

# Default expiration for all
ExpiresActive On
ExpiresDefault "access plus 1 hours"

# Extended status
ExtendedStatus on
<Location /server-status>
  SetHandler server-status
  Require all granted
  Allow from localhost
</Location>

# Virtual hosts over http
<VirtualHost *:80>
ServerName www.my-domain.san
ServerAlias my-domain.san
DocumentRoot /var/www/my-domain
Include conf.d/mg-redirections.include
</VirtualHost>

# Forced automatic redirection of all requests to https
# Access to /.well-known used by Let's Encrypt
<VirtualHost *:80>
ServerName preview.my-domain.san
DocumentRoot /var/www/html

<Directory "/var/www/html">
Options Indexes IncludesNOEXEC
AllowOverride FileInfo
Require all granted
</Directory>

RedirectMatch permanent "^(/[^\.].*)" "https://preview.my-domain.san$1"
RedirectMatch permanent "^(/?)$" "https://preview.my-domain.san$1"
Alias "/.well-known" "/var/www/my-domain/.well-known"
</VirtualHost>

# Similar lines for other virtual hosts deleted

<Directory "/var/www/my-domain/.well-known">
Options -Indexes
Require all granted
ExpiresDefault "access plus 1 minutes"
</Directory>

V nastavení adresáře /.well-known zatím změníme parametr na Options +Indexes, budeme to potřebovat při ladění.

 Začátek stránky 

4.5. Obnova certifikátu jedné domény

Obnovu certifikátu provedeme skriptem /etc/cron.daily/certrenew, který je zobrazen níže:

#!/bin/bash

# Parameters, paths, etc.
HOME=/root/.acme.sh
DOMAIN=my-domain.san
ACME=$HOME/acme.sh
ETC=/etc/ssl

# Day of month (zero padded) when the certificate info is displayed
DAY='02'

# Directory autolocation (may need changes)
U=/usr/bin
[ -x $U/echo ] && B=$U || B=/bin

# Web service unit (or init.d script)
SRV=$($B/systemctl list-units --type=service | $U/awk '/^\s*(apache2|httpd)\./ {print $1}')

# Do not touch below this point
C=/var/log/certrenew.log

# Certificate info
function certinfo {
  $U/openssl x509 -in $ETC/$DOMAIN/$DOMAIN.cer -text -noout | $B/egrep '^\s*(Not|Validity|Subject:)' >> $C
}

$B/echo '=============================================================================' >> $C
$B/date >> $C

if [ 0 = $($B/date +%w) ]
then
  $ACME --upgrade 2>&1 >/dev/null || $B/echo "ACME upgrade failed."
fi

if [ "$SRV" = "" ]
then
  $B/echo 'No web service unit found.' >> $C
  exit 2
fi

$B/echo 'Key renewal...' >> $C
$ACME --cron --home $HOME 2>&1 >/dev/null || {
  $B/echo 'Renewal of the certificates failed.' >> $C
  exit 1
}

$U/diff -qr $HOME/$DOMAIN/ $ETC/$DOMAIN/ >/dev/null 2>&1 && {
  $B/echo 'Certificates are OK' >> $C
  [ $($B/date +%d) = "$DAY" ] && {
    certinfo || $B/echo 'Error: cannot examine the certificate.' >>$C
  } || $B/true
} || {
  $B/echo 'Renewing certificates...' >> $C
  $U/rsync -Haq --delete $HOME/$DOMAIN $ETC && {
    certinfo
    $B/echo 'Restarting Apache...' >> $C
    $B/systemctl restart $SRV && $B/echo 'Restarted'>>$C || $B/echo 'Restart failed'>>$C
  } || $B/echo 'Cannot copy certificates to the target directory' >> $C
}

Pouze úvodní řádky vyžadují nastavení. Skript se jednou týdně (v neděli) aktualizuje. Potom požádá o obnovu certifikátů, je-li to nutné. Pokud v cílovém adresáři certifikát a další soubory chybí nebo jsou staré, skript nainstaluje nové a restartuje Apache. Svoji činnost zapisuje do logu. Při obnově certifikátu a druhý den v měsíci (viz proměnná DAY) vypíše do logu též informaci o aktuálním certifikátu. Z tohoto popisu je zřejmé, čím dokončíme konfiguraci Apache. Spustíme tento skript ručně. Certifikát je čerstvý, proto nebude obnovován. Cílový adresář však neexistuje, proto bude vytvořen a soubory do něj budou nainstalovány, následně bude restartován Apache. Nyní by přístup protokolem https měl fungovat a informace o certifikátu by měly vypadat podobně jako u jednoho z mých serverů (všimněte si položky Certificate Subject Alt Name). Pokud něco nefunguje, vždy vymažte nainstalované soubory (ponechte ty od ACME.sh), opravte konfiguraci a spusťte skript certrenew. Tak budete mít jistotu, že se při automatické obnově nedočkáte havárie.

Certificate details

Log obnovy certifikátu nechceme schovávat navždy, vytvoříme tedy soubor /etc/logrotate.d/certrenew:

# Certificate renewal by Lets'Encrypt
/var/log/certrenew.log {
    missingok
    nocompress
    nocreate
    notifempty
    rotate 5
    monthly
    copytruncate
}

Log je obvykle rotován až po pokusu o obnovu, proto jsme použili DAY='02'.

 Začátek stránky 

4.6. Obnova certifikátů více domén

Následující postup je platný jak pro certifikáty SNI, tak pro případ, že domény mají odlišné IP adresy. Každý z těch certifikátů může být typu SAN. Skript ACME.sh si automaticky ověří certifikáty ve všech podadresářích a obnoví vše, co je nutné obnovit. Skript certrenew je tedy o trochu komplikovanější než v předchozí kapitole:

#!/bin/bash

# Parameters, paths, etc.
HOME=/root/.acme.sh
DOMAIN=LetsEncrypt
CERTS=$HOME/$DOMAIN
ACME=$HOME/acme.sh
ETC=/etc/ssl

# Day of month (zero padded) when the certificate info is displayed
DAY='02'

# Directory autolocation (may need changes)
U=/usr/bin
[ -x $U/echo ] && B=$U || B=/bin

# Web service unit (or init.d script)
SRV=$($B/systemctl list-units --type=service | $U/awk '/^\s*(apache2|httpd)\./ {print $1}')

# Do not touch below this point
C=/var/log/certrenew.log

# Certificate info
function certinfo {
  for dir in $ETC/$DOMAIN/*
  do
    cert=${dir##*/}.cer
    $U/openssl x509 -in $dir/$cert -text -noout | $B/egrep '^\s*(Not|Validity|Subject:)' >> $C
  done
}

$B/echo '=============================================================================' >> $C
$B/date >> $C

if [ 0 = $($B/date +%w) ]
then
  $ACME --upgrade 2>&1 >/dev/null || $B/echo "ACME upgrade failed."
fi

if [ "$SRV" = "" ]
then
  $B/echo 'No web service unit found.' >> $C
  exit 2
fi

$B/echo 'Key renewal...' >> $C
$ACME --cron --home $HOME 2>&1 >/dev/null || {
  $B/echo 'Renewal of the certificates failed.' >> $C
  exit 1
}

$U/diff -qr $CERTS/ $ETC/$DOMAIN/ >/dev/null 2>&1 && {
  $B/echo 'Certificates are OK' >> $C
  [ $($B/date +%d) = "$DAY" ] && {
    certinfo || $B/echo 'Error: cannot examine the certificate.' >>$C
  } || $B/true
} || {
  $B/echo 'Renewing certificates...' >> $C
  $U/rsync -Haq --delete $CERTS $ETC/ && {
    certinfo
    $B/echo 'Restarting Apache...' >> $C
    $B/systemctl restart $SRV && $B/echo 'Restarted'>>$C || $B/echo 'Restart failed'>>$C
  } || $B/echo 'Cannot copy certificates to the target directory' >> $C
}
 Začátek stránky 

4.7. Závěrečné kroky

Nyní jsme na konci procedury. Musíme ještě ověřit dostupnost adresáře /.well-known/ protokolem http na všech virtuálních serverech. Pak vrátíme nastavení Options -Indexes. Pokud má být některý virtuální server dostupný výhradně protokolem https, přidáme do jeho konfigurace:

Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains"
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff

Nevkládejte tyto řádky do konfigurace serveru, který musí být dostupný i nešifrovaným spojením. S těmito příkazy však získáte hodnocení A+ na https://www.ssllabs.com/ssltest/index.html.

Nezapomeňte po změně konfigurace restartovat Apache.

 Začátek stránky 

4.8. Když věci nefungují

Může se stát, že přes veškerou snahu obnova certifikátu selže a důvod nemusí být zřejmý. V instalačním adresáři ACME.sh najdeme soubor account.conf, v němž definujeme proměnnou LOG a odkomentujeme DEBUG=1. Při běhu pak získáme informace, které pomohou při diagnostice.

 Začátek stránky 

5. Co by ACME.sh měl dělat, ale nedělá

Řekli jsme si, že z pouhé znalosti veřejného klíče nelze určit soukromý klíč. Není to úplná pravda. Přímý výpočet skutečně možný není, ale existuje brutální síla, metoda pokusu a omylu. Těch nutných omylů je veliké množství, takže taková úloha je časově značně náročná. Jde tedy o to, aby platnost klíče skončila dostatečně brzy. Certifikát od Let's Encrypt má tedy platnost pouze tři měsíce. Při obnově certifikátu však ACME.sh vytvoří nový požadavek o certifikát ke stávajícím klíčům. ACME.sh by tedy měl alespoň jednou za rok vygenerovat nové klíče.

 Začátek stránky 

6. Použití v jiných operačních systémech

Přístup zvolený ve skriptu ACME.sh je nenáročný na existenci dalších nástrojů. Postup popsaný na této straně vyžaduje pouze nástroje, které existují i v jiných operačních systémech včetně OS/2 (eComStation). Program logrotate je možno nahradit tím, že jméno souboru pro log bude obsahovat rok a měsíc a staré soubory budou odstraňovány jiným mechanismem.

 Začátek stránky 

7. Download

Download certrenew.tar.gz (4 KiB)

 Začátek stránky