Instalacja Certbot na Ubuntu 24.04 dla Nginx
Instrukcja instalacji Certbot przez apt lub snap na Ubuntu 24.04. Wyjaśnienie różnic w odnawianiu certyfikatów Let's Encrypt oraz rozwiązanie problemu timeout na porcie 80.
Instalacja Certbot: apt lub snap
W systemie Ubuntu 24.04 pakiet sudo apt install certbot python3-certbot-nginx dostarcza działającego klienta Certbot, który wydaje rzeczywiste, zaufane publicznie certyfikaty Let's Encrypt. Oficjalna dokumentacja Certbot zaleca użycie pakietu snap; różnica jest niewielka – snap śledzi wydania upstream, natomiast pakiet z repozytorium systemowego podąża za wersją dostarczoną z wydaniem LTS i otrzymuje poprawki bezpieczeństwa.
Należy wybrać jedną metodę. Posiadanie dwóch kopii Certbot oznacza dwa timery odnawiania wycelowane w to samo drzewo /etc/letsencrypt, a zapomniana instancja może spowodować nieoczekiwane problemy.
Ścieżka apt:
sudo apt update
sudo apt install certbot python3-certbot-nginxTo polecenie instaluje /usr/bin/certbot, wtyczkę dla nginx, parę certbot.service + certbot.timer oraz wpis /etc/cron.d/certbot, który w systemie systemd nie wykonuje żadnych działań.
Ścieżka snap:
sudo apt remove certbot python3-certbot-nginx
sudo snap install core && sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbotPakiet snap dostarcza własny timer, snap.certbot.renew.timer. Przed instalacją wersji snap należy usunąć pakiet apt.
Obie metody instalacji zachowują się później identycznie, poza dokładnym momentem decyzji o odnowieniu (opisano to w sekcji Odnawianie poniżej). Certbot w wersji 2.x domyślnie używa kluczy ECDSA (P-256); flagę --key-type rsa należy przekazać tylko w przypadku klienta, który nie obsługuje ECDSA. Cały stan przechowywany jest w /etc/letsencrypt: archive/ zawiera rzeczywiste pliki kluczy i certyfikatów, live/ przechowuje dowiązania symboliczne do aktualnych plików, renewal/ zawiera jeden plik konfiguracyjny na certyfikat, a accounts/ przechowuje klucz konta ACME.
Na czym polega wyzwanie HTTP-01 i dlaczego port 80 jest wymagany
Wyzwanie HTTP-01 to mechanizm typu callback. Użytkownik prosi Let's Encrypt o certyfikat dla domeny example.com; urząd certyfikacji sprawdza nazwę w publicznym systemie DNS, nawiązuje połączenie z portem 80 pod znalezionym adresem i żąda pliku http://example.com/.well-known/acme-challenge/<token>. Serwer odpowiada dokładną treścią tokena, który Certbot zapisał wcześniej na dysku. To cały mechanizm. Wynikają z niego trzy konsekwencje, które odpowiadają za większość nieudanych prób wydania certyfikatu.
- Port 80 musi być dostępny z publicznego Internetu, a nie tylko z poziomu sieci lokalnej. Reguła
ufw, grupa zabezpieczeń u dostawcy chmurowego lub firewall w konsoli VPS, który otwiera wyłącznie port 443, uniemożliwia wydanie certyfikatu oraz każde przyszłe odnowienie. - Rekordy DNS muszą już wskazywać na ten serwer. Serwer walidacyjny wykonuje własne zapytanie z zewnątrz; wpisy w pliku
/etc/hostsoraz pamięć podręczna przeglądarki nie mają dla niego znaczenia. - W przypadku publikacji rekordu AAAA, w pierwszej kolejności podejmowana jest próba połączenia przez IPv6. Let's Encrypt ponawia próbę przez IPv4 tylko wtedy, gdy połączenie IPv6 przekroczy limit czasu. Odrzucone połączenie IPv6 nie jest ponawiane, a nieaktualny rekord AAAA wskazujący na hosta, który akceptuje połączenie i serwuje inną treść, powoduje błąd krytyczny.
Przekierowania są dozwolone: walidacja podąża za przekierowaniem HTTP na HTTPS i nie weryfikuje, czy certyfikat po drugiej stronie jest poprawny, wygasły lub samopodpisany. Proces walidacji musi jednak zawsze rozpocząć się na porcie 80. Certbot nie posiada implementacji TLS-ALPN-01, więc "użycie portu 443" nie stanowi rozwiązania problemu.
Wybór metody uwierzytelniania: --nginx, --webroot, --standalone
--nginx jest właściwym wyborem domyślnym, gdy Nginx już działa i obsługuje daną domenę. Certbot analizuje konfigurację, wstrzykuje tymczasową lokalizację wyzwania (challenge), przeładowuje Nginx, przeprowadza walidację, a następnie zapisuje dyrektywy TLS w bloku serwera. Brak przestojów.
sudo certbot --nginx -d example.com -d www.example.comWersja skryptowa dla świeżego systemu:
sudo certbot --nginx \
-d example.com -d www.example.com \
--agree-tos -m ops@example.com --no-eff-email \
--redirect --non-interactive--webroot jest odpowiedni, gdy konfiguracja Nginx ma pozostać nienaruszona przez Certbot, na przykład gdy jest generowana z szablonu, przechowywana w git lub wdrażana przez Ansible. Certbot zapisuje jedynie plik wyzwania w katalogu, który jest już serwowany.
sudo certbot certonly --webroot -w /var/www/example.com \
-d example.com -d www.example.com \
--deploy-hook "systemctl reload nginx"--standalone jest właściwy, gdy port 80 jest wolny: w przypadku serwera pocztowego, API komunikującego się wyłącznie przez 443 lub skryptu inicjującego, który uruchamia się przed instalacją Nginx. Certbot samodzielnie wiąże port 80 na kilka sekund. Jeśli Nginx działa, proces zakończy się niepowodzeniem; należy go zatrzymać na czas wykonania polecenia:
sudo certbot certonly --standalone -d mail.example.com \
--pre-hook "systemctl stop nginx" \
--post-hook "systemctl start nginx"Te operacje (hooki) są zapisywane w konfiguracji odnawiania certyfikatu, dzięki czemu to samo zatrzymanie i uruchomienie usług odbywa się automatycznie podczas odnawiania.
Blok serwera działający przed i po uzyskaniu certyfikatu
Problem jajka i kury: nginx odmawia uruchomienia, gdy ssl_certificate wskazuje na nieistniejący plik, a Certbot nie może przeprowadzić walidacji, gdy nginx nie działa. Należy najpierw uruchomić witrynę na porcie 80.
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
location ^~ /.well-known/acme-challenge/ {
root /var/www/example.com;
default_type "text/plain";
try_files $uri =404;
}
location / {
try_files $uri $uri/ =404;
}
}Uruchom sudo nginx -t && sudo systemctl reload nginx, upewnij się, że curl -I http://example.com/ odpowiada z zewnątrz serwera, a następnie wystaw certyfikat. Następnie:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
location ^~ /.well-known/acme-challenge/ {
root /var/www/example.com;
default_type "text/plain";
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}Dłuższy prefiks ACME ma pierwszeństwo przed location /, więc return 301 nigdy nie otrzymuje żądania wyzwania. Modyfikator ^~ jest przydatny w innych sytuacjach: gdy prefiks pasuje, nginx całkowicie pomija lokalizacje z wyrażeniami regularnymi, więc reguła dodana później, taka jak location ~ /\. { deny all; }, nie może zablokować wyzwania. Utrzymanie tej lokalizacji na porcie 80 zapewnia, że odnawianie certyfikatów będzie działać nawet po przełączeniu reszty witryny wyłącznie na HTTPS.
Oba powyższe bloki serwują pliki z dysku; jeśli nginx pełni rolę proxy dla aplikacji, location / staje się blokiem proxy_pass, a blok serwera reverse proxy, wiersz po wierszu opisuje nagłówki wymagane przez aplikację, podczas gdy lokalizacja ACME i dyrektywy TLS pozostają bez zmian.
Składnia HTTP/2 zależy od wersji nginx. Ubuntu 24.04 dostarcza nginx 1.24, który wymaga zapisu w jednej linii, listen 443 ssl http2;, i nie uruchomi się, jeśli użyjesz oddzielnej dyrektywy http2 on;. Debian 13 dostarcza nginx 1.26, który wymaga http2 on; i jedynie wyświetla ostrzeżenie, że zapis w jednej linii jest przestarzały. Sprawdź najpierw nginx -v.
Wskaż nginx na live/, nigdy na archive/. Dowiązania symboliczne live/ są aktualizowane przy każdym odnowieniu; użycie bezpośredniej ścieżki do archive/ spowoduje przypisanie do certyfikatu, który wygaśnie bez wiedzy administratora.
Certyfikaty wildcard wymagają DNS-01, a DNS-01 wymaga wtyczki
Certyfikatu typu wildcard (*.example.com) nie można zweryfikować metodą HTTP-01, ponieważ nie istnieje pojedyncza nazwa hosta, z której można pobrać plik. Jedyną drogą jest DNS-01: kontrolę nad domeną potwierdza się poprzez publikację rekordu TXT _acme-challenge.example.com. Aby Certbot mógł wykonać to automatycznie, wymaga danych uwierzytelniających API dostawcy DNS – właśnie do tego służą wtyczki dostawców. Pełny przewodnik po certyfikatach wildcard omawia mechanikę rekordów TXT oraz pułapkę odnawiania w trybie ręcznym; poniżej znajduje się skrócona wersja dla Cloudflare.
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflareW przypadku instalacji przez apt należy użyć sudo apt install python3-certbot-dns-cloudflare. Dane uwierzytelniające umieszcza się w pliku dostępnym tylko dla użytkownika root:
# /root/.secrets/cloudflare.ini
# then: sudo chmod 600 /root/.secrets/cloudflare.ini
dns_cloudflare_api_token = your_scoped_token_hereOgranicz uprawnienia tokena do edycji DNS tylko dla wybranej strefy. Jest to klucz do Twojego DNS; traktuj go odpowiednio.
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
-d example.com -d '*.example.com'Użyj cudzysłowu dla nazwy wildcard, aby powłoka nie zinterpretowała jej jako wzorca (glob). Metoda DNS-01 rozwiązuje również problemy, z którymi HTTP-01 sobie nie radzi: certyfikaty dla hostów bez publicznego portu 80, usług wewnętrznych, maszyn dostępnych wyłącznie przez własny serwer WireGuard VPN na VPS lub paneli administracyjnych na prywatnym interfejsie.
Odnawianie: 90 dni, timer, deploy hook
Certyfikaty Let’s Encrypt są ważne przez 90 dni. Pakiet apt (Certbot 2.9.0) wykonuje odnowienie, gdy pozostaje mniej niż 30 dni ważności. Wersja snap śledzi aktualne wydania Certbot, który od wersji 4.1 sprawdza również w Let’s Encrypt sugerowany czas odnowienia poprzez ACME Renewal Info (ARI) i może odnowić certyfikat wcześniej; dla certyfikatu Let’s Encrypt oznacza to zazwyczaj około dwóch trzecich okresu jego ważności. W obu przypadkach użytkownik dysponuje około 30-dniowym oknem, w którym nieudane odnowienie jest problemem możliwym do naprawienia, a nie awarią. Należy spodziewać się częstszych odnowień od przyszłego roku: domyślny profil Let’s Encrypt przechodzi na certyfikaty 64-dniowe 10 lutego 2027 roku oraz na certyfikaty 45-dniowe 16 lutego 2028 roku. Let’s Encrypt nie wysyła już powiadomień e-mail o wygasaniu, nikt nie przypomni o tym fakcie, więc monitorowanie pozostaje w gestii administratora.
Sprawdź timer dostarczony z instalacją:
systemctl list-timers 'certbot*' 'snap.certbot*'
sudo certbot certificatescertbot renew przegląda każdą konfigurację w /etc/letsencrypt/renewal/, pomija te, których termin jeszcze nie nadszedł, i odnawia pozostałe przy użyciu opcji zapisanych w danej konfiguracji. Są to flagi z pierwszego uruchomienia, chyba że zostały później zmienione za pomocą certbot reconfigure. Dlatego pierwsze uruchomienie jest kluczowe: to ono zostaje zapisane.
Samo odnowienie pliku na dysku niczego nie zmienia, nginx kontynuuje serwowanie starego certyfikatu z pamięci, dopóki nie otrzyma polecenia przeładowania. Skonfiguruj deploy hook jednorazowo:
sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh >/dev/null <<'EOF'
#!/bin/sh
set -e
nginx -t && systemctl reload nginx
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.shKażdy plik wykonywalny w renewal-hooks/deploy/ uruchamia się po każdym udanym odnowieniu. Flaga --deploy-hook wykonuje to samo zadanie dla pojedynczego certyfikatu, zapisując renew_hook = ... w jego konfiguracji odnowienia. certbot --nginx przeładowuje usługę automatycznie; konfiguracje --webroot oraz --standalone tego nie robią. Brak hooka jest bezpośrednią przyczyną sytuacji, w której witryna serwuje wygasły certyfikat, podczas gdy certbot certificates poprawnie raportuje nowy. Każda inna usługa odczytująca certyfikat przy starcie wymaga tego samego hooka; aplikacja kontenerowa, taka jak instalacja Nextcloud na VPS z Dockerem, TLS i kopiami zapasowymi, również wymaga tutaj skonfigurowania kroku restartu lub przeładowania.
Testowanie odnawiania w warunkach rzeczywistych
sudo certbot renew --dry-runPolecenie to uruchamia pełny proces weryfikacji w środowisku testowym (staging) Let's Encrypt. Wykorzystywana jest ta sama ścieżka kodu, te same reguły firewalla oraz ta sama konfiguracja DNS. Operacja nie jest wliczana do limitów produkcyjnych (środowisko staging posiada własne, znacznie wyższe limity), a certyfikaty nie są zapisywane na dysku. Jeśli test zakończy się powodzeniem, automatyczne odnawianie za 60 dni również przebiegnie pomyślnie, pod warunkiem, że konfiguracja serwera nie ulegnie zmianie.
Testowe uruchomienie (dry run) nie potwierdza poprawnego wywołania skryptu przeładowania (reload hook), ponieważ zachowanie to różni się w zależności od wersji Certbot. Należy przetestować ten element ręcznie: uruchomić skrypt hooka bezpośrednio, potwierdzić, że systemctl reload nginx kończy się powodzeniem, oraz sprawdzić sudo grep renew_hook /etc/letsencrypt/renewal/example.com.conf.
Błędy, które faktycznie wystąpią
Could not bind to IPv4 or IPv6., --standalone podczas gdy nginx zajmuje już port 80. Użyj --nginx lub --webroot albo zatrzymaj nginx na czas uruchomienia. Potwierdź proces zajmujący port za pomocą sudo ss -lntp | grep ':80'.
Timeout during connect (likely firewall problem), Let's Encrypt nie może uzyskać dostępu do portu 80. Sprawdź po kolei: sudo ufw status (otwórz go za pomocą sudo ufw allow 'Nginx Full'), następnie własny firewall dostawcy VPS, a na końcu DNS. Przetestuj połączenie z lokalizacji innej niż serwer: curl -sSv http://example.com/.well-known/acme-challenge/test. Nieaktualny rekord AAAA powoduje ten sam komunikat.
unauthorized :: Invalid response from http://example.com/.well-known/acme-challenge/xyz: 404, port 80 jest osiągalny, ale token nie jest serwowany. Żądanie trafiło do innego bloku serwera (sprawdź, który z nich obsługuje default_server) lub katalog wskazany w -w nie jest tym, z którego korzysta nginx. Umieść plik w /var/www/example.com/.well-known/acme-challenge/test i pobierz go z zewnątrz; jeśli otrzymasz błąd 404, problem nigdy nie dotyczył certyfikatu.
DNS problem: NXDOMAIN looking up A for example.com, nazwa nie rozwiązuje się publicznie. Przyczyną są nowe rekordy, które nie zostały jeszcze rozpropagowane, lub rekord w strefie, której nie obsługuje Twój rejestrator.
too many certificates (5) already issued ..., limit szybkości, na który użytkownicy trafiają podczas debugowania w pętli. Komunikat wskazuje limit i kończy się czasem retry after. Let's Encrypt ogranicza liczbę duplikatów certyfikatów (ten sam zestaw nazw) do pięciu na tydzień i nie oferuje możliwości obejścia tego limitu, więc jedynym rozwiązaniem jest odczekanie. Osobno dozwolone jest 50 nowych certyfikatów na domenę zarejestrowaną na tydzień; ten limit można zwiększyć, składając wniosek o jego podniesienie. Żądanie o ten sam zestaw nazw co istniejący certyfikat jest traktowane jako odnowienie i jest zwolnione z tego limitu, a odnowienia koordynowane przez ARI są zwolnione ze wszystkich limitów. Debuguj w środowisku staging za pomocą --dry-run.
nginx: [emerg] cannot load certificate "/etc/letsencrypt/live/example.com/fullchain.pem": No such file or directory, nginx jest skonfigurowany dla certyfikatu, który nigdy nie został wydany lub został usunięty za pomocą certbot delete. Zakomentuj blok serwera TLS, uruchom nginx, wydaj certyfikat, a następnie przywróć blok.
open() "/etc/letsencrypt/options-ssl-nginx.conf" failed, ten plik jest dostarczany z pakietem wtyczki nginx. Na systemie certonly bez python3-certbot-nginx należy albo dodać wtyczkę, albo zastąpić linię include własnymi ustawieniami ssl_protocols oraz ssl_ciphers.
Zarządzanie na dużą skalę
Jeden certyfikat może zawierać do 100 nazw, a pojedynczy certbot --nginx -d a.example.com -d b.example.com ... bywa kuszący, dopóki jeden nieaktualny rekord DNS nie uniemożliwi walidacji, wyłączając tym samym wszystkie pozostałe nazwy przypisane do tego certyfikatu. Osobne certyfikaty dla każdej witryny ulegają awarii niezależnie, co jest pożądanym zachowaniem na serwerze obsługującym więcej niż kilka usług. Powyżej kilku witryn, reverse proxy z obsługą ACME staje się opłacalne: Traefik reverse proxy działający z wieloma aplikacjami w Docker Compose samodzielnie żąda i odnawia certyfikaty, eliminując potrzebę korzystania z Certbot. Wybór odpowiedniego proxy zależy od indywidualnych potrzeb, a porównanie Nginx, Caddy i Traefik sprowadza się głównie do tego, jak dużą część konfiguracji certyfikatów i poszczególnych aplikacji ma przejąć proxy.
Wykonuj kopie zapasowe /etc/letsencrypt w całości, używając sudo tar -czf letsencrypt-$(date +%F).tar.gz -C /etc letsencrypt, zachowując dowiązania symboliczne. To drzewo katalogów zawiera accounts/, klucz konta ACME, którego nie można odtworzyć w identycznej postaci. Przeniesienie na nowy VPS sprowadza się do: synchronizacji drzewa za pomocą -a, instalacji Certbot, przekierowania DNS i uruchomienia certbot renew --dry-run przed przełączeniem ruchu.
Po przebudowie serwera lub migracji do nowej wersji LTS, licznik odnowień nie zostanie przeniesiony automatycznie. Po każdej migracji, przywróceniu migawki lub aktualizacji dystrybucji, należy uruchomić systemctl list-timers 'certbot*' oraz wykonać --dry-run. Pominięcie tego kroku skutkuje wygaśnięciem certyfikatu po 89 dniach, o godzinie 3 nad ranem, mimo przekonania, że proces odnawiania działa w tle.
Powyższe metody HTTP-01 zakładają posiadanie maszyny z publicznym adresem IP i otwartym portem 80, czyli w praktyce VPS; metoda DNS-01 nie wymaga żadnego z nich. Mechanizmy działania pozostają identyczne w obu przypadkach.
Te same kroki dotyczące certyfikatów mają zastosowanie w przypadku Apache zamiast nginx, a gdy użycie publicznego certyfikatu nie jest możliwe, certyfikat z podpisem własnym na Ubuntu zabezpiecza usługi wewnętrzne.
FAQ
Czy port 80 musi być otwarty, jeśli witryna obsługuje tylko HTTPS?
Tak, ze względu na wyzwanie HTTP-01. Let’s Encrypt zawsze rozpoczyna żądanie weryfikacji na porcie 80, a Certbot nie posiada implementacji TLS-ALPN-01. Firewall blokujący wszystko poza portem 443 uniemożliwi zarówno pierwsze wydanie certyfikatu, jak i każde kolejne automatyczne odnowienie. Przekierowanie z portu 80 na HTTPS jest dopuszczalne, ponieważ weryfikacja podąża za nim. Jedynym sposobem na całkowite pominięcie portu 80 jest użycie DNS-01, za pomocą wtyczki dostawcy lub opcji --manual --preferred-challenges dns w Certbot, gdzie rekord TXT dodaje się ręcznie. W takim przypadku odnawianie przestaje być automatyczne, chyba że zostanie dostarczony skrypt --manual-auth-hook.
apt czy snap – którą wersję Certbot zainstalować dla nginx na Ubuntu 24.04?
Należy użyć apt. sudo apt install certbot python3-certbot-nginx dostarcza Certbot 2.9.0 na Ubuntu 24.04, co jest wersją wystarczającą dla wszystkich kroków w tym poradniku. Wersja ta otrzymuje poprawki bezpieczeństwa poprzez unattended-upgrades i nie wymaga snapd. Wybór snap jest uzasadniony tylko w przypadku konieczności natychmiastowego dostępu do najnowszego wydania lub wtyczki DNS dystrybuowanej wyłącznie jako snap. Należy wybrać tylko jedną metodę: dwie instalacje oznaczają dwa timery odnawiania wskazujące na to samo drzewo /etc/letsencrypt, co prowadzi do problemów z zapomnianą instancją.
Czy Certbot może wydać certyfikat typu wildcard dla nginx?
Tylko poprzez DNS-01. Certyfikat wildcard, taki jak *.example.com, nie posiada pojedynczej nazwy hosta, z której można pobrać plik wyzwania, dlatego metody --nginx, --webroot oraz --standalone nie mają zastosowania. Należy zainstalować wtyczkę dla dostawcy DNS, umieścić ograniczony token API w pliku z uprawnieniami dostępnymi tylko dla root i uruchomić certbot certonly --dns-cloudflare -d example.com -d '*.example.com', ujmując wildcard w cudzysłów, aby zapobiec jego interpretacji przez powłokę.
Dlaczego nginx nadal serwuje stary certyfikat po udanym odnowieniu?
nginx przechowuje certyfikat w pamięci i nie wykrywa zmiany pliku na dysku, dopóki nie zostanie przeładowany. certbot --nginx wykonuje przeładowanie automatycznie, jednak --webroot oraz uruchomienia --standalone tego nie robią. W efekcie odnowienie może zakończyć się sukcesem, podczas gdy przeglądarka nadal widzi wygasający certyfikat. Należy umieścić wykonywalny skrypt w /etc/letsencrypt/renewal-hooks/deploy/, który uruchamia nginx -t && systemctl reload nginx; zostanie on wywołany po każdym udanym odnowieniu.
Czy certbot renew --dry-run gwarantuje, że odnawianie będzie działać?
W większości przypadków. Polecenie to uruchamia rzeczywiste wyzwanie w środowisku testowym (staging), wykorzystując tę samą konfigurację firewalla, DNS i ścieżkę kodu, bez naruszania limitów produkcyjnych i bez zapisywania certyfikatów na dysku. Pomyślny wynik oznacza, że warstwa sieciowa jest poprawna. Nie potwierdza to jednak niezawodnie działania skryptu wdrażającego (deploy hook). Należy przetestować go oddzielnie: uruchomić skrypt ręcznie i sprawdzić sudo grep renew_hook /etc/letsencrypt/renewal/example.com.conf.