Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

Kürzlich standen wir vor der Aufgabe, die Gültigkeitsdauer von Zertifikaten auf Windows-Servern zu überwachen. Nun, wie ich aufgestanden bin, nachdem sich die Zertifikate mehrmals in einen Kürbis verwandelt hatten, genau zu der Zeit, als der bärtige Kollege, der für die Erneuerung verantwortlich war, im Urlaub war. Danach ahnten er und ich etwas und beschlossen, darüber nachzudenken. Da wir das NetXMS-Überwachungssystem langsam implementieren, ist es zum wichtigsten und im Prinzip einzigen Kandidaten für diese Aufgabe geworden.

Das Ergebnis ergab sich schließlich in folgender Form:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

Und der Prozess selbst geht weiter.

Gehen. In NetXMS gibt es keinen integrierten Zähler für ablaufende Zertifikate. Sie müssen also ein eigenes Zertifikat erstellen und Skripte verwenden, um es mit Daten zu versorgen. Unter Powershell ist dies natürlich Windows. Das Skript sollte alle Zertifikate im Betriebssystem lesen, deren Ablaufdatum in Tagen ermitteln und diese Zahl an NetXMS übergeben. Durch seinen Agenten. Da fangen wir an.

Option One, am einfachsten. Ermitteln Sie einfach die Anzahl der Tage bis zum Ablaufdatum des Zertifikats mit dem nächstgelegenen Datum.

Damit der NetXMS-Server von der Existenz unseres benutzerdefinierten Parameters erfährt, muss er ihn vom Agenten erhalten. Andernfalls kann dieser Parameter aufgrund seines Fehlens nicht hinzugefügt werden. Daher in der Agentenkonfigurationsdatei nxagentd.conf Wir fügen eine externe Parameterzeichenfolge mit dem Namen hinzu HTTPS.CertificateExpireDateSimple, in dem wir den Start des Skripts registrieren:

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

Wenn man bedenkt, dass das Skript über das Netzwerk gestartet wird, müssen Sie daran denken Ausführungsrichtlinie, und vergessen Sie auch nicht das andere „-NoLogo -NoProfile -NonInteractive“, das ich zur besseren Lesbarkeit des Codes weggelassen habe.

Infolgedessen sieht die Agentenkonfiguration in etwa so aus:

#
# 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"

Danach müssen Sie die Konfiguration speichern und den Agenten neu starten. Sie können dies über die NetXMS-Konsole tun: Öffnen Sie die Konfiguration (Konfigurationsdatei des Agenten bearbeiten), bearbeiten Sie sie, führen Sie „Speichern und Anwenden“ aus, woraufhin tatsächlich dasselbe passieren wird. Lesen Sie dann die Konfiguration erneut durch (Umfrage > Konfiguration), wenn Sie nicht die Kraft haben, überhaupt zu warten. Nach diesen Schritten sollten Sie in der Lage sein, unseren benutzerdefinierten Parameter hinzuzufügen.

Gehen Sie in der NetXMS-Konsole zu Konfiguration der Datenerfassung experimenteller Server, auf dem wir Zertifikate überwachen und dort einen neuen Parameter erstellen werden (in Zukunft ist es nach der Konfiguration sinnvoll, ihn in Vorlagen zu übertragen). Wählen Sie HTTPS.CertificateExpireDateSimple aus der Liste aus, geben Sie eine Beschreibung mit einem eindeutigen Namen ein, legen Sie den Typ auf „Integer“ fest und konfigurieren Sie das Abfrageintervall. Für Debugging-Zwecke ist es sinnvoll, die Zeitspanne zu verkürzen, beispielsweise 30 Sekunden. Alles ist fertig, das reicht für den Moment.

Sie können es überprüfen... Nein, es ist zu früh. Jetzt bekommen wir natürlich nichts. Ganz einfach, weil das Drehbuch noch nicht geschrieben ist. Korrigieren wir dieses Versäumnis. Das Skript zeigt einfach eine Zahl an, die Anzahl der verbleibenden Tage bis zum Ablauf des Zertifikats. Das Minimalste von allen verfügbaren. Beispielskript:

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
}

Es stellt sich so heraus:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

Noch 723 Tage, fast zwei Jahre bis zum Ablauf des Zertifikats. Das ist logisch, denn ich habe erst vor Kurzem Zertifikate für den Exchange-Prüfstand neu ausgestellt.

Es war eine einfache Option. Wahrscheinlich wird jemand damit zufrieden sein, aber wir wollten mehr. Wir haben es uns zur Aufgabe gemacht, eine Liste aller Zertifikate auf dem Server nach Namen zu erhalten und für jedes einzelne die Anzahl der verbleibenden Tage bis zum Ablauf des Zertifikats anzuzeigen.

Die zweite Option, etwas komplizierter.

Wieder bearbeiten wir die Agentenkonfiguration und schreiben dort anstelle der Zeile mit ExternalParameter zwei weitere:

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

В Externe Liste Wir erhalten lediglich eine Liste von Zeichenfolgen. In unserem Fall eine Liste von Zeichenfolgen mit Zertifikatsnamen. Mithilfe des Skripts erhalten wir eine Liste dieser Zeilen. Listennamen - HTTPS.CertificateNames.

Skript 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)"
    }
}

Und schon drin Externer Parameter Wir geben Zeilen aus der ExternalList-Liste ein und als Ausgabe erhalten wir für jede die gleiche Anzahl von Tagen. Die Kennung ist der Fingerabdruck des Zertifikats. Beachten Sie, dass HTTPS.CertificateExpireDate in dieser Variante ein Sternchen (*) enthält. Dies ist notwendig, damit externe Variablen akzeptiert werden, also nur unsere CertificateId.

Skript 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)"
}

In der Datenerfassungskonfiguration des Servers erstellen wir einen neuen Parameter. In Parameter wählen wir unsere aus HTTPS.CertificateExpireDate(*) aus der Liste, und (Achtung!) ändern Sie das Sternchen in {Beispiel}. Dieser wichtige Punkt ermöglicht es Ihnen, für jede Instanz (Zertifikat) einen separaten Zähler zu erstellen. Der Rest wird wie in der vorherigen Version ausgefüllt:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

Um etwas zu haben, aus dem Sie Zähler erstellen können, müssen Sie auf der Registerkarte „Instanzerkennung“ die Agentenliste aus der Liste auswählen und im Feld „Listenname“ den Namen unserer ExternalList aus dem Skript eingeben – HTTPS.CertificateNames.

Fast fertig, warten Sie ein wenig oder erzwingen Sie Umfrage > Konfiguration und Umfrage > Instanzerkennung, wenn das Warten völlig unmöglich ist. Als Ergebnis erhalten wir alle unsere Zertifikate mit Gültigkeitszeiträumen:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

Was brauchen Sie? Nun ja, nur der Wurm des Perfektionismus blickt mit traurigen Augen auf diesen unnötigen Fingerabdruck im Namen des Zählers und lässt mich den Artikel nicht zu Ende lesen. Um es zu füttern, öffnen Sie die Zählereigenschaften erneut und fügen Sie auf der Registerkarte „Instanzerkennung“ im Feld „Instanzerkennungsfilterskript“ das geschriebene hinzu NXSL (NetXMS-interne Sprache) Skript:

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

Dadurch wird der Fingerabdruck gefiltert:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

Und um es gefiltert anzuzeigen, ändern Sie auf der Registerkarte „Allgemein“ im Feld „Beschreibung“ den Wert „CertificateExpireDate: {instance}“ in CertificateExpireDate: {instance-name}:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

Das ist es, endlich die Ziellinie von KDPV:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

Ist es Schönheit?

Jetzt müssen nur noch Benachrichtigungen eingerichtet werden, damit diese per E-Mail bei Ablauf des Zertifikats eintreffen.

1. Zuerst müssen wir eine Ereignisvorlage erstellen, um sie zu aktivieren, wenn der Zählerwert auf einen von uns festgelegten Schwellenwert sinkt. IN Ereigniskonfiguration Lassen Sie uns zwei neue Vorlagen mit Namen wie erstellen CertificateExpireDate_Threshold_Activate mit Warnstatus:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

und ähnlich CertificateExpireDate_Threshold_Deactivate mit Normalstatus.

2. Gehen Sie als Nächstes zu den Zählereigenschaften und legen Sie den Schwellenwert auf der Registerkarte Schwellenwerte fest:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

Dabei wählen wir unsere erstellten Ereignisse CertificateExpireDate_Threshold_Activate und CertificateExpireDate_Threshold_Deactivate aus, setzen die Anzahl der Proben (Samples) auf 1 (speziell für diesen Zähler macht es keinen Sinn, mehr festzulegen), der Wert beträgt beispielsweise 30 (Tage) und, was wichtig ist, setzen die Ereigniswiederholungszeit. Für Zertifikate in der Produktion stelle ich es einmal am Tag ein (86400 Sekunden), sonst kann man in Benachrichtigungen ertrinken (was übrigens einmal vorkam, so sehr, dass das Postfach am Wochenende voll war). Für die Debugging-Zeit ist es sinnvoll, sie niedriger anzusetzen, beispielsweise 60 Sekunden.

3. In Aktionskonfiguration Erstellen Sie eine Vorlage für ein Benachrichtigungsschreiben wie folgt:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

All diese %m, %S usw. — Makros, in die Werte aus unserem Parameter eingesetzt werden. Sie werden ausführlicher beschrieben in Handbuch NetXMS.

4. Und schließlich kombinieren wir die vorherigen Punkte zu Richtlinie zur Ereignisverarbeitung Erstellen Sie eine Regel, nach der ein Alarm erstellt und ein Brief gesendet wird:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

Wir speichern die Police, alles kann getestet werden. Zur Überprüfung setzen wir den Schwellenwert höher. Mein nächstgelegenes Zertifikat läuft in 723 Tagen ab. Ich habe es zur Überprüfung auf 724 gesetzt. Als Ergebnis erhalten wir den folgenden Alarm:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

und diese E-Mail-Benachrichtigung:

Überwachen des Ablaufdatums des Zertifikats in Windows unter NetXMS

Das ist jetzt alles sicher. Es wäre natürlich möglich, ein Dashboard einzurichten und Diagramme zu erstellen, aber für Zertifikate wären das etwas bedeutungslose und langweilige gerade Linien, anders als beispielsweise Diagramme der Prozessor- oder Speicherauslastung. Aber mehr dazu ein andermal.

Source: habr.com

Kommentar hinzufügen