# 1. Restricționăm permisiunile pe fișierul cu token-ul Cloudflare
chmod 600 /etc/letsencrypt/cloudflare.ini
# 2. Generăm certificatul wildcard cu deploy-hook inclus
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
--dns-cloudflare-propagation-seconds 60 \
-d "domeniu.ro" \
-d "*.domeniu.ro" \
--deploy-hook "systemctl reload nginx"Am dat de problema asta acum doi ani la un proiect cu peste 50 de subdomenii de client, unde aveam nevoie neapărat de wildcard-uri. Să reînnoiești manual certificatele la fiecare 90 de zile introducând TXT record-uri în DNS e sinucidere curată. Cineva o să uite, iar site-ul o să pice exact duminică seara.
De ce ne lovim de DNS-01?
Dacă vrei un certificat wildcard (*.domeniu.ro), Let's Encrypt te obligă să folosești challenge-ul DNS-01. Nu merge cu clasicul fișier pus în .well-known/acme-challenge/ prin HTTP-01. Protocolul ACME trebuie să verifice că deții întreg domeniul de la nivel de DNS, iar singura cale e să scrii un record de tip TXT în zona ta DNS (_acme-challenge.domeniu.ro).
Asta înseamnă că serverul tău web, sau cel puțin mașina pe care rulează Certbot, are nevoie de acces API la providerul tău de DNS (Cloudflare, Route53, DigitalOcean etc.) pentru a adăuga și șterge acele înregistrări temporare.
Trade-off-ul de securitate pe care mulți îl ignoră
Aici apare marea problemă. Ca să automatizezi procesul, trebuie să lași o cheie API cu drepturi de scriere pe serverul de producție. Dacă cineva îți compromite serverul web, îți fură token-ul de Cloudflare și îți poate deturna tot traficul modificând IP-urile în DNS. E un risc major.
Cum am rezolvat-o noi? Nu folosi niciodată Global API Key. În Cloudflare, de exemplu, creezi un API Token extrem de limitat: doar drepturi de Zone:DNS:Edit pentru o singură zonă specifică (domeniul tău). Dacă acel token este expus, paguba e limitată la acel singur domeniu, nu la tot contul tău.
Configurarea fără dureri de cap
Pentru Nginx și Cloudflare, procesul e destul de curat dacă folosești pluginul dedicat de Certbot. Am instalat python3-certbot-dns-cloudflare și am creat un fișier de configurare securizat, accesibil doar de root (/etc/letsencrypt/cloudflare.ini) care conține token-ul.
După ce rulezi comanda de generare, Certbot își creează automat un job de systemd în spate care rulează de două ori pe zi și verifică dacă certificatul mai are mai puțin de 30 de zile. Dar simpla reînnoire pe disc nu rezolvă totul.
Capcana clasică: Nginx nu știe că ai certificat nou
Am pățit asta chiar la început. Certificatul se reînnoia pe disc, dar Nginx rula fericit cu cel vechi, încărcat în memorie. După 90 de zile, clienții primeau eroare de conexiune nesigură, deși pe server fișierele .pem erau proaspete.
Soluția este parametrul --deploy-hook. Acesta rulează o comandă doar atunci când certificatul a fost reînnoit cu succes. Un simplu systemctl reload nginx rezolvă problema fără nicio secundă de downtime pentru utilizatori, deoarece reload-ul în Nginx este graceful și nu închide conexiunile active.
Voi cum gestionați cheile de DNS pe servere? Le țineți pe aceeași mașină cu Nginx sau aveți o mașină separată de management care doar împinge certificatele prin Ansible?