Let’s Encrypt za reverse proxy: jak uzyskać certyfikat


W tym artykule
- Dlaczego odnowienie certyfikatu nie działa po przejściu za proxy?
- Najpierw zdecyduj: certyfikat na serwerze źródłowym czy na proxy?
- Kierowanie ścieżki wyzwania ACME w NGINX dla HTTP-01
- Wyzwanie DNS-01: walidacja, której proxy nie przeszkadza
- Co sprawdzić przed następnym odnowieniem
- Jak wybrać konfigurację Let’s Encrypt za reverse proxy, która nie przestanie się odnawiać
- FAQ
Gdy Let’s Encrypt działa za reverse proxy, certyfikaty zwykle przestają się wystawiać z jednego nudnego powodu: żądanie walidacyjne trafia teraz na proxy, a nie na serwer źródłowy. Są trzy rozwiązania. Przekazać ścieżkę wyzwania ACME do serwera źródłowego, przenieść certyfikat na proxy albo przejść na walidację DNS-01.
Historia prawie zawsze wygląda tak samo. Odnawianie przez miesiące działało bez zarzutu. Potem ktoś skierował rekord A domeny na proxy i następna próba się wyłożyła. Poniżej znajdziesz, jak namierzyć przyczynę, gdzie certyfikat powinien właściwie być, jak skonfigurować NGINX pod ścieżkę wyzwania oraz DNS-01 (sposób, który działa tak samo, niezależnie od tego, czy przed stroną stoi proxy).
Dlaczego odnowienie certyfikatu nie działa po przejściu za proxy?
Bo walidacja HTTP-01 pobiera plik z adresu IP, na który rozwiązuje się domena. A ten adres należy teraz do proxy. Token zapisany przez serwer źródłowy nigdy więc nie zostaje zwrócony. Dokumentacja typów wyzwań Let’s Encrypt opisuje mechanizm: klient ACME zapisuje plik z tokenem pod http://<domain>/.well-known/acme-challenge/<TOKEN>, a Let’s Encrypt go pobiera, czasem kilka razy i z kilku lokalizacji. Coś między publiczną nazwą hosta a tym plikiem zachowuje się inaczej? Walidacja się sypie.
Log klienta powie ci, z którym wariantem masz do czynienia. Błąd 404 albo „unauthorized”. Przekierowanie na HTTPS, którego proxy nie potrafi obsłużyć. Albo zwykły timeout. Jeszcze jedno: nieudana walidacja oznacza start od nowa z nowym zamówieniem, więc najpierw napraw ścieżkę, a dopiero potem ponów próbę, nie odwrotnie.
Najpierw zdecyduj: certyfikat na serwerze źródłowym czy na proxy?
Miejsce, w którym kończy się TLS, decyduje o tym, gdzie jest certyfikat i które wyzwanie ma sens. Zostawiasz certyfikat na serwerze źródłowym: proxy tylko przepuszcza ruch, serwer źródłowy zachowuje swojego klienta ACME, a ścieżka wyzwania musi do niego docierać. Przenosisz go na proxy: ten, kto obsługuje tam TLS, obsługuje też klienta ACME. Serwer źródłowy nie wystawia wtedy publicznie niczego do walidacji.
- Kto odnawia: ty na serwerze źródłowym albo operator proxy na proxy.
- Co się psuje przy zmianie proxy: certyfikat na serwerze źródłowym zależy od tego, czy proxy przekazuje ścieżkę wyzwania, a certyfikat na proxy trzeba wystawić ponownie wszędzie tam, gdzie przenosi się TLS.
- Wildcardy: potrzebujesz takiego? Tak czy inaczej planuj DNS-01.
Wybór należy do ciebie. Zanim się zdecydujesz, zapytaj operatora proxy, jak obsługuje TLS i ścieżkę /.well-known (zdziwiłbyś się, jak często nikt o to nie pyta). A jeśli nadal nie masz pewności, czy proxy w ogóle powinno stać przed stroną, najpierw rozważ argumenty za reverse proxy.
Kierowanie ścieżki wyzwania ACME w NGINX dla HTTP-01
Na serwerze źródłowym udostępnij /.well-known/acme-challenge/ przez zwykłe HTTP i umieść tę regułę przed jakimkolwiek przekierowaniem na HTTPS. Wtedy żądanie przekazane przez proxy faktycznie znajdzie token. Na własnym serwerze źródłowym:
- Dodaj blok location dla ścieżki wyzwania, wskazujący na katalog webroot.
- Wyłącz ten blok z przekierowania z HTTP na HTTPS.
- Skieruj klienta ACME na ten sam webroot, na przykład
certbot certonly --webroot -w /var/www/acme -d example.com. - Sprawdź konfigurację poleceniem
nginx -ti przeładuj NGINX.
server {
listen 80;
server_name example.com;
location ^~ /.well-known/acme-challenge/ {
root /var/www/acme;
default_type text/plain;
}
location / {
return 301 https://$host$request_uri;
}
}Test jest prosty. Wrzuć plik do /var/www/acme/.well-known/acme-challenge/, pobierz go przez publiczną nazwę hosta z innej sieci i sprawdź, czy access log serwera źródłowego odnotował żądanie. Haczyk: to działa tylko wtedy, gdy proxy przekazuje zwykłe żądania HTTP dla tej ścieżki bez zmian. Sprawdź więc także stronę proxy.
Wyzwanie DNS-01: walidacja, której proxy nie przeszkadza
DNS-01 potwierdza kontrolę nad domeną rekordem TXT pod _acme-challenge.<domain>, więc routing HTTP przez proxy przestaje mieć znaczenie. Czy konfiguracja jest trudniejsza niż przy HTTP-01? Tak. Ale obsługuje przypadki, z którymi HTTP-01 sobie nie radzi, i pozwala wystawiać certyfikaty wildcard. Potrzebujesz dostawcy DNS z API albo delegujesz _acme-challenge przez CNAME lub NS do strefy, która szybko się aktualizuje.
Na propagacji ludzie najczęściej się przejeżdżają. Klient powinien poczekać, aż rekord będzie widoczny wszędzie, zanim uruchomi walidację. Zgodnie z sekcją DNS-01 w dokumentacji, jeśli dostawca nie daje sposobu na sprawdzenie propagacji, czasem trzeba czekać nawet godzinę. Aha, i usuwaj stare rekordy TXT, bo Let’s Encrypt odrzuca zbyt dużą odpowiedź.
Co sprawdzić przed następnym odnowieniem
Zrób próbne odnowienie i sprawdź ścieżkę wyzwania albo rekord TXT spoza swojej sieci, dużo wcześniej, niż certyfikat zbliży się do końca ważności. certbot renew --dry-run przechodzi cały proces na środowisku testowym i nie rusza działającego certyfikatu.
- DNS rozwiązuje się tam, gdzie oczekujesz: na proxy albo na serwer źródłowy.
- Adres wyzwania zwraca token przez zwykłe HTTP z zewnętrznej sieci.
- Nie ma pętli przekierowań między proxy a serwerem źródłowym.
- Deploy hook przeładowuje NGINX po odnowieniu, na przykład
--deploy-hook "systemctl reload nginx". - Monitoring ważności wysyła alerty niezależnie od klienta ACME.
Każdy wystawiony certyfikat trafia do publicznych logów, więc twoje nazwy hostów zostawiają ślady w logach Certificate Transparency, którym warto się czasem przyjrzeć. Dopiero planujesz warstwę proxy? Porównaj plany reverse proxy Jalvo i rozważ współdzielone i dedykowane adresy IP dla adresów stojących przed twoim serwerem źródłowym.
Jak wybrać konfigurację Let’s Encrypt za reverse proxy, która nie przestanie się odnawiać
Działają trzy opcje. Zostawić certyfikat na serwerze źródłowym i przekazywać ścieżkę wyzwania. Zarządzać certyfikatem na proxy. Albo wybrać DNS-01, gdy nie masz kontroli nad routingiem HTTP lub potrzebujesz wildcarda. Moja rada: wybierz tę opcję, której elementy naprawdę kontrolujesz, i przetestuj ją przed oknem odnowienia, a nie w jego trakcie. Konfigurację wokół tego opisujemy w artykułach o konfiguracji hostingu. Let’s Encrypt za reverse proxy odnawia się niezawodnie, gdy walidacja ma ścieżkę, która nie opiera się na zgadywaniu.
FAQ
Czy mogę zostać przy HTTP-01, jeśli proxy wymusza HTTPS?
u003cpu003eTak, o ile ścieżka wyzwania pozostaje osiągalna. Let’s Encrypt podąża za przekierowaniem, ale walidacja udaje się tylko wtedy, gdy cel faktycznie zwraca token. Uszkodzony certyfikat albo pętla przekierowań po stronie HTTPS nadal ją zablokuje. Bezpieczniej jest wyłączyć tę ścieżkę z przekierowania.u003c/pu003e
Czy do certyfikatu wildcard potrzebuję DNS-01?
u003cpu003eTak. Dokumentacja wyzwań Let’s Encrypt przypisuje wystawianie wildcardów do DNS-01, a HTTP-01 nie zwaliduje nazwy wildcard. Zaplanuj API DNS albo delegowaną strefę u003ccodeu003e_acme-challengeu003c/codeu003e.u003c/pu003e
Dlaczego walidacja przeszła na jednym serwerze, a przez proxy nie?
u003cpu003eBo Let’s Encrypt sprawdza publiczną nazwę hosta z kilku lokalizacji. Lokalny curl na serwerze źródłowym nic nie mówi o trasie przez proxy. Testuj przez publiczną nazwę DNS z zewnętrznej sieci i upewnij się, że żądanie pojawia się w access logu serwera źródłowego.u003c/pu003e
Daj każdej stronie własne IP.
Pierwszą domenę dodasz w kilka minut.


