====== Inventura certifikatov ====== **Kompleksnost:** Nizka \\ **Trajanje:** 1-4 ure (odvisno od velikosti) \\ **Predpogoj:** Dostop do vseh sistemov Popoln popis vseh certifikatov kot osnova za migracijo. ---- ===== Zakaj inventura? ===== | Razlog | Opis | |--------|------| | **Obseg** | Koliko certifikatov je treba migrirati? | | **Algoritmi** | Kateri algoritmi so v uporabi? | | **Datumi izteka** | Kdaj lahko certifikate migriramo ob obnovi? | | **Odvisnosti** | Kateri sistemi so medsebojno povezani? | | **Tveganja** | Kje so kritični certifikati? | ---- ===== Viri inventure ===== flowchart TB subgraph LOCAL["LOKALNO"] L1[Datotečni sistem] L2[Shrambe certifikatov] L3[Konfiguracijske datoteke] end subgraph NETWORK["OMREŽJE"] N1[TLS končne točke] N2[LDAP/AD] N3[HSM] end subgraph MGMT["UPRAVLJANJE"] M1[CA baza podatkov] M2[CMDB] M3[Nadzor] end subgraph OUTPUT["IZHOD"] O[Inventura-CSV] end L1 & L2 & L3 --> O N1 & N2 & N3 --> O M1 & M2 & M3 --> O ---- ===== Linux: Pregled datotečnega sistema ===== #!/bin/bash # cert-inventory-linux.sh OUTPUT="inventory-linux-$(hostname)-$(date +%Y%m%d).csv" echo "Pot,Subject,Issuer,Algoritem,Dolzina_kljuca,Veljavno_od,Veljavno_do,Dni_preostalo,Serial,SAN" > "$OUTPUT" # Standardni imeniki CERT_DIRS=( "/etc/ssl/certs" "/etc/pki/tls/certs" "/etc/nginx/ssl" "/etc/apache2/ssl" "/opt/*/ssl" "/var/lib/docker/volumes/*/ssl" ) for dir in "${CERT_DIRS[@]}"; do for cert in $(find $dir -name "*.pem" -o -name "*.crt" -o -name "*.cer" 2>/dev/null); do # Samo certifikati (ne ključi/CSR) openssl x509 -in "$cert" -noout 2>/dev/null || continue subject=$(openssl x509 -in "$cert" -subject -noout | sed 's/subject=//' | tr ',' ';') issuer=$(openssl x509 -in "$cert" -issuer -noout | sed 's/issuer=//' | tr ',' ';') algo=$(openssl x509 -in "$cert" -text -noout | grep "Signature Algorithm" | head -1 | awk '{print $3}') keysize=$(openssl x509 -in "$cert" -text -noout | grep "Public-Key:" | grep -oP '\d+') not_before=$(openssl x509 -in "$cert" -startdate -noout | cut -d= -f2) not_after=$(openssl x509 -in "$cert" -enddate -noout | cut -d= -f2) days_left=$(( ($(date -d "$not_after" +%s) - $(date +%s)) / 86400 )) serial=$(openssl x509 -in "$cert" -serial -noout | cut -d= -f2) sans=$(openssl x509 -in "$cert" -text -noout | grep -A1 "Subject Alternative Name" | tail -1 | tr ',' ';') echo "\"$cert\",\"$subject\",\"$issuer\",\"$algo\",\"$keysize\",\"$not_before\",\"$not_after\",\"$days_left\",\"$serial\",\"$sans\"" >> "$OUTPUT" done done echo "Inventura končana: $OUTPUT" echo "Najdenih certifikatov: $(tail -n +2 "$OUTPUT" | wc -l)" ---- ===== Windows: Pregled shrambe certifikatov ===== # Cert-Inventory-Windows.ps1 param( [string]$OutputPath = "inventory-windows-$env:COMPUTERNAME-$(Get-Date -Format 'yyyyMMdd').csv" ) $results = @() # Pregled vseh shrambenih mest certifikatov $stores = @( @{ Location = "LocalMachine"; Name = "My" }, @{ Location = "LocalMachine"; Name = "Root" }, @{ Location = "LocalMachine"; Name = "CA" }, @{ Location = "LocalMachine"; Name = "WebHosting" }, @{ Location = "CurrentUser"; Name = "My" } ) foreach ($store in $stores) { $storePath = "Cert:\$($store.Location)\$($store.Name)" Get-ChildItem $storePath -ErrorAction SilentlyContinue | ForEach-Object { $cert = $_ $daysLeft = ($cert.NotAfter - (Get-Date)).Days # Ekstrakcija SAN $sanExt = $cert.Extensions | Where-Object { $_.Oid.Value -eq "2.5.29.17" } $sans = if ($sanExt) { $sanExt.Format($false) } else { "" } $results += [PSCustomObject]@{ Store = "$($store.Location)\$($store.Name)" Subject = $cert.Subject Issuer = $cert.Issuer Algorithm = $cert.SignatureAlgorithm.FriendlyName KeySize = $cert.PublicKey.Key.KeySize NotBefore = $cert.NotBefore NotAfter = $cert.NotAfter DaysLeft = $daysLeft Serial = $cert.SerialNumber Thumbprint = $cert.Thumbprint SANs = $sans HasPrivateKey = $cert.HasPrivateKey } } } $results | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8 Write-Host "Inventura končana: $OutputPath" Write-Host "Najdenih certifikatov: $($results.Count)" ---- ===== Omrežje: Pregled TLS končnih točk ===== #!/bin/bash # cert-inventory-network.sh OUTPUT="inventory-network-$(date +%Y%m%d).csv" ENDPOINTS_FILE="endpoints.txt" echo "Koncna_tocka,Subject,Issuer,Algoritem,Dolzina_kljuca,Veljavno_do,Dni,Serial" > "$OUTPUT" # Končne točke iz datoteke ali CMDB/DNS # Format: hostname:port cat "$ENDPOINTS_FILE" | while read endpoint; do host=${endpoint%:*} port=${endpoint#*:} [ -z "$port" ] && port=443 echo "Preglejujem $host:$port..." cert_info=$(echo | openssl s_client -connect "$host:$port" -servername "$host" 2>/dev/null | openssl x509 -text -noout 2>/dev/null) if [ -n "$cert_info" ]; then subject=$(echo "$cert_info" | grep "Subject:" | head -1 | sed 's/.*Subject: //' | tr ',' ';') issuer=$(echo "$cert_info" | grep "Issuer:" | head -1 | sed 's/.*Issuer: //' | tr ',' ';') algo=$(echo "$cert_info" | grep "Signature Algorithm" | head -1 | awk '{print $3}') keysize=$(echo "$cert_info" | grep "Public-Key:" | grep -oP '\d+') not_after=$(echo | openssl s_client -connect "$host:$port" -servername "$host" 2>/dev/null | openssl x509 -enddate -noout | cut -d= -f2) days_left=$(( ($(date -d "$not_after" +%s) - $(date +%s)) / 86400 )) serial=$(echo | openssl s_client -connect "$host:$port" -servername "$host" 2>/dev/null | openssl x509 -serial -noout | cut -d= -f2) echo "\"$endpoint\",\"$subject\",\"$issuer\",\"$algo\",\"$keysize\",\"$not_after\",\"$days_left\",\"$serial\"" >> "$OUTPUT" else echo "\"$endpoint\",\"POVEZAVA NEUSPEŠNA\",\"\",\"\",\"\",\"\",\"\",\"\"" >> "$OUTPUT" fi done echo "Omrežna inventura končana: $OUTPUT" ---- ===== Inventura CA baze podatkov ===== #!/bin/bash # cert-inventory-ca.sh - Iz OpenSSL CA indeksa CA_INDEX="/etc/pki/CA/index.txt" OUTPUT="inventory-ca-$(date +%Y%m%d).csv" echo "Status,Serial,Iztece,Subject,Datoteka" > "$OUTPUT" while IFS=$'\t' read -r status expiry revoke serial unknown subject; do # Status: V=Veljaven, R=Preklican, E=Potekel status_text="" case "$status" in V) status_text="Veljaven" ;; R) status_text="Preklican" ;; E) status_text="Potekel" ;; esac # Pretvorba datuma izteka (format YYMMDDHHMMSSZ) expiry_formatted=$(date -d "20${expiry:0:2}-${expiry:2:2}-${expiry:4:2}" +%Y-%m-%d 2>/dev/null) # Datoteka certifikata cert_file="/etc/pki/CA/newcerts/${serial}.pem" echo "\"$status_text\",\"$serial\",\"$expiry_formatted\",\"$subject\",\"$cert_file\"" >> "$OUTPUT" done < "$CA_INDEX" echo "CA inventura končana: $OUTPUT" echo "Certifikati:" echo " Veljavni: $(grep -c "^\"Veljaven\"" "$OUTPUT")" echo " Preklicani: $(grep -c "^\"Preklican\"" "$OUTPUT")" echo " Potekli: $(grep -c "^\"Potekel\"" "$OUTPUT")" ---- ===== Analiza in poročanje ===== #!/usr/bin/env python3 # analyze-inventory.py import pandas as pd from datetime import datetime # Nalaganje vseh inventurnih datotek df = pd.concat([ pd.read_csv('inventory-linux*.csv'), pd.read_csv('inventory-windows*.csv'), pd.read_csv('inventory-network*.csv') ]) # Analiza print("=== Povzetek inventure ===\n") print(f"Skupno število certifikatov: {len(df)}") print("\n--- Po algoritmu ---") print(df['Algoritem'].value_counts()) print("\n--- Po dolžini ključa ---") print(df['Dolzina_kljuca'].value_counts()) print("\n--- Analiza izteka ---") df['Dni_preostalo'] = pd.to_numeric(df['Dni_preostalo'], errors='coerce') print(f"Potekli: {len(df[df['Dni_preostalo'] < 0])}") print(f"< 30 dni: {len(df[(df['Dni_preostalo'] >= 0) & (df['Dni_preostalo'] < 30)])}") print(f"30-90 dni: {len(df[(df['Dni_preostalo'] >= 30) & (df['Dni_preostalo'] < 90)])}") print(f"90-365 dni: {len(df[(df['Dni_preostalo'] >= 90) & (df['Dni_preostalo'] < 365)])}") print(f"> 1 leto: {len(df[df['Dni_preostalo'] >= 365])}") print("\n--- Potencial migracije ---") rsa = len(df[df['Algoritem'].str.contains('rsa', case=False, na=False)]) ecdsa = len(df[df['Algoritem'].str.contains('ecdsa|ec', case=False, na=False)]) hybrid = len(df[df['Algoritem'].str.contains('ml-dsa|hybrid', case=False, na=False)]) print(f"RSA (za migracijo): {rsa}") print(f"ECDSA (za migracijo): {ecdsa}") print(f"Hibridno (že): {hybrid}") # Izvoz za načrtovanje migracije df.to_excel('inventory-complete.xlsx', index=False) print("\nPolna inventura izvožena: inventory-complete.xlsx") ---- ===== Predloga nadzorne plošče ===== | Kategorija | Število | Migracija | |------------|---------|-----------| | **Algoritem** | | | | RSA-2048 | 150 | → Hibridno | | RSA-4096 | 30 | → Hibridno | | ECDSA P-256 | 80 | → Hibridno | | ECDSA P-384 | 20 | → Hibridno | | ML-DSA/Hibridno | 5 | Končano | | **Iztece** | | | | < 30 dni | 12 | Takoj migrirati | | 30-90 dni | 25 | Faza 1 | | 90-365 dni | 100 | Faza 2 | | > 1 leto | 148 | Faza 3 | | **Kritičnost** | | | | Zunanji | 40 | Prioriteta 1 | | Notranji kritični | 80 | Prioriteta 2 | | Razvoj | 165 | Prioriteta 3 | ---- ===== Kontrolni seznam ===== | # | Kontrolna točka | | |---|-----------------|---| | 1 | Vsi Linux strežniki pregledani | | | 2 | Vsi Windows strežniki pregledani | | | 3 | Vse TLS končne točke pregledane | | | 4 | CA baza podatkov izvožena | | | 5 | Podatki konsolidirani | | | 6 | Analiza izvedena | | | 7 | Načrt migracije ustvarjen | | ---- ===== Povezana dokumentacija ===== * [[.:classic-to-hybrid|Klasično → Hibridno]] – Začetek migracije * [[..:monitoring:ablauf-monitoring|Nadzor veljavnosti]] – Tekoče spremljanje * [[sl:int:pqcrypt:business:start|Poslovno]] – Strateško načrtovanje ---- << [[.:rollback-strategie|← Strategija povrnitve]] | [[..:start|→ Scenariji za operaterje]] >> ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional// {{tag>inventur bestandsaufnahme migration analyse operator}}