Files
ROMFASTSQL/proxmox/vm201-windows/docs/vm201-certificat-letsencrypt-iis.md
Claude Agent a41e9d81cf feat(vm201): wildcard *.roa auto-renew via cPanel DNS-01 hook
Fix expirare cert wildcard *.roa.romfast.ro (incident 2026-05-31):
renewal-ul era [Manual] DNS-01, nu rula din Scheduled Task -> 61 erori
-> expirat. Subdomeniile Dokploy (efactura.roa etc.) dadeau
ERR_CERT_DATE_INVALID.

- cpanel-acme-dns.ps1: hook win-ACME DNS-01 (cPanel UAPI mass_edit_zone,
  fallback ZoneEdit) care pune/sterge TXT _acme-challenge automat
- cpanel-dns.config.example.json: template (token-ul real e gitignored)
- monitor-ssl-certificates.sh: sentinel efactura.roa (wildcard) + alerta
  in loc de auto-renew prin guest-exec (dezactivat)
- README + doc cert: flux DNS-01 cPanel + acces OpenSSH VM 201

Renewal nou roa-wildcard-cpanel, auto, due 2026-08-19; vechiul [Manual]
anulat. Cert live valid pana 2026-09-23.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 13:23:54 +00:00

320 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Certificat Let's Encrypt pentru IIS - Ghid Rapid
## Instalare Win-ACME
```powershell
# 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
```powershell
Import-Module WebAdministration
Get-Website | Select-Object ID, Name, State, @{N='Bindings';E={$_.Bindings.Collection.bindingInformation}}
```
### Adaugă Binding-uri pentru Domeniu
```powershell
# 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)
```powershell
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
```powershell
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:**
1. Deschide IIS Manager (`inetmgr`)
2. Pentru fiecare site:
- Site → **Bindings** → Selectează **https****Edit**
- ☑️ **Bifează "Require Server Name Indication"**
- Selectează **certificatul corect** pentru site
- **OK**
3. Restart IIS: `iisreset`
**PowerShell:**
```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
```powershell
cd C:\Tools\win-acme
.\wacs.exe --list
```
### Verificare Certificate în Browser
```bash
# 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
```powershell
Get-ScheduledTask | Where-Object {$_.TaskName -like "*acme*"}
```
### Verificare Certificate IIS
```powershell
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ă
```powershell
cd C:\Tools\win-acme
.\wacs.exe --renew --force
iisreset
```
## Troubleshooting
### Certificat Vechi Încă Servit
```powershell
# 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`
```powershell
# 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`
```bash
# Verificare manuală
/opt/scripts/monitor-ssl-certificates.sh
# Verificare log
tail -50 /var/log/ssl-monitor.log
```
## Comenzi Rapide
```powershell
# 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.
### 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
```powershell
# 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
```bash
# 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
```powershell
# Pe VM 201
Get-ScheduledTask | Where-Object {$_.TaskName -like "*SSL*" -or $_.TaskName -like "*acme*"}
```
```bash
# 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ădeau `ERR_CERT_DATE_INVALID`. Monitorizarea nu prindea pentru că `*.roa` nu era
> în lista de domenii verificate (era doar `roa.romfast.ro`, un cert separat).
Wildcardul **nu** poate folosi HTTP-01 (ca site-urile 16); 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)
1. cPanel **Manage API Tokens** creează token cu drept de editare DNS.
2. Copiază pe VM 201:
- `scripts/cpanel-acme-dns.ps1` `C:\Tools\win-acme\cpanel-acme-dns.ps1`
- `scripts/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`).
3. Test manual:
```powershell
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
```
4. 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)
```
5. Confirmă Scheduled task (rulând `wacs.exe` ca admin) → reînnoire 100% automată.
### Verificare
```bash
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 fie **accesibil pe port 80** din internet pentru validare HTTP-01
- DNS trebuie pointeze corect către IP-ul public
- **Monitorizarea duală** (Windows + Proxmox) asigură redundanță