Monitoraggio della data di scadenza del certificato in Windows su NetXMS

Recentemente ci siamo trovati di fronte al compito di monitorare il periodo di validità dei certificati sui server Windows. Ebbene, come mi sono alzato dopo che i certificati si sono trasformati più volte in una zucca, proprio nel momento in cui il collega barbuto responsabile del loro rinnovo era in vacanza. Dopodiché, lui ed io sospettammo qualcosa e decidemmo di pensarci. Poiché stiamo lentamente implementando il sistema di monitoraggio NetXMS, è diventato il principale e, in linea di principio, l'unico candidato per questo compito.

Il risultato è stato infine ottenuto nella seguente forma:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

E il processo stesso continua.

Andare. Non esiste un contatore integrato per la scadenza dei certificati in NetXMS, quindi è necessario crearne uno proprio e utilizzare gli script per fornirgli i dati. Naturalmente, su Powershell, questo è Windows. Lo script dovrebbe leggere tutti i certificati nel sistema operativo, prendere la loro data di scadenza in giorni e passare questo numero a NetXMS. Tramite il suo agente. È da lì che inizieremo.

Opzione uno, più semplice. Ottieni semplicemente il numero di giorni fino alla data di scadenza del certificato con la data più vicina.

Affinché il server NetXMS possa conoscere l'esistenza del nostro parametro personalizzato, deve riceverlo dall'agente. Altrimenti questo parametro non può essere aggiunto a causa della sua assenza. Pertanto, nel file di configurazione dell'agente nxagentd.conf aggiungiamo una stringa di parametri esterni chiamata HTTPS.CertificateExpireDateSimple, in cui registriamo il lancio dello script:

ExternalParameter = HTTPS.CertificateExpireDateSimple: powershell.exe -File "servershareNetXMS_CertExpireDateSimple.ps1"

Considerando che lo script viene lanciato sulla rete, è necessario ricordarlo Politica di esecuzione, e non dimenticare l'altro "-NoLogo -NoProfile -NonInteractive", che ho omesso per una migliore leggibilità del codice.

Di conseguenza, la configurazione dell'agente è simile alla seguente:

#
# NetXMS agent configuration file
# Created by agent installer at Thu Jun 13 11:24:43 2019
#
 
MasterServers = netxms.corp.testcompany.ru
ConfigIncludeDir = C:NetXMSetcnxagentd.conf.d
LogFile = {syslog}
FileStore = C:NetXMSvar
SubAgent = ecs.nsm
SubAgent = filemgr.nsm
SubAgent = ping.nsm
SubAgent = logwatch.nsm
SubAgent = portcheck.nsm
SubAgent = winperf.nsm
SubAgent = wmi.nsm
 
ExternalParameter = HTTPS.CertificateExpireDateSimple: powershell.exe -File "servershareNetXMS_CertExpireDateSimple.ps1"

Successivamente, è necessario salvare la configurazione e riavviare l'agente. Puoi farlo dalla console NetXMS: apri il config (Modifica il file di configurazione dell'agente), modificalo, esegui Save&Apply, a seguito del quale, in effetti, accadrà la stessa cosa. Quindi rileggi la configurazione (Sondaggio > Configurazione), se non hai la forza di aspettare. Dopo questi passaggi, dovresti essere in grado di aggiungere il nostro parametro personalizzato.

Nella console NetXMS vai a Configurazione della raccolta dati server sperimentale su cui monitoreremo i certificati e creeremo lì un nuovo parametro (in futuro, dopo la configurazione, ha senso trasferirlo sui modelli). Seleziona HTTPS.CertificateExpireDateSimple dall'elenco, inserisci una Descrizione con un nome chiaro, imposta il tipo su Integer e configura l'intervallo di polling. Ai fini del debugging, è opportuno renderlo più breve, ad esempio 30 secondi. Tutto è pronto, per ora basta.

Puoi verificare... no, è troppo presto. Ora, ovviamente, non otterremo nulla. Semplicemente perché la sceneggiatura non è stata ancora scritta. Correggiamo questa omissione. Lo script visualizzerà semplicemente un numero, il numero di giorni rimanenti fino alla scadenza del certificato. Il più minimale tra tutti quelli disponibili. Script di esempio:

try {
    # Получаем все сертификаты из хранилища сертификатов
    $lmCertificates = @( Get-ChildItem -Recurse -path 'Cert:LocalMachineMy' -ErrorAction Stop )
     
    # Если сертификатов нет, вернуть "10 лет"
    if ($lmCertificates.Count -eq 0) { return 3650 }
 
    # Получаем Expiration Date всех сертификатов
    $expirationDates = @( $lmCertificates | ForEach-Object { return $_.NotAfter } )
 
    # Получаем наиболее близкий Expiration Date из всех
    $minExpirationDate = ($expirationDates | Measure-Object -Minimum -ErrorAction Stop ).Minimum
 
    # Конвертируем наиболее близкий Expiration Date в количество оставшихся дней с округлением в меньшую сторону
    $daysLeft = [Math]::Floor( ($minExpirationDate - [DateTime]::Now).TotalDays )
 
    # Возвращаем значение
    return $daysLeft
}
catch {
    return -1
}

Si scopre così:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

Mancano 723 giorni, quasi due anni alla scadenza del certificato. È logico, perché di recente ho emesso nuovamente i certificati per il banco di prova di Exchange.

Era un'opzione facile. Probabilmente qualcuno ne sarà soddisfatto, ma noi volevamo di più. Ci siamo posti il ​​compito di ottenere un elenco di tutti i certificati presenti sul server, per nome, e per ciascuno di vedere il numero di giorni rimanenti fino alla scadenza del certificato.

La seconda opzione, un po' più complicato.

Ancora una volta modifichiamo la configurazione dell'agente e lì, invece della riga con ExternalParameter, ne scriviamo altre due:

ExternalList = HTTPS.CertificateNames: powershell.exe -File "serversharenetxms_CertExternalNames.ps1"
ExternalParameter = HTTPS.CertificateExpireDate(*): powershell.exe -File "serversharenetxms_CertExternalParameter.ps1" -CertificateId "$1"

В ElencoEsterno otteniamo solo un elenco di stringhe. Nel nostro caso, un elenco di stringhe con nomi di certificati. Riceveremo un elenco di queste righe utilizzando lo script. Lista nome - HTTPS.CertificateNames.

Script NetXMS_CertNames.ps1:

#Список возможных имен сертификатов
$nameTypeList = @(
        [System.Security.Cryptography.X509Certificates.X509NameType]::SimpleName,
        [System.Security.Cryptography.X509Certificates.X509NameType]::DnsName,
        [System.Security.Cryptography.X509Certificates.X509NameType]::DnsFromAlternativeName,
        [System.Security.Cryptography.X509Certificates.X509NameType]::UrlName,
        [System.Security.Cryptography.X509Certificates.X509NameType]::EmailName,
        [System.Security.Cryptography.X509Certificates.X509NameType]::UpnName
)
 
#Ищем все сертификаты, имеющие закрытый ключ
$certList = @( Get-ChildItem -Path 'Cert:LocalMachineMy' | Where-Object { $_.HasPrivateKey -eq $true } )
 
#Проходим по списку сертификатов, формируем строку "Имя сертификата - Дата - Thumbprint" и возвращаем её
foreach ($cert in $certList) {
    $name = '(unknown name)'
    try {
        $thumbprint = $cert.Thumbprint
        $dateExpire = $cert.NotAfter
        foreach ($nameType in $nameTypeList) {
            $name_temp = $cert.GetNameInfo( $nameType, $false)
            if ($name_temp -ne $null -and $name_temp -ne '') {
                $name = $name_temp;
                break;
            }
        }
        Write-Output "$($name) - $($dateExpire.ToString('dd.MM.yyyy')) - [T:$($thumbprint)]"
    }
    catch {
        Write-Error -Message "Error processing certificate list: $($_.Exception.Message)"
    }
}

E già dentro Parametro esterno Inseriamo le righe dall'elenco ExternalList e in output otteniamo lo stesso numero di giorni per ciascuna. L'identificatore è l'identificazione personale del certificato. Tieni presente che HTTPS.CertificateExpireDate contiene un asterisco (*) in questa variante. Ciò è necessario affinché accetti variabili esterne, solo il nostro CertificateId.

Script NetXMS_CertExpireDate.ps1:

#Определяем входящий параметр $CertificateId
param (
    [Parameter(Mandatory=$false)]
    [String]$CertificateId
)
 
#Проверка на существование
if ($CertificateId -eq $null) {
    Write-Error -Message "CertificateID parameter is required!"
    return
}
 
#По Thumbprint из строки в $CertificateId ищем сертификат и определяем его Expiration Date 
$certId = $CertificateId;
try {
    if ($certId -match '^.*[T:(?<Thumbprint>[A-Z0-9]+)]$') {
        $thumbprint = $Matches['Thumbprint']
        $certificatePath = "Cert:LocalMachineMy$($thumbprint)"
         
        if (Test-Path -PathType Leaf -Path $certificatePath ) {
            $certificate = Get-Item -Path $certificatePath;
            $certificateExpirationDate = $certificate.NotAfter
            $certificateDayToLive = [Math]::Floor( ($certificateExpirationDate - [DateTime]::Now).TotalDays )
            Write-Output "$($certificateDayToLive)";
        }
        else {
            Write-Error -Message "No certificate matching this thumbprint found on this server $($certId)"
        }
    }
    else {
        Write-Error -Message "CertificateID provided in wrong format. Must be FriendlyName [T:<thumbprint>]"
    }
}
catch {
    Write-Error -Message "Error while executing script: $($_.Exception.Message)"
}

Nella configurazione della raccolta dati del server, creiamo un nuovo parametro. In Parametro selezioniamo our HTTPS.CertificateExpireDate(*) dalla lista, e (attenzione!) cambia l'asterisco in {esempio}. Questo punto importante ti consentirà di creare un contatore separato per ciascuna istanza (certificato). Il resto viene compilato come nella versione precedente:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

Per avere qualcosa da cui creare contatori, nella scheda Individuazione istanza è necessario selezionare Elenco agenti dall'elenco e nel campo Nome elenco inserire il nome della nostra Lista esterna dallo script - HTTPS.CertificateNames.

Quasi pronto, attendi un po' o forza Poll > Configurazione e Poll > Individuazione istanza se è completamente impossibile aspettare. Di conseguenza, otteniamo tutti i nostri certificati con periodi di validità:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

Di che cosa hai bisogno? Ebbene sì, solo il verme del perfezionismo guarda con occhi tristi questa inutile impronta digitale nel nome del contatore e non mi lascia finire l'articolo. Per alimentarlo, aprire nuovamente le proprietà del contatore e nella scheda Instance Discovery, nel campo “Script filtro Instance discovery”, aggiungere quello scritto in NXSL (linguaggio interno NetXMS):

instance = $1;
 if (instance ~= "^(.*)s-s[T:[a-zA-Z0-9]+]$")
 {
 return %(true, instance, $1);
 }
 return true;

che filtrerà l'identificazione personale:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

E per visualizzarlo filtrato, nella scheda Generale nel campo Descrizione, modifica CertificateExpireDate: {instance} in Data di scadenza del certificato: {nome-istanza}:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

Questo è tutto, finalmente il traguardo di KDPV:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

È bellezza?

Non resta che impostare gli avvisi in modo che arrivino via email alla scadenza del certificato.

1. Per prima cosa dobbiamo creare un modello di evento per attivarlo quando il valore del contatore diminuisce fino alla soglia che abbiamo impostato. IN Configurazione dell'evento creiamo due nuovi modelli con nomi come CertificateExpireDate_Threshold_Activate con stato di avviso:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

e simili CertificateExpireDate_Threshold_Deactivate con stato normale.

2. Successivamente, vai alle proprietà del contatore e imposta la soglia nella scheda Soglie:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

dove selezioniamo i nostri eventi creati CertificateExpireDate_Threshold_Activate e CertificateExpireDate_Threshold_Deactivate, impostiamo il numero di campioni (Samples) su 1 (nello specifico per questo contatore non ha senso impostarne di più), il valore è 30 (giorni), ad esempio, e, soprattutto, impostiamo il tempo di ripetizione dell'evento. Per i certificati in produzione l'ho impostato una volta al giorno (86400 secondi), altrimenti rischi di affogare nelle notifiche (cosa che tra l'altro è avvenuta una volta, tanto che la casella di posta era piena durante il fine settimana). Per il tempo di debug è opportuno impostarlo su un valore inferiore, ad esempio 60 secondi.

3. In Configurazione dell'azione creare un modello di lettera di notifica, come questo:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

Tutti questi %m, %S, ecc. — macro in cui verranno sostituiti i valori del nostro parametro. Sono descritti più dettagliatamente in Manuale NetXMS.

4. E infine, combinando i punti precedenti, in Politica di elaborazione degli eventi creare una regola in base alla quale verrà creato un Allarme e verrà inviata una lettera:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

Salviamo la politica, tutto può essere testato. Impostiamo la soglia più alta per controllare. Il mio certificato più vicino scade tra 723 giorni, per verificarlo l'ho impostato su 724. Di conseguenza, riceviamo il seguente allarme:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

e questa notifica via email:

Monitoraggio della data di scadenza del certificato in Windows su NetXMS

Questo è tutto certo adesso. Sarebbe ovviamente possibile impostare un dashboard e costruire grafici, ma per i certificati questi sarebbero linee rette in qualche modo noiose e prive di significato, a differenza, ad esempio, dei grafici del carico del processore o della memoria. Ma ne parleremo un'altra volta.

Fonte: habr.com

Aggiungi un commento