Certbot + Nginx — SSL/TLS dla własnej domeny
Opublikowano: 9 kwietnia 2026 · Kategoria: Bezpieczeństwo
HTTP to dziś przeszłość — przeglądarki oznaczają niebezpieczne połączenia, Google obniża ranking niezaszyfrowanych stron, a użytkownicy po prostu nie ufają adresom bez kłódki. Certbot z Let's Encrypt daje darmowy, zaufany certyfikat SSL w 5 minut. Oto jak go skonfigurować na Nginx.
Instalacja Certbot
Zalecana metoda instalacji to snap — zapewnia zawsze aktualną wersję niezależnie od dystrybucji:
# Metoda 1: Snap (zalecana — Ubuntu 20.04+, Debian 11+) sudo snap install --classic certbot sudo ln -s /snap/bin/certbot /usr/bin/certbot # Metoda 2: APT (starsza, może nie mieć najnowszej wersji) sudo apt update sudo apt install certbot python3-certbot-nginx # Sprawdź wersję certbot --version
Konfiguracja Nginx przed Certbot
Certbot potrzebuje server_name w konfiguracji Nginx żeby wiedzieć dla której domeny wystawić certyfikat. Upewnij się że masz podstawowy vhost:
# /etc/nginx/sites-available/example.com
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
} # Aktywacja vhosta sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx
Uzyskanie certyfikatu SSL
# Automatyczna konfiguracja Nginx (certbot modyfikuje nginx.conf)
sudo certbot --nginx -d example.com -d www.example.com
# Tylko certyfikat — bez modyfikacji Nginx (ręczna konfiguracja)
sudo certbot certonly --nginx -d example.com -d www.example.com
# Tryb testowy (staging) — bez limitów, certyfikat nie jest zaufany
sudo certbot --nginx --staging -d example.com
# Nieinteraktywny (dla skryptów)
sudo certbot --nginx -d example.com --non-interactive \
--agree-tos --email [email protected] Po pomyślnym wykonaniu certbot automatycznie:
- Pobierze certyfikat do
/etc/letsencrypt/live/example.com/ - Zmodyfikuje konfigurację Nginx — doda blok
serverna porcie 443 - Doda redirect z HTTP na HTTPS
- Ustawi automatyczne odnawianie przez systemd timer
Konfiguracja Nginx po Certbot
Certbot generuje podstawową konfigurację, ale warto ją rozbudować o mocniejsze szyfry i nagłówki bezpieczeństwa:
# /etc/nginx/sites-available/example.com (po certbot)
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# Certyfikaty Let's Encrypt
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;
# Mocniejsza konfiguracja TLS
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# Nagłówki bezpieczeństwa
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
root /var/www/example.com/html;
location / {
try_files $uri $uri/ =404;
}
} Automatyczne odnawianie
# Sprawdź czy timer systemd jest aktywny sudo systemctl status snap.certbot.renew.timer # lub sudo systemctl status certbot.timer # Test odnowienia (dry-run — nie zmienia certyfikatu) sudo certbot renew --dry-run # Alternatywa: cron (jeśli timer nie działa) # Edytuj /etc/crontab lub crontab -e 0 3 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx" # Ręczne odnowienie sudo certbot renew # Wymuś odnowienie (nawet gdy certyfikat jest ważny) sudo certbot renew --force-renewal
Wildcard certyfikat z DNS challenge
Certyfikat wildcard (*.example.com) pokrywa wszystkie subdomeny. Wymaga
weryfikacji DNS — musisz dodać rekord TXT do swojej domeny:
# Ręczna weryfikacja DNS (certbot zatrzyma się i poczeka)
sudo certbot certonly --manual --preferred-challenges dns \
-d "*.example.com" -d "example.com"
# Certbot wyświetli komunikat:
# Please deploy a DNS TXT record under the name:
# _acme-challenge.example.com
# with the following value: aBcDeFgHiJ...
# Po dodaniu rekordu naciśnij Enter # Automatyczna DNS challenge przez plugin Cloudflare
pip install certbot-dns-cloudflare
# /root/.secrets/cloudflare.ini
# dns_cloudflare_api_token = TWÓJ_TOKEN
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
-d "*.example.com" -d "example.com" Troubleshooting
- Błąd 80/443 port zajęty — przed uzyskaniem certyfikatu upewnij się że Nginx
działa i port 80 jest dostępny z internetu. Sprawdź firewall:
ufw allow 80iufw allow 443. - Certyfikat nie odnawia się — sprawdź logi:
journalctl -u snap.certbot.renewlub/var/log/letsencrypt/letsencrypt.log. - Too many certificates — używaj
--stagingdo testów. Limity resetują się po 7 dniach. - Certyfikat wygasł mimo timera — sprawdź czy post-hook restartuje Nginx:
certbot renew --post-hook "nginx -s reload". - Sprawdź ważność certyfikatu —
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates