====== Verifica revoca ====== **Complessità:** Bassa \\ **Durata:** 30 minuti per il setup \\ **Obiettivo:** Garantire disponibilità CRL/OCSP Sorveglianza delle informazioni di revoca (CRL e OCSP) per una PKI funzionante. ---- ===== Architettura ===== flowchart LR subgraph CHECK["🔍 VERIFICA"] C1[Download CRL] C2[Parsing CRL] C3[Richiesta OCSP] end subgraph VALIDATE["✅ VALIDAZIONE"] V1[Firma OK?] V2[Non scaduta?] V3[Raggiungibile?] end subgraph ALERT["🚨 ALERT"] A1[CRL scaduta] A2[Timeout OCSP] A3[CDP non raggiungibile] end C1 --> V1 & V2 C3 --> V3 V1 -->|No| A1 V2 -->|No| A1 V3 -->|No| A2 style A1 fill:#ffebee style A2 fill:#ffebee ---- ===== Monitoraggio CRL ===== ==== Verificare stato CRL ==== #!/bin/bash # /usr/local/bin/check-crl.sh CRL_URLS=( "http://crl.example.com/intermediate.crl" "http://crl.example.com/root.crl" ) WARN_HOURS=72 # Avviso se < 3 giorni al prossimo aggiornamento CRIT_HOURS=24 # Critico se < 1 giorno al prossimo aggiornamento for url in "${CRL_URLS[@]}"; do echo "Verifica: $url" # Scaricare CRL crl_data=$(curl -sf --max-time 10 "$url") if [ $? -ne 0 ]; then echo "ERRORE: CRL non raggiungibile - $url" continue fi # Parsing CRL (DER o PEM) if [[ "$crl_data" == *"-----BEGIN"* ]]; then crl_info=$(echo "$crl_data" | openssl crl -text -noout) else crl_info=$(echo "$crl_data" | openssl crl -inform DER -text -noout) fi # Estrarre Next Update next_update=$(echo "$crl_info" | grep "Next Update" | sed 's/.*: //') next_epoch=$(date -d "$next_update" +%s) now_epoch=$(date +%s) hours_left=$(( (next_epoch - now_epoch) / 3600 )) # CRL Number crl_number=$(echo "$crl_info" | grep -A1 "CRL Number" | tail -1 | tr -d ' ') # Output stato if [ "$hours_left" -lt 0 ]; then echo "CRITICO: CRL scaduta! - $url" elif [ "$hours_left" -lt "$CRIT_HOURS" ]; then echo "CRITICO: CRL scade tra $hours_left ore - $url" elif [ "$hours_left" -lt "$WARN_HOURS" ]; then echo "AVVISO: CRL scade tra $hours_left ore - $url" else echo "OK: CRL valida per $hours_left ore - $url (CRL#: $crl_number)" fi # Numero certificati revocati revoked_count=$(echo "$crl_info" | grep -c "Serial Number:") echo " Revocati: $revoked_count certificati" echo "" done ==== Prometheus Exporter per CRL ==== #!/bin/bash # crl-exporter.sh - Genera metriche Prometheus METRICS_FILE="/var/lib/node_exporter/textfile_collector/crl.prom" cat /dev/null > "$METRICS_FILE" CRL_URLS=( "intermediate|http://crl.example.com/intermediate.crl" "root|http://crl.example.com/root.crl" ) for entry in "${CRL_URLS[@]}"; do IFS='|' read -r name url <<< "$entry" crl_data=$(curl -sf --max-time 10 "$url" 2>/dev/null) if [ $? -ne 0 ]; then echo "crl_reachable{name=\"$name\"} 0" >> "$METRICS_FILE" continue fi echo "crl_reachable{name=\"$name\"} 1" >> "$METRICS_FILE" next_update=$(echo "$crl_data" | openssl crl -inform DER -nextupdate -noout 2>/dev/null | cut -d= -f2) if [ -n "$next_update" ]; then next_epoch=$(date -d "$next_update" +%s) echo "crl_next_update_timestamp{name=\"$name\"} $next_epoch" >> "$METRICS_FILE" fi revoked=$(echo "$crl_data" | openssl crl -inform DER -text -noout 2>/dev/null | grep -c "Serial Number:") echo "crl_revoked_count{name=\"$name\"} $revoked" >> "$METRICS_FILE" done **Alert Rule:** - alert: CRLExpiringSoon expr: crl_next_update_timestamp - time() < 86400 labels: severity: critical annotations: summary: "CRL {{ $labels.name }} scade tra < 24h" - alert: CRLUnreachable expr: crl_reachable == 0 for: 5m labels: severity: critical annotations: summary: "CRL {{ $labels.name }} non raggiungibile" ---- ===== Monitoraggio OCSP ===== ==== Verificare OCSP Responder ==== #!/bin/bash # /usr/local/bin/check-ocsp.sh OCSP_URL="http://ocsp.example.com" ISSUER_CERT="/etc/pki/CA/intermediate-ca.pem" TEST_CERT="/etc/ssl/certs/test-server.pem" echo "OCSP Responder Check: $OCSP_URL" # Inviare richiesta OCSP start_time=$(date +%s%N) response=$(openssl ocsp \ -issuer "$ISSUER_CERT" \ -cert "$TEST_CERT" \ -url "$OCSP_URL" \ -resp_text 2>&1) end_time=$(date +%s%N) # Calcolare tempo di risposta (ms) response_time=$(( (end_time - start_time) / 1000000 )) # Estrarre stato if echo "$response" | grep -q "good"; then status="good" elif echo "$response" | grep -q "revoked"; then status="revoked" else status="error" fi # Output echo "Stato: $status" echo "Tempo risposta: ${response_time}ms" if [ "$status" = "error" ]; then echo "ERRORE: OCSP Responder non funzionante" exit 1 fi if [ "$response_time" -gt 2000 ]; then echo "AVVISO: Tempo risposta OCSP > 2s" fi ==== OCSP Prometheus Exporter ==== #!/bin/bash # ocsp-exporter.sh METRICS_FILE="/var/lib/node_exporter/textfile_collector/ocsp.prom" OCSP_ENDPOINTS=( "intermediate|http://ocsp.example.com|/etc/pki/CA/intermediate.pem|/etc/ssl/certs/test.pem" ) cat /dev/null > "$METRICS_FILE" for entry in "${OCSP_ENDPOINTS[@]}"; do IFS='|' read -r name url issuer cert <<< "$entry" start_time=$(date +%s%N) response=$(openssl ocsp -issuer "$issuer" -cert "$cert" -url "$url" -resp_text 2>&1) exit_code=$? end_time=$(date +%s%N) response_time=$(( (end_time - start_time) / 1000000 )) echo "ocsp_response_time_ms{name=\"$name\"} $response_time" >> "$METRICS_FILE" if [ $exit_code -eq 0 ]; then echo "ocsp_up{name=\"$name\"} 1" >> "$METRICS_FILE" else echo "ocsp_up{name=\"$name\"} 0" >> "$METRICS_FILE" fi if echo "$response" | grep -q "good"; then echo "ocsp_status{name=\"$name\"} 0" >> "$METRICS_FILE" # 0=good elif echo "$response" | grep -q "revoked"; then echo "ocsp_status{name=\"$name\"} 1" >> "$METRICS_FILE" # 1=revoked else echo "ocsp_status{name=\"$name\"} 2" >> "$METRICS_FILE" # 2=unknown/error fi done **Alert Rules:** - alert: OCSPResponderDown expr: ocsp_up == 0 for: 2m labels: severity: critical annotations: summary: "OCSP Responder {{ $labels.name }} non raggiungibile" - alert: OCSPResponseSlow expr: ocsp_response_time_ms > 2000 for: 5m labels: severity: warning annotations: summary: "OCSP {{ $labels.name }} lento: {{ $value }}ms" ---- ===== Blackbox Exporter ===== # blackbox.yml modules: tls_connect: prober: tcp timeout: 5s tcp: tls: true tls_config: insecure_skip_verify: false http_crl: prober: http timeout: 10s http: method: GET valid_status_codes: [200] fail_if_body_not_matches_regexp: ["-----BEGIN X509 CRL-----|^\x30"] ocsp_check: prober: http timeout: 5s http: method: POST headers: Content-Type: application/ocsp-request ---- ===== PowerShell (Windows) ===== # Check-Revocation.ps1 param( [string]$OcspUrl = "http://ocsp.example.com", [string]$CrlUrl = "http://crl.example.com/intermediate.crl" ) # Verificare CRL Write-Host "=== Verifica CRL ===" -ForegroundColor Cyan try { $crlResponse = Invoke-WebRequest -Uri $CrlUrl -TimeoutSec 10 Write-Host "CRL raggiungibile: OK ($($crlResponse.StatusCode))" -ForegroundColor Green # Parsing CRL (richiede strumenti aggiuntivi o .NET) $crlBytes = $crlResponse.Content # ... CRL-Parsing qui } catch { Write-Host "ERRORE CRL: $_" -ForegroundColor Red } # Verificare OCSP (semplificato via openssl) Write-Host "`n=== Verifica OCSP ===" -ForegroundColor Cyan try { $certPath = "C:\certs\test.pem" $issuerPath = "C:\certs\intermediate.pem" $ocspResult = & openssl ocsp -issuer $issuerPath -cert $certPath -url $OcspUrl -text 2>&1 if ($ocspResult -match "good") { Write-Host "Stato OCSP: GOOD" -ForegroundColor Green } elseif ($ocspResult -match "revoked") { Write-Host "Stato OCSP: REVOKED" -ForegroundColor Yellow } else { Write-Host "Stato OCSP: ERROR" -ForegroundColor Red } } catch { Write-Host "ERRORE OCSP: $_" -ForegroundColor Red } ---- ===== Checklist ===== | # | Punto di verifica | ✓ | |---|-------------------|---| | 1 | URL CRL definiti | ☐ | | 2 | Download CRL funzionante | ☐ | | 3 | Avviso scadenza CRL configurato | ☐ | | 4 | URL OCSP definito | ☐ | | 5 | Risposta OCSP funzionante | ☐ | | 6 | Prometheus Exporter attivo | ☐ | | 7 | Alert configurati | ☐ | ---- ===== Documentazione correlata ===== * [[..:tagesgeschaeft:zertifikat-widerrufen|Revocare certificato]] – Aggiornare CRL * [[.:ablauf-monitoring|Monitoraggio scadenze]] – Scadenza certificati * [[it:int:pqcrypt:szenarien:widerruf:start|Scenari revoca]] – Guide dettagliate ---- << [[.:ablauf-monitoring|← Monitoraggio scadenze]] | [[.:audit-logging|→ Audit logging]] >> ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional// {{tag>monitoring crl ocsp revocation operator}}