Let’s Encrypt bez roota na GitLabu

Autoritu Let’s Encrypt asi netřeba představovat. Jedná se o projekt veřejné certifikační autority, která zdarma vydává SSL certifikáty pro použití na webu a internetu obecně.

Autorita sází na automatické ověřování a automatické obnovování certifikátů. Certifikáty mají platnost pouze 3 měsíce, tedy nějaké ruční ověřování a ruční instalace není příliš pohodlná. K ověření a vystavení certifikátu je nutné použít nějakého ACME klienta. Těch je víc, ale nejčastější a doporučovaný je certbot vyvíjený pod záštitou EFF. Navíc je k disposici jako balíček v repositáři většiny distribucí.

Proč root?

No a tady pro mě přišel největší šok. Certbot by default potřebuje ke své činnosti práva roota. Už to odstranili, ale ještě před rokem bylo na stránkách EFF doporučení ve smyslu: „nebojte se roota, certbot je open source a zkontrolovalo jej tisíc očí“. Tohle je asi nejhorší věta, kterou může vývojář bezpečnostního software vyslovit. Nejde o to, že by někdo úmyslně do certbota přidal zadní vrátka, ale jde o to, že všichni děláme chyby a vliv těchto chyb by měl být minimalizován. To znamená používat v OS nejmenší možná práva, která ještě stačí pro výkon dané činnosti.

No nic, tohle prohlášení už na webu EFF k nalezení není a je to jen dobře. Jenže oficiální certbot klient roota stále automaticky používá. A to je špatně. Naštěstí se tomu lze v některých případech vyhnout.

LE v GitLabu

Já jsem potřeboval dostat SSL CRT do soukromého GitLabu a v tomto prostředí pochopitelně nechci povolit přístup k datům většímu množství procesů, než je nezbytně nutné.

Takže jdeme na to. Návod je platný pro aktuální Debian Testing (což je aktuálně zmražený budoucí Stretch). Některé příkazy se mohou pro ostatní operační systémy lišit.

Budeme potřebovat uživatele, pod kterým má certbot běžet:

useradd -d /var/lib/letsencrypt -r -s /usr/bin/nologin certbot

Dále vytoříme adresáře a přiřadíme jim vlastníka:

mkdir /var/lib/letsencrypt
chown certbot /var/lib/letsencrypt

mkdir /var/log/letsencrypt
chown certbot /var/log/letsencrypt

mkdir /etc/letsencrypt
chown certbot /etc/letsencrypt

A nainstalujeme klienta:

apt install certbot

Balíček v aktuálním Debian Stretch si nainstaluje systemd službu a timer (certbot.service a certbot.timer). Je třeba nastavit User=certbot:

systemctl edit --full certbot

Nastavení můžeme zkontrolovat například pomocí:

systemctl show certbot | grep User

Tímto máme prostředí pro běh programu certbot částečně připravené. Je na čase se pustit do konfigurace gitlabu a nastavit .well-known adresář v gitlabím nginxu.

cd /etc/gitlab
edit gitlab.rb

A nastavíme:

nginx['custom_gitlab_server_config'] = "location ^~ /.well-known { root /var/lib/letsencrypt; }"

A necháme to probublat nastavením GitLabu:

gitlab-ctl reconfigure

Tím je Gitlab (opět částečně) připraven.

Nastavíme certbot klienta:

cd /etc/letsencrypt/
edit cli.ini
chown certbot cli.ini

Soubor cli.ini bude obsahovat:

email = muj@email
domains = moje.domena.cz
text = True
non-interactive = True
staple-ocsp = True
authenticator = webroot
webroot-path = /var/lib/letsencrypt

Kde upravíme nastavení email a domains. Po uložení nastavíme vlastníka na uživatele certbot.

Tím by mělo být vše připraveno na vygenerování certifikátu. Přepneme se do uživatele certbot a spustíme příkaz pro vygenerování certu:

sudo -u certbot bash
certbot certonly

Klient vypíše informace o průběhu a pokud vše proběhne OK, tak by výpis měl obsahovat cestu k novému crt. Tuto cestu budeme potřebovat pro další konfiguraci GitLabu.

V soubor /etc/gitlab/gitlab.rb nastavíme cestu k crt a klíči:

nginx['ssl_certificate'] = "/etc/letsencrypt/live/moje.domena.cz/fullchain.pem"
nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/moje.domena.cz/privkey.pem"

A necháme přenastavit gitlab:

gitlab-ctl reconfigure

Tím by mělo být hotovo.

Ještě zbývá zakomentovat řádek domains v cli.ini, protože renew klient volaný z timeru to nemá rád. Neptejte se mě proč.

Takže zkusíme ještě ručně spustit službu volanou z timeru a prozkoumáme log:

systemctl start certbot
systemctl status certbot
less /var/log/letsencrypt/letsencrypt.log

Tím je hotovo.

Nejsem nadšený

Předpokládám, že z tónu tohoto článku je jasné, že z oficiálního ACME klienta a to ještě pod záštitou takové organizace, jakou je EFF, nejsem vůbec nadšený. Nutnost používat roota a ještě to okecávat podle mě nepatří do roku 2017.

Dalším problémem jsou chybové hlášky. Pokud spustíte timer (který volá jen příkaz certbot renew), můžete se dočkat hlášky:

Error: Currently, the renew verb is only capable of renewing
all installed certificates that are due to be renewed;
individual domains cannot be specified with this action.
If you would like to renew specific certificates, use the certonly
command. The renew verb may provide other options for selecting
certificates to renew in the future.

Přitom jsme na příkazovou řádku žádné další parametry nezadali. Problém je v tom, že renew se nelíbí řádek domains v souboru cli.ini. Jestli to někdo z výše uvedené hlášky dokáže vyvěštit, tak si ke mě může přijít pro diplom.

Ne, fakt z toho nejsem nadšený. StartSSL skončila, žádná jiná autorita se do free certifikátů nehrne a Let’s Encrypt je tak prakticky jedinou možností. Implementace DANE v prohlížečích je na bodu mrazu.

Zdroje

Tenhle článek berte spíš jako ilustrativní návod, jakou cestou se vydat. Během nastavení se patrně budete potýkat s množstvím nesmyslných chybových hlášek. Já jsem čerpal info z těchto zdrojů:

Příspěvek byl publikován v rubrice Debian, GIT, Linux, SSL, systemd. Můžete si uložit jeho odkaz mezi své oblíbené záložky.

1 komentář u Let’s Encrypt bez roota na GitLabu

  1. Heron napsal:

    Jenom poznámku: Článek neřeší reload služby po renew certifikátu. Toto si každý admin musí vyřešit podle svého nastavení, možností je víc:

    * reload při logrotate
    * restart při update (Gitlab vydává updaty velmi často, takže se i často restartuje)
    * restart při záloze apod

    Pokud někdo potřebuje automatický restart, lze se inspirovat článkem:
    https://tim.siosm.fr/blog/2016/07/10/lets-encrypt-safely/
    kde se reloadovací skript řídí podle existence jistého souboru.

    Do článku jsem to nezahrnoval, protože je to jednak mimo samotný proces vydání crt, a také existuje víc možností, jak reload řešit.

Komentáře nejsou povoleny.