Darmowe certyfikaty SSL dla środowisk testowych i deweloperskich
Jeżeli jesteś autorem aplikacji i stoisz własnie przed problemem skonfigurowania SSL w środowiskach testowych, ten artykuł jest własnie dla Ciebie. Dowiesz się z niego jak:
- zaopatrzyć swoje środowiska w certyfikaty LetsEncrypt;
- zautomatyzować ich generowanie oraz odświeżanie;
- w elegancki sposób obejść ograniczenia środowisk testowych i developerskich.
Z problemem konfiguracji SSL w środowiskach testowych mierzy się wielu autorów aplikacji. Certyfikaty płatne niepotrzebnie podnoszą koszt wdrożenia. Certyfikaty typu wildcard są często niedostępne albo klient/właściciel nie pozwala na ich użycie poza swoimi systemami produkcyjnymi. Z kolei certyfikaty self-signed psują wrażenie podczas prezentacji testowej wersji aplikacji.
LetsEncrypt jest darmowym urzędem certyfikacji, pozwalającym na tworzenie i odświeżanie darmowych certyfikatów X.509. Oferowany od 2016 roku, zdobył bardzo dużą popularność oraz doczekał się wielu implementacji integrujących go z popularnymi serwerami WWW i aplikacjami terminującymi ruch SSL.
Certyfikaty LetsEncrypt są bardzo przydatne w środowiskach developerskich i stagingowych. Z racji krótkiego terminu ważności (90 dni) pociągają za sobą konieczność automatyzacji, która bywa utrudniona z uwagi na niejednolite i często niedostępne z Internetu środowisko.
Przeszkodę mogą stanowić także obowiązujące limity pozwalające – w momencie pisania tego artykułu – na generowanie maksymalnie 20 certyfikatów dla domen tygodniowo.
W tym artykule przyjrzymy się metodom które możemy wdrożyć, aby obejść te ograniczenia, zapewnić szyfrowaną komunikację bez względu na to czy środowisko jest dostępne z Internetu czy nie oraz za pomocą jakiej aplikacji terminowany jest ruch SSL. Przedstawimy również pseudokod implementacji oraz rozwiązania, których można użyć do wdrożenia własnego rozwiązania.
Sposoby uwierzytelnień (challenge types)
Standardowym sposobem walidacji żądań o certyfikat jest protokół http-01 ACME. Korzysta on z weryfikacji poprzez czasowe wystawienie pliku o nazwie i treści podanej przez serwer ACME (np. LetsEncrypt.org). Z tej metody korzysta większość narzędzi służących do automatyzacji certyfikacji serwerów WWW, wraz z najpopularniejszym certbot.
Rozwiązanie to posiada dwie zasadnicze wady:
- sposób implementacji jest zależny od rodzaju użytego serwera WWW
- wystawienie zasobów do weryfikacji może interferować z wykorzystywaną aplikacją webową – jeśli przykładowo posiadamy automatyczne przekierowanie dodające prefiks www. do adresu, to będziemy musieli je wyłączyć na czas generowania certyfikatu bez prefiksu.
- certyfikowana witryna musi być dostępna z Internetu, co często jest niemożliwe dla środowisk czysto developerskich.
Istnieje możliwość dokonania walidacji bez inicjowania ruchu do serwera WWW. Udostępnia go mechanizm dns-01 ACME. Autentykacja w tym schemacie odbywa się z wykorzystaniem rekordów TXT w DNS, w związku z czym:
- może być wykorzystana niezależnie od wykorzystywanego serwera WWW
- nie ma możliwości interferencji z aplikacją webową
- certyfikowana witryna nie musi być dostępna z Internetu, co więcej – certyfikowana domena nie musi w ogóle istnieć, o ile mamy tylko kontrolę nad domeną nadrzędną.
Przykładowa architektura
Poniższy diagram przedstawia przykładowy schemat komunikacji podczas certyfikacji z wykorzystaniem metody dns-01:
Bezpośrednio w procesie biorą udział tylko: serwer DNS dla obsługi pożądanej domeny oraz usługa certyfikacji.
Za serwer DNS może służyć dowolna usługa, która pozwala na dynamiczną edycję rekordów. Może być to przykładowo serwer DNS obsługiwany przez API (Amazon Route53, CloudFlare), a także dowolny serwer obsługujący protokół RFC2136 (Microsoft DNS, Bind 8, Bind 9).
Usługa certyfikacji inicjuje komunikację z LetsEncrypt, dokonuje walidacji poprzez edycję serwerów DNS oraz – po otrzymaniu certyfikatów – wgrywa go na serwery webowe i wykonuje ich reload w celu wczytania nowych danych.
Co warto zauważyć, usługa certyfikacji może działać osobno i obsługiwać wszystkie serwery WWW, ale również może być zainstalowana na każdym serwerze WWW jako osobny proces – o ile tylko polityka ruchu w podsieci prywatnej będzie pozwalać na ruch wychodzący.
Implementacja
Pseudokod usługi certyfikacji może wyglądać następująco:
domeny=pobierz_liste_domen()
challenge=zainicjuj_komunikacje_letsencrypt(domeny)
wprowadz_zmiany_w_dns(challenge)
while sprawdz_challenge(challenge):
time.sleep(5)
zapisz_certyfikat_i_klucz()
przeladuj_serwer_www()
domeny=pobierz_liste_domen()
challenge=zainicjuj_komunikacje_letsencrypt(domeny)
wprowadz_zmiany_w_dns(challenge)
while sprawdz_challenge(challenge):
time.sleep(5)
zapisz_certyfikat_i_klucz()
przeladuj_serwer_www()
W przypadku jeśli nasz serwer obsługuje RFC2136 to do aktualizacji możemy wykorzystać narzędzie nsupdate:
$ nsupdate -d -k klucz
server dns.example.org
zone example.org.
update delete _acme-challenge.dev.projekt.example.org.
update add _acme-challenge.dev.projekt.example.org. 3600 TXT “LOREM IPSUM”
send
lub oprzeć się na wielu dostępnych implementacjach programistycznych, np. module dns dostępnych w Pythonie:
def doDNSUpdate(server, zone, record, value):
keyRing, keyAlgo = getDNSKey(DNS_KEYFILE)
update = dns.update.Update(zone, keyring=keyRing)
if value is not None:
update.replace(record, 5, "TXT", value)
else:
update.delete(record)
dns.query.tcp(update, server)
W przypadku jeśli nasz serwer DNS nie obsługuje dynamicznych zmian w DNS, zawsze możemy spróbować skorzystać z ich API – może to być konieczne przykładowo w przypadku AWS Route53.
Implementacja protokołu ACME może być czasochłonna, dlatego warto oprzeć się gotowych rozwiązaniach, np. acme-tiny.
Podsumowując…
Wdrożenie mechanizmu automatycznej certyfikacji witryn jest szczególnie przydatne w mieszanych środowiskach devopsowych, gdzie rozwijane jest wiele projektów w różnych technologiach. Zaproponowane rozwiązania mogą być zastosowane niezależnie od tego czy aplikacja jest w Javie, Ruby on Rails czy w PHP. Co ważne, nie wymagają one otwarcia środowisk developerskich na świat.
Wydzielenie osobnej usługi generowania certyfikatów pozwala dodatkowo obejść ograniczenia ilościowe LetsEncrypt, o ile tylko pozwolimy, aby usługa certyfikacji zbierała wiele poddomen w jednym certyfikacie z rozszerzeniem SAN. Pozwala to na zwiększenie maksymalnej ilości certyfikatów o około 100 razy.
Prawidłowo przygotowana usługa certyfikacji będzie mogła zostać szybko wrzucona na dowolne istniejące lub nowe środowisko, automatycznie zaopatrując je w zaufane certyfikaty SSL.