Cert Warden - narzędzie do centralnego zarządzania certyfikatami ACME (Let's Encrypt, ZeroSSL itd.)
Współcześnie dostęp do serwisów internetowych z wykorzystaniem bezpiecznego połączenia HTTPS jest standardem. Znakomita większość popularnych usług wymusza szyfrowanie, a choćby jest dostępna wyłącznie poprzez protokół HTTPS. Szerokie rozpowszechnienie HTTPS sprawiło, iż przeglądarki internetowe przestały specjalnie „wyróżniać” bezpieczne połączenia – nie pojawia się już znana „zielona kłódka”, a protokół nie jest w kolorze zielonym (o ile w ogóle jest widoczny). Mniej techniczni użytkownicy z pewnością nie zwracają choćby uwagi na fakt użycia szyfrowanej komunikacji, a o ewentualnych problemach dowiadują się, gdy przeglądarka blokuje dostęp do danej domeny.
Oczywiście zastosowanie szyfrowanej komunikacji ma ogromne znaczenie. Przede wszystkim zdecydowanie ogranicza możliwość „odczytu” i modyfikacji transmitowanych danych przez nieupoważnione osoby, co jest realnym zagrożeniem szczególnie w przypadku sieci lokalnych (również Wi-Fi). Z kolei w aspektach technicznych istotne jest także możliwe zwiększenie wydajności komunikacji, ponieważ nowoczesny protokół HTTP/3 wymaga stosowania szyfrowania.
Certyfikaty SSL
Konfiguracja serwera HTTP do obsługi szyfrowanych połączeń przy założeniu minimalnego nakładu pracy ogranicza się w zasadzie do podania ścieżek do certyfikatu i powiązanego z nim klucza – niektóre serwery wymagają konkatenacji obu tych elementów w jednym pliku, ale nie zmienia to założeń. Tak prosta konfiguracja niestety wymaga dopracowania, chociażby pod kątem HSTS, obsługi TLS 1.3 czy też dhparam. Administratorzy mogą skorzystać z generatora https://configurator.tlsref.org/ (wcześniej https://ssl-config.mozilla.org/), który po wskazaniu używanego przez nas serwera przedstawia dostosowaną do obecnych zaleceń konfigurację – najlepiej stosować konfigurację Modern (z TLS 1.3), chyba iż ze względów kompatybilności z pewnymi starszymi rozwiązaniami wymagane jest użycie „mniej bezpiecznych” ustawień.
Certyfikat SSL dla naszej domeny możemy uzyskać poprzez różne metody weryfikacji jej własności. Dla podstawowych certyfikatów (które są absolutnie w pełni wystarczające) najczęściej sprowadza się to do dodania konkretnego rekordu TXT w systemie DNS bądź też weryfikacji możliwości pobrania specjalnego pliku tekstowego przez serwer weryfikujący. Dla certyfikatów EV, które są często wykorzystywane przez instytucje finansowe, przeprowadza się również background check danej organizacji. Przeglądarki co prawda nie zaznaczają, iż domena korzysta z certyfikatu EV, ale różnicę widać jednoznacznie w szczegółach danego certyfikatu. Oba rodzaje certyfikatów zapewniają ten sam poziom bezpieczeństwa, natomiast EV w pełnym stopniu potwierdza, iż korzystamy z serwisu należącego do danego podmiotu.
Właściwości certyfikatu SSL dla avlab.pl
Właściwości certyfikatu SSL dla domeny banku – widoczna nazwa organizacji
Z podstawowej wiedzy teoretycznej dotyczącej certyfikatów warto też wspomnieć, iż certyfikat może obejmować pojedynczą domenę (avlab.pl), ale możliwe jest objęcie również subdomen (*.avlab.pl). Taki certyfikat określa się jako wildcard i staje się bardzo przydatny, jeżeli posiadamy kilka subdomen kierujących na ten sam adres (serwer, load balancer itp.).
Certyfikat SSL możemy nabyć drogą zwyczajnego zakupu i wtedy będzie on istotny najczęściej przez miesiąc – w tym wypadku kupujemy de facto subskrypcję na (automatyczne) odnawianie certyfikatu przez różne okresy czasu, np. do roku. Przykładami dostawców takiej usługi (urzędy certyfikacji) są m.in. DigiCert, GlobalSign, Sectigo czy polski Certum.
Let's Encrypt
Nie jest wymagane poniesienie dodatkowych kosztów, ponieważ można skorzystać z równie profesjonalnych, ale bezpłatnych alternatyw. Przykładem jest m.in. usługa Cloudflare, która dodatkowo może zapewniać podstawowy WAF dla naszego serwisu. Jednak najbardziej znanym rozwiązaniem (a przy okazji największym urzędem certyfikacji) jest Let’s Encrypt – powiązane narzędzie Certbot może całkowicie automatycznie i bez ingerencji administratora odnawiać bezpłatny certyfikat SSL. Na ten moment jedyną alternatywą pozostaje ZeroSSL, gdzie certyfikaty możemy generować w panelu, ale też przez znane zaawansowane narzędzie acme.sh.
Właśnie dzięki możliwości szerokiej automatyzacji Let’s Encrypt stał się wręcz kluczową usługą, a z certyfikatów wystawianych przez ten CA korzystają m.in. Squarespace, WordPress, Wix czy choćby Oracle. Również mniejsze serwisy często używają Let’s Encrypt, bo większość paneli hostingowych zapewnia możliwość dodania takiego certyfikatu z ich poziomu. Nie bez znaczenia pozostaje rosnąca skala zastosowania rozwiązań typu Kubernetes, gdzie Cert-Manager powiązany z Ingress (serwis pełniący rolę reverse proxy do aplikacji uruchomionych w podach) obsługuje głównie Let’s Encrypt – więc często to najszybszy sposób dodania SSL, a praktyka korzystania z płatnych alternatyw raczej nie jest spotykana.
Problemy związane z certyfikatami
Mimo tak wielu udogodnień zarządzanie certyfikatami SSL w większych środowiskach jest problematyczne. Certbot znakomicie automatyzuje odnawianie i działa niemal bez konieczności podejmowania manualnych czynności. Jednak weryfikacja oparta na testowaniu możliwości odczytu pliku (w znanej każdemu administratorowi ścieżce .well-known/acme-challenge) przez zewnętrzny serwer wymaga, aby nasza usługa była publicznie dostępna – co rzecz jasna nie jest możliwe w każdym przypadku. Oczywiście dla przykładu domena avlab.pl będzie dostępna z zewnątrz, ale dev.avlab.pl raczej nie – pewnym obejściem będzie zastosowanie certyfikatu wildard dla *.avlab.pl, ale w przyszłości może pojawić się konieczność dodania certyfikatu dla api.dev.avlab.pl, co już nie będzie objęte wildcardem. Możemy też korzystać z lokalnej domeny avlab.local i wtedy wolelibyśmy uniknąć manualnego generowania certyfikatów self-signed.
Wszystkie opisane czynności można zautomatyzować oraz skonfigurować alerty o zbliżającym się czasie, w którym dany certyfikat wygasa, ale niedługo pojawi się stan nieuporządkowania. Zdecydowanie lepszym podejściem będzie przygotowanie scentralizowanego miejsca, w którym przechowywane byłyby wszystkie nasze certyfikaty i klucze. W miarę zbliżania się dnia wygaśnięcia danego certyfikatu administrator mógłby go wygodnie odnowić w jednym miejscu, a wszystkie serwery z zainstalowanym certyfikatem pobrałyby nową wersję i wykonałyby reload usługi korzystającej z tego certyfikatu.
Cert Warden
Nie trzeba w tym celu opracowywać dedykowanego rozwiązania, bo od blisko czterech lat istnieje sprawdzone narzędzie Cert Warden. Instalacja ogranicza się do uruchomienia kontenera (wszystkie parametry są zapisane w niewielkim pliku docker-compose.yml), a sama obsługa jest intuicyjna i oprócz przedstawienia kilku „konceptów” związanych z generowaniem certyfikatów nie wymaga obszernych instrukcji. Sam panel zarządzania jest przystępny i raczej zaprojektowany bez nadmiarowych i rzadko potrzebnych opcji.
Założenia konfiguracji serwerów
Z uwagi na prostotę obsługi dla publicznych domen, gdzie w praktyce wystarczy skonfigurować dostęp do naszego dostawcy DNS, zaprezentuję konfigurację wszystkich usług używanych w procesie generowania certyfikatów SSL – DNS, serwer ACME i właśnie Cert Warden. Z wyjątkiem zastosowanego serwera ACME może to być konfiguracja odpowiednia dla środowisk produkcyjnych. Ważne jest zresztą zrozumienie koncepcji stojącej za wystawianiem certyfikatów zamiast prób odwzorowywania konfiguracji, która będzie się różnić między konkretnymi rozwiązaniami.
Wstępnym wymaganiem do przeprowadzania pełnej konfiguracji jest zainstalowane oprogramowanie Docker. Użycie konteneryzacji degraduje znaczenie systemu operacyjnego i co do zasady można wykorzystać dowolną dystrybucję Linux. Dla celów przygotowania poradnika wszystkie podane polecenia wykonuję w systemie Ubuntu Server.
Technitium DNS
Pierwszym krokiem będzie uruchomienie kontenera z Technitium DNS, o którym szerszej pisaliśmy w tym tekście. Na potrzeby zastosowania do generowania certyfikatów nie ma konieczności tak kompleksowej konfiguracji, a jedynie wprowadzenia podstawowych modyfikacji. Tworzymy plik docker-compose.yml o poniższej zawartości i uruchamiany kontener dzięki polecenia docker compose up -d.
Serwer ma przypisany adres IP 192.168.1.45. Uruchomiliśmy usługę DNS, więc z pełnym przekonaniem można ustawić ten adres „na stałe” jako adres serwera DNS. W tym miejscu będzie jedyna różnica pomiędzy systemem Ubuntu, a np. RHEL, gdzie wystarczy użyć polecenia nmtui i w sposób niemal graficzny zmienić adres serwera DNS.
W przeglądarce otwieramy adres http://192.168.1.45:5380/. Ustawiamy hasła dla użytkownika admin i przechodzimy do karty Settings. W opcji DNS Server Local End Points możemy ograniczyć zakres do 192.168.1.45:53. Zapisujemy zmiany znajdującym się na samym dole przyciskiem Save Settings, po czym przechodzimy do Proxy & Forwardes i ustawiamy wybrany zewnętrzny serwer DNS do rozwiązywania nazw – w naszym przypadku będzie to Cloudflare (DNS-over-HTTPS).
Na koniec w karcie Zones tworzymy lokalną strefę, np. avlab.local. Warto od razu wspomnieć o istnieniu protokołu TSIG, który umożliwia (zdalne) dodawanie/modyfikację rekordów DNS bez konieczności bezpośrednich zmian w konfiguracji serwera. W tym przypadku akurat nie ma potrzeby korzystania z TSIG (wykorzystamy API), natomiast sam temat jest interesujący i polecam zapoznać się ze szczegółami. Technitium w pełni obsługuje TSIG.
W strefie możemy dodać rekordy, np. acme i certs. Pod acme.avlab.local wystawimy serwer ACME, a Cert Warden będzie korzystał z domeny certs.avlab.local.
Dodane rekordy w Technitium DNS
Pebble
Jako serwer ACME użyjemy Pebble, który stanowi minimalistyczną wersję zaawansowanego rozwiązania Boulder. Oba serwery zostały opracowane przez zespół Let’s Encrypt. Pebble nie nadaje się do zastosowań produkcyjnych, ponieważ generuje certyfikaty jedynie na okres pięciu dni, a także nie zaimplementowano (zapewne celowo) persystencji danych – po restarcie aplikacji zostaną one utracone. Natomiast jest w pełni wystarczający do różnych scenariuszy testowych.
Dla domen publicznych uruchamianie własnego serwera DNS i ACME jest krokiem całkowicie zbędnym. Przypominam, iż naszym celem jest automatyzacja tworzenia certyfikatów dla domeny avlab.local i ewentualnie innych domen wewnętrznych.
Pebble jest napisany w języku Go, co oznacza, iż potrzebujemy pobrać i wypakować archiwum z kompilatorem. Link do pobrania najnowszej wersji znajdziemy na stronie https://go.dev/doc/install. Wykonujemy kolejno polecenia:
Oczywiście można użyć ścieżki w katalogu domowym – tutaj zdecydowałem się jednak na instalację globalną. Dodajemy jeszcze poniższe wpisy do pliku .profile.
Wykonujemy source .profile bądź ponownie nawiązujemy połączenie SSH, aby zmiany zostały załadowane. Teraz klonujemy repozytorium z Pebble i wykonujemy polecenia zgodnie z instrukcją zawartą w README.md.
Pebble domyślnie używa swojego certyfikatu SSL. Problem w tym, iż nie będzie on z wiadomych powodów „zaufany” przez jakiegokolwiek klienta, co uniemożliwi integrację przede wszystkim z Cert Warden. Sugeruję więc wygenerować własną parę certyfikat/klucz i w pliku test/config/pebble-config.json wskazać ścieżkę do tych plików.
Zawartość pliku pebble.crt zapisujemy w tymczasowym miejscu – użyjemy jej, aby „zaufać” ten certyfikat w customowym obrazie z Cert Warden.
Ustawienie ścieżek do certyfikatu i klucza w konfiguracji Pebble
Pebble uruchamiamy np. w screen. Możemy dodać serwis systemd, chociaż dla tak prostego zastosowania może nie być to szczególnie przydatne. Teraz po wejściu na https://acme.avlab.local:14000/dir powinniśmy zobaczyć analogiczną zawartość do tej widocznej na zrzucie ekranu.
Uruchomiony serwer ACME
Przygotowanie obrazu z Cert Warden
Kluczowe usługi zostały już przygotowane, więc przystępujemy do uruchomienia Cert Warden. Wspomniany wyżej plik docker-compose.yml nie jest skomplikowany, natomiast dodamy jeszcze kontener z nginx, który będzie pełnił rolę reverse proxy – dzięki temu Cert Warden dostępny będzie poprzez HTTPS.
Najważniejszym elementem wciąż pozostaje certyfikat używany przez Pebble, który trzeba dodać do magazynu certyfikatów w obrazie. Tworzymy więc plik Dockerfile.
W pliku cert umieszczamy skopiowaną wcześniej zawartość. Budujemy obraz.
Uruchomienie kontenerów z Cert Warden i nginx
Teraz tworzymy docker-compose.yml z definicjami potrzebnych kontenerów.
Plik default.conf z konfiguracją serwera nginx można ograniczyć do tej zawartości.
W katalogu ssl z kolei umieszczamy certyfikat i klucz dla domeny certs.avlab.local – nazwy plików widoczne są w powyższej konfiguracji. Można tymczasowo wygenerować certyfikat self-signed analogicznie do przykładu z acme.avlab.local.
Uruchamiany kontenery poleceniem
Konfiguracja Cert Warden
Po wejściu na http://certs.avlab.local zostaniemy przekierowani na połączenie szyfrowane, a następnie zobaczymy stronę logowania do Cert Warden. Domyślne poświadczenia to admin/password.
Strona logowania Cert Warden
Warto od razu ustawić bardziej złożone hasło w zakładce Settings.
Następnie przechodzimy do ACME Servers i dodajemy nasz serwer ACME. Nazwa dowolna, ale rozsądnym wyborem wydaje się acme_avlab. Jako adres serwera (Directory URL) podajemy https://acme.avlab.local:14000/dir.
Konfiguracja serwera ACME
Teraz w zakładce Providers usuniemy domyślną opcję http01internal – zamierzamy wykorzystywać weryfikację DNS do wszystkich domen, co w tej chwili jest ustawione dla domyślnego wpisu. Nie jest możliwe, aby usunąć ten wpis (bo przynajmniej jeden musi być dodany), więc poprzez edycję zmieniamy zakres obsługiwanych domen i wpisujemy dla przykładu avlab.old. Zapisujemy zmiany i wybieramy NEW PROVIDER, gdzie jako Provider Type ustawiamy DNS-01 go-acme le-go oraz obsługę wszystkich naszych domen (*). Czas oczekiwania na propagację rekordów (z racji używania lokalnego serwera nazw) można zmniejszyć do 5 sekund.
Dalsze zmiany są powiązane z konkretnym serwerem DNS. Warto kliknąć ikonę ze znakiem zapytania, co spowoduje otwarcie dokumentacji Cert Warden. Wybieramy z menu po lewej naszego providera (dns01 go-acme le-go) i klikamy odnośnik „dozens of DNS providers”. W dokumentacji go-acme szukamy wymaganych ustawień dla naszego serwera – tutaj to oczywiście Technitium (https://go-acme.github.io/lego/dns/technitium/). Jak widać, integracja z tym serwerem nie będzie skomplikowana.
Wymagana przez go-acme konfiguracja dla Technitium
W formularzu wpisujemy „technitium” i dodajemy pierwszą wymaganą zmienną, czyli TECHNITIUM_SERVER_BASE_URL=”http://192.168.1.45:5380″. API token należy wygenerować w panelu zarządzania Technitium dla użytkownika z uprawnieniami do modyfikacji stref – najprościej będzie wygenerować go zwyczajnie dla użytkownika Administrator. Po wyborze nazwy użytkownika w prawym górnym rogu panelu Technitium wybieramy Create API Token. Podajemy nazwę (np. acme) i przyciskiem Create tworzymy nowy token, który następnie kopiujemy. W Cert Warden dodajemy drugą wymaganą zmienną TECHNITIUM_API_TOKEN o wiadomej wartości. Zapisujemy zmiany, po czym możemy wreszcie usunąć http01internal (należy wybrać EDIT i dalej DELETE potwierdzając chęć usunięcia).
Utworzony token API
Pełna konfiguracja challenge providera
Teraz w Private Keys tworzymy nowy klucz dla celów ACME. Wystarczy ustawić nazwę (np. key_acme_avlab) i wybrać algorytm (zalecany jest najwyższy możliwy), ale oprócz tego polecam zaznaczyć opcję Disable API Key, co w pewnym stopniu „utwardzi” naszą konfigurację.
Klucze API w Cert Warden są wykorzystywane do pobierania certyfikatów/kluczy, a sama aplikacja może generować choćby format PFX naszych certyfikatów. Klucze są powiązane z danym kluczem, co pod względem bezpieczeństwa jest bardzo dobrą praktyką. jeżeli zależy nam na automatyzacji pobierania certyfikatów, to polecam zapoznać się z opisem na stronie https://www.certwarden.com/docs/using_certificates/api_calls/ – w każdym aspekcie działania Cert Warden zachowano prostotę.
Ostatnią wymaganą konfiguracją do dodania jest utworzenia konta używanego do komunikacji z serwerem ACME. W zakładce ACME Accounts wybieramy NEW ACCOUNT i uzupełniamy formularz zgodnie ze zrzutem ekranu.
Konfiguracja konta ACME
Generowanie certyfikatów
Możliwe jest już generowanie certyfikatów w zakładce Certificates. Sprowadza się to do podania nazwy certyfikatu (pewnie w większości przypadków sprawdzi się tutaj podawanie po prostu nazwy domeny), wybrania utworzonego konta ACME, algorytmu klucza oraz rzecz jasna nazwy domeny. jeżeli chcielibyśmy przygotować certyfikat wildcard, to w Subject Alternate Names należy wpisać domenę poprzedzając ją znakiem *, np. *.avlab.pl. Po uzupełnieniu wybieramy SUBMIT, a następnie PLACE NEW ORDER. Po chwili certyfikat powinien zostać wygenerowany i pojawi się możliwość jego pobrania.
Oczekiwanie na rozpoczęcie procesu wystawiania certyfikatu
Gotowy certyfikat – widoczna możliwość pobrania
W tym czasie „w tle” skrypt acme.sh (znajdujący się w kontenerze z Cert Warden) poprzez API Technitium dodaje rekord TXT _acme-challenge o wartości tokena otrzymanego z serwera ACME, a ten z kolei weryfikuje poprawność i ostatecznie generuje certyfikat SSL. Z innymi metodami weryfikacji można zapoznać się na stronie https://letsencrypt.org/docs/challenge-types/.
Wszystkie certyfikaty wraz z graficznie przedstawionym czasem do wygaśnięcia są wyświetlane w zakładce Dashboard. Po wejściu w wybraną pozycję będzie można pobrać certyfikat. Z kolei klucze dostępne są z poziomu Private Keys.
Szczegóły certyfikatu
Szczegóły klucza prywatnego
W logach Pebble widoczna jest aktywność związana z weryfikowaniem domeny i generowaniem certyfikatu.
Logi z działania Pebble
W przypadku wystąpienia błędów podczas procesu generowania certyfikatu można sprawdzić zakładkę Logs. Logowane są wszystkie istotne zdarzenia i co do zasady te informacje powinny być przydatne do rozwiązania problemu.
Podgląd logów Cert Warden
Podsumowanie
Cert Warden zdecydowanie ułatwia zarządzanie certyfikatami i z całą pewnością sprawdzi się w każdym środowisku z większą ilością serwerów czy domen do utrzymania. Po wdrożeniu – które nie jest specjalnie złożone i wymagające – powinien stać się centralnym punktem pozwalającym na pobieranie certyfikatów. Łatwość użycia API pozwala też na przygotowanie automatyzacji, aby uniknąć manualnej procedury wymiany certyfikatów co 90 dni.
To dojrzałe rozwiązanie i w tej chwili brak choćby porównywalnej alternatywy, aczkolwiek na początku tego roku pojawił się CertMate – jednak nie można tego uznać za jakościowe narzędzie, bo zwyczajnie nie działa (problemy pojawiają się już podczas instalacji), a sama obsługa jest znacznie trudniejsza. Wydaje się, iż mamy do czynienia z przykładem AI slop i raczej nie przewidywałbym sukcesu tego projektu.
















