Cauza ERR_CERT_DATE_INVALID pe roa-qr.romfast.ro: renewal-ul win-acme avea Installation plugin "None" in loc de IIS -> certul se reinnoia in store dar binding-ul SNI ramanea pe certul vechi (expirat 31 mai). - monitor-ssl-certificates.sh: adaugat roa-qr.romfast.ro (Site ID 5); normalizat CRLF->LF (CRLF dadea exit 127 la exec pe Linux) - docs: box incident 2026-06-25 cu cauza-radacina + diagnostic per renewal Fix aplicat pe VM 201: plugin install None->IIS in renewal.json + force renew (cert nou valid pana 23 sep 2026, binding auto-actualizat). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
12 KiB
Certificat Let's Encrypt pentru IIS - Ghid Rapid
Instalare Win-ACME
# Download și instalare
Invoke-WebRequest -Uri "https://github.com/win-acme/win-acme/releases/download/v2.2.9.1701/win-acme.v2.2.9.1701.x64.pluggable.zip" -OutFile "$env:TEMP\win-acme.zip"
Expand-Archive -Path "$env:TEMP\win-acme.zip" -DestinationPath "C:\Tools\win-acme" -Force
Prerequisite IIS
Verificare Site ID-uri
Import-Module WebAdministration
Get-Website | Select-Object ID, Name, State, @{N='Bindings';E={$_.Bindings.Collection.bindingInformation}}
Adaugă Binding-uri pentru Domeniu
# Exemplu pentru roa.romfast.ro pe Default Web Site
New-WebBinding -Name "Default Web Site" -Protocol http -Port 80 -HostHeader "roa.romfast.ro"
New-WebBinding -Name "Default Web Site" -Protocol https -Port 443 -HostHeader "roa.romfast.ro"
Generare Certificate
Metoda 1: Comenzi PowerShell (Automat)
cd C:\Tools\win-acme
# Pentru fiecare site (înlocuiește Site ID și email)
.\wacs.exe --source iis --siteid 1 --accepttos --emailaddress your@email.com
.\wacs.exe --source iis --siteid 2 --accepttos --emailaddress your@email.com
.\wacs.exe --source iis --siteid 3 --accepttos --emailaddress your@email.com
Metoda 2: Mod Interactiv
cd C:\Tools\win-acme
.\wacs.exe
# În meniu:
# N - Create certificate (simple for IIS)
# Selectează site-ul
# Confirmă binding-urile
# yes - Accept ToS
# Enter email
Configurare Binding-uri IIS cu SNI
Important: SNI OBLIGATORIU pentru Multiple Certificate pe Același IP
GUI - IIS Manager:
- Deschide IIS Manager (
inetmgr) - Pentru fiecare site:
- Site → Bindings → Selectează https → Edit
- ☑️ Bifează "Require Server Name Indication"
- Selectează certificatul corect pentru site
- OK
- Restart IIS:
iisreset
PowerShell:
Import-Module WebAdministration
# Exemplu pentru un site
$siteName = "Dokploy"
$hostHeader = "dokploy.romfast.ro"
# Găsește certificatul
$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object {
$_.Subject -like "*$hostHeader*" -and $_.NotAfter -gt (Get-Date).AddDays(60)
} | Select-Object -First 1
# Șterge binding vechi și creează cu SNI (SslFlags = 1)
Remove-WebBinding -Name $siteName -Protocol https -HostHeader $hostHeader -ErrorAction SilentlyContinue
New-WebBinding -Name $siteName -Protocol https -Port 443 -HostHeader $hostHeader -SslFlags 1
# Asociază certificatul
$binding = Get-WebBinding -Name $siteName -Protocol https -HostHeader $hostHeader
$binding.AddSslCertificate($cert.Thumbprint, "My")
# Restart IIS
iisreset
Verificare
Listare Certificate Gestionate
cd C:\Tools\win-acme
.\wacs.exe --list
Verificare Certificate în Browser
# Din WSL sau Linux
echo | openssl s_client -connect domain.ro:443 -servername domain.ro 2>/dev/null | openssl x509 -noout -dates -subject
Verificare Task Scheduler
Get-ScheduledTask | Where-Object {$_.TaskName -like "*acme*"}
Verificare Certificate IIS
Get-ChildItem Cert:\LocalMachine\My | Where-Object {
$_.Issuer -like "*Let's Encrypt*" -and $_.NotAfter -gt (Get-Date)
} | Select-Object Subject, NotAfter, Thumbprint
Reînnoire
Automată
- Task Scheduler verifică zilnic
- Reînnoiește automat cu 30 zile înainte de expirare
Manuală
cd C:\Tools\win-acme
.\wacs.exe --renew --force
iisreset
Troubleshooting
Certificat Vechi Încă Servit
# Verifică SNI
Get-WebBinding | Where-Object {$_.Protocol -eq "https"} | Select-Object @{N='Site';E={$_.ItemXPath -replace '.*name=''([^'']+)''.*','$1'}}, bindingInformation, @{N='SNI';E={($_.sslFlags -band 1) -eq 1}}
# Forțează reinstalare
cd C:\Tools\win-acme
.\wacs.exe --renew --force
iisreset
Validare HTTP-01 Eșuează
- Verifică că portul 80 este accesibil din internet
- Verifică că DNS pointează corect
- Verifică că URL Rewrite nu blochează
/.well-known/acme-challenge/*
Certificate Nu Se Asociază Automat
Folosește scriptul: configure-iis-sni.ps1
Structură Site-uri IIS
| Site ID | Nume | Hostname | Binding HTTPS | SNI |
|---|---|---|---|---|
| 1 | Default Web Site | roa.romfast.ro | *:443:roa.romfast.ro | ☑️ Activ |
| 2 | Dokploy | dokploy.romfast.ro | *:443:dokploy.romfast.ro | ☑️ Activ |
| 3 | Gitea | gitea.romfast.ro | *:443:gitea.romfast.ro | ☑️ Activ |
Scripturi Utile
Script Verificare/Reînnoire Certificate (PowerShell)
Locație repo: ../scripts/check-ssl-certificates.ps1
Locație VM 201: D:\kit\ssl\check-ssl-certificates.ps1
# Verificare manuală
D:\kit\ssl\check-ssl-certificates.ps1 -Verbose
# Forțare reinstalare toate certificatele
D:\kit\ssl\check-ssl-certificates.ps1 -Force -Verbose
Script Monitorizare Certificate (Bash - Proxmox)
Locație repo: ../scripts/monitor-ssl-certificates.sh
Locație Proxmox: /opt/scripts/monitor-ssl-certificates.sh
# Verificare manuală
/opt/scripts/monitor-ssl-certificates.sh
# Verificare log
tail -50 /var/log/ssl-monitor.log
Comenzi Rapide
# Instalare
Expand-Archive win-acme.zip -DestinationPath C:\Tools\win-acme
# Generare certificate
cd C:\Tools\win-acme
.\wacs.exe --source iis --siteid X --accepttos --emailaddress email@domain.com
# Verificare
.\wacs.exe --list
# Reînnoire
.\wacs.exe --renew --force
# Restart IIS
iisreset
Monitorizare Automată Certificate
Problema Cunoscută
Win-acme poate reînnoi certificatele, dar IIS uneori nu aplică noile certificate pe binding-uri. Acest lucru cauzează servirea certificatelor expirate chiar dacă cele noi sunt în Certificate Store.
Incident 2026-06-25 —
roa-qr.romfast.roservea cert expirat (31 mai). Cauza-rădăcină: renewal-ulroa-qrfusese creat cu Installation plugin =None(aecc502c-5f75-43d2-b578-f95d50c79ea1) în loc de IIS (ea6a5be3-f8de-4d27-a6bd-750b619b2ee2). Win-acme reînnoia certul și-l punea în store (27 apr, 21 iun), dar nu reactualiza niciodată binding-ul SNI → binding-ul a rămas blocat pe certul din 2 mar, care a expirat pe 31 mai. (wacs --listarătaroa-qr ... 1 error.) Site-urile 1–4 erau OK pentru că au plugin-ul IIS.Fix aplicat: în
…\Renewals\<id>.renewal.json(roa-qr =kfRYWLrEAkSk_-XRqoobEQ) am schimbat GUID-ul dinInstallationPluginOptionspe cel de IIS, apoiwacs.exe --renew --id <id> --force→ certul nou s-a legat automat pe binding (dovada că auto-renew-ul viitor funcționează). Backup:<id>.renewal.json.bak-20260625.Diagnostic (ce plugin de install are fiecare renewal):
$dir = "C:\ProgramData\win-acme\acme-v02.api.letsencrypt.org" Get-ChildItem $dir -Filter "*.renewal.json" | ForEach-Object { $j = Get-Content $_.FullName -Raw | ConvertFrom-Json "{0,-40} install={1}" -f $j.LastFriendlyName, $j.InstallationPluginOptions[0].Plugin } # ea6a5be3-... = IIS (corect) ; aecc502c-... = None (NU re-leagă binding-ul)
Soluția: Scripturi de Monitorizare
1. Script PowerShell pe VM 201
Locație: D:\kit\ssl\check-ssl-certificates.ps1
Task Scheduler: "SSL Certificate Check" - rulează zilnic la 07:00
# Verificare manuală
D:\kit\ssl\check-ssl-certificates.ps1 -Verbose
# Forțare reinstalare toate certificatele
D:\kit\ssl\check-ssl-certificates.ps1 -Force -Verbose
2. Script Bash pe Proxmox (pvemini)
Locație: /opt/scripts/monitor-ssl-certificates.sh
Cron: Zilnic la 08:00
# Verificare manuală
/opt/scripts/monitor-ssl-certificates.sh
# Verificare log
tail -50 /var/log/ssl-monitor.log
Ce Fac Scripturile
- Verifică zilele rămase pentru fiecare certificat
- Dacă < 14 zile: forțează reinstalare cu
wacs.exe --force - Restart IIS după reinstalare
- Trimite alertă email dacă există probleme
Verificare Task Schedulers
# Pe VM 201
Get-ScheduledTask | Where-Object {$_.TaskName -like "*SSL*" -or $_.TaskName -like "*acme*"}
# Pe Proxmox
grep ssl /etc/crontab
Wildcard *.roa.romfast.ro — Reînnoire Automată DNS-01 (cPanel)
Incident 2026-05-31: wildcardul a expirat. Renewal-ul win-acme era de tip
[Manual](DNS-01 cu TXT pus de mână) → nu rula din Scheduled Task → ~60 de erori consecutive → expirare. Subdomeniile Dokploy (efactura.roa…,space.roa…) dădeauERR_CERT_DATE_INVALID. Monitorizarea nu prindea pentru că*.roanu era în lista de domenii verificate (era doarroa.romfast.ro, un cert separat).
Wildcardul nu poate folosi HTTP-01 (ca site-urile 1–6); necesită DNS-01.
DNS-ul romfast.ro e pe hosting.com (cPanel), fără plugin nativ în win-acme,
deci folosim hook-ul de script cpanel-acme-dns.ps1 care pune/șterge TXT-ul prin
cPanel API.
Setup (o singură dată, pe VM 201 ca Administrator)
- cPanel → Manage API Tokens → creează token cu drept de editare DNS.
- Copiază pe VM 201:
scripts/cpanel-acme-dns.ps1→C:\Tools\win-acme\cpanel-acme-dns.ps1scripts/cpanel-dns.config.example.json→C:\Tools\win-acme\cpanel-dns.config.jsonși completeazăHostname,User,ApiToken. Nu commite fișierul real (e în.gitignore).
- Test manual:
cd C:\Tools\win-acme .\cpanel-acme-dns.ps1 create _acme-challenge.roa.romfast.ro testvalue123 # verifică TXT-ul în cPanel Zone Editor, apoi: .\cpanel-acme-dns.ps1 delete _acme-challenge.roa.romfast.ro testvalue123 - Recreează renewal-ul wildcard:
.\wacs.exe (ca Administrator) M → Create renewal (full options) Source: Manual → *.roa.romfast.ro Validation: dns-01 → "Create verification records with your own script" Run create: Powershell.exe -File C:\Tools\win-acme\cpanel-acme-dns.ps1 Create args : create {RecordName} {Token} Run delete: Powershell.exe -File C:\Tools\win-acme\cpanel-acme-dns.ps1 Delete args : delete {RecordName} {Token} Store: Windows Certificate Store (My) Installation: IIS → site "roa-apps" (re-leagă certul automat pe binding) - Confirmă Scheduled task (rulând
wacs.execa admin) → reînnoire 100% automată.
Verificare
echo | openssl s_client -connect efactura.roa.romfast.ro:443 \
-servername efactura.roa.romfast.ro 2>/dev/null | openssl x509 -noout -dates
Monitorizare
monitor-ssl-certificates.sh include acum efactura.roa.romfast.ro ca sentinel
pentru wildcard (Site ID WILDCARD). Dacă expiră, scriptul alertează (nu mai
încearcă auto-renew prin guest-exec, care e dezactivat) → intervenție pe VM 201.
Securitate: tokenul cPanel ajunge pe VM 201. Dă-i drepturi cât mai granulare (doar DNS). Dacă panoul e vechi și expune doar API2 ZoneEdit, setează
"LegacyZoneEdit": trueîn config.
Note Importante
- SNI este OBLIGATORIU pentru multiple certificate pe același IP:port
- Certificatele expiră la 90 zile
- Task Scheduler reînnoiește automat cu 30 zile înainte
- Fiecare domeniu trebuie să fie accesibil pe port 80 din internet pentru validare HTTP-01
- DNS trebuie să pointeze corect către IP-ul public
- Monitorizarea duală (Windows + Proxmox) asigură redundanță