Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

Ostatnio stanęliśmy przed zadaniem monitorowania ważności certyfikatów na serwerach z systemem Windows. A właściwie po tym, jak certyfikaty kilka razy stały się bezużyteczne, w momencie, gdy odpowiedzialny za ich przedłużenie kolega był na urlopie. Po tym incydencie coś nas tknęło i postanowiliśmy to przemyśleć. Ponieważ w naszej firmie wprowadza się system monitorowania NetXMS, to on stał się głównym i właściwie jedynym kandydatem do tego zadania.

Ostateczny wynik uzyskano w takiej formie:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

A oto dalszy proces.

Zaczynamy. Nie ma wbudowanego licznika końca ważności certyfikatów w NetXMS, dlatego musimy stworzyć swój i wykorzystać skrypty do zapewnienia mu danych. Oczywiście w PowerShell, to przecież Windows. Skrypt musi odczytać wszystkie certyfikaty w systemie operacyjnym, wziąć stamtąd termin ich wygaśnięcia w dniach i przekazać tę liczbę do NetXMS. Przez jego agenta. Od tego zaczniemy.

Opcja pierwsza, najprostsza. Po prostu uzyskać liczbę dni do końca ważności certyfikatu z najbliższą datą.

Aby serwer NetXMS dowiedział się o istnieniu naszego niestandardowego parametru, musi go otrzymać od agenta. W przeciwnym razie niemożliwe będzie dodanie tego parametru z powodu jego braku. Dlatego do pliku konfiguracyjnego agenta nxagentd.conf dodajemy linię zewnętrznego parametru o nazwie HTTPS.CertificateExpireDateSimple, w której opisujemy uruchomienie skryptu:

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

Biorąc pod uwagę, że skrypt jest uruchamiany przez sieć, nie można zapomnieć o Execution Policy, a także nie zapomnieć o innych „-NoLogo -NoProfile -NonInteractive”, które pominąłem dla lepszej czytelności kodu.

W wyniku czego konfiguracja agenta wygląda mniej więcej tak:

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

Po tym trzeba zapisać konfigurację i ponownie uruchomić agenta. Można to zrobić z konsoli NetXMS: otwórz konfigurację (Edytuj plik konfiguracyjny agenta), edytuj, wykonaj Zapisz i Zastosuj, a w rezultacie zdarzy się to samo. Następnie odczytaj konfigurację (Poll > Configuration), jeśli nie ma się siły czekać. Po tych czynnościach powinna pojawić się możliwość dodania naszego niestandardowego parametru.

W konsoli NetXMS przechodzimy do Konfiguracji zbierania danych serwera testowego, na którym zamierzamy monitorować certyfikaty i tworzymy nowy parametr (w przyszłości, po skonfigurowaniu, warto przenieść go do szablonów). Wybieramy HTTPS.CertificateExpireDateSimple z listy, wpisujemy opis z zrozumiałą nazwą, typ ustawiamy na Integer i konfigurujemy interwał zapytań. Na czas debugowania warto ustawić go na krótszy, na przykład 30 sekund. Wszystko, gotowe, na razie wystarczy.

Można sprawdzać… nie, jeszcze za wcześnie. Obecnie, oczywiście, nic nie uzyskamy. Po prostu dlatego, że skrypt jeszcze nie został napisany. Naprawiamy to niedopatrzenie. Skrypt będzie zwracać tylko liczbę, dni pozostałe do wygaśnięcia certyfikatu. Najniższą z dostępnych. Przykład skryptu:

try {
    # Pobieramy wszystkie certyfikaty z magazynu certyfikatów
    $lmCertificates = @( Get-ChildItem -Recurse -path 'Cert:LocalMachineMy' -ErrorAction Stop )
     
    # Jeśli nie ma certyfikatów, zwróć "10 lat"
    if ($lmCertificates.Count -eq 0) { return 3650 }
 
    # Pobieramy daty wygaśnięcia wszystkich certyfikatów
    $expirationDates = @( $lmCertificates | ForEach-Object { return $_.NotAfter } )
 
    # Pobieramy najbliższą datę wygaśnięcia ze wszystkich
    $minExpirationDate = ($expirationDates | Measure-Object -Minimum -ErrorAction Stop ).Minimum
 
    # Konwertujemy najbliższą datę wygaśnięcia na liczbę pozostałych dni, zaokrąglając w dół
    $daysLeft = [Math]::Floor( ($minExpirationDate - [DateTime]::Now).TotalDays )
 
    # Zwracamy wartość
    return $daysLeft
}
catch {
    return -1
}

Wygląda na to:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

723 dni, do wygaśnięcia certyfikatu pozostało prawie dwa lata. Logiczne, ponieważ certyfikaty na Exchange w testowym środowisku niedawno odnowiłem.

To był prosty wariant. Może kogoś zadowoli, ale nam zależało na więcej. Postawiliśmy sobie zadanie uzyskać listę wszystkich certyfikatów na serwerze, z imienia i nazwiska, i widzieć liczbę dni, które pozostały do wygaśnięcia certyfikatu.

Druga opcja, nieco trudniejszy.

Ponownie edytujemy konfigurację agenta i zamiast linii z ExternalParameter wpisujemy dwie inne:

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

W ExternalList otrzymujemy po prostu listę ciągów. W naszym przypadku, listę ciągów z nazwami certyfikatów. Tę listę ciągów otrzymamy ze skryptu. Nazwa listy — HTTPS.CertificateNames.

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

A już w ExternalParameter Przekazujemy ciągi z listy ExternalList, a na wyjściu otrzymujemy tę samą liczbę dni dla każdego z nich. Identyfikatorem jest Thumbprint certyfikatu. Zwróć uwagę, że w tym przypadku HTTPS.CertificateExpireDate zawiera gwiazdkę (*). Jest to niezbędne, aby akceptował zewnętrzne zmienne, a konkretnie nasz CertificateId.

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

W konfiguracji zbierania danych serwera tworzymy nowy parametr. W Parameter wybieramy nasz HTTPS.CertificateExpireDate(*) z listy, i (uwaga!) zamieniamy gwiazdkę na {instance}. Ten ważny moment pozwoli stworzyć osobny licznik dla każdej instancji (certyfikatu). Reszta wypełniana jest tak jak w poprzedniej wersji:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

Aby móc tworzyć liczniki, na zakładce Instance Discovery należy wybrać Agent List z listy i w polu List Name wpisać nazwę naszego ExternalList z skryptu — HTTPS.CertificateNames.

Prawie gotowe, wystarczy poczekać lub wymusić Poll > Configuration i Poll > Instance Discovery, jeśli naprawdę nie można czekać. W rezultacie otrzymujemy wszystkie nasze certyfikaty z datami ważności:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

Czy to, co potrzeba? No tak, tylko mały robak perfekcjonizmu patrzy na ten zbędny Thumbprint w nazwie licznika smutnymi oczami i nie pozwala zakończyć artykułu. Aby go nakarmić, ponownie otwieramy właściwości licznika i na zakładce Instance Discovery w polu „Instance discovery filter script” dodajemy napisany w NXSL (wewnętrzny język NetXMS) skrypt:

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

który będzie filtrować Thumbprint:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

Aby go wyświetlić w wersji odfiltrowanej, na zakładce General w polu Description zmieniamy CertificateExpireDate: {instance} na CertificateExpireDate: {instance-name}:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

Już, w końcu metamorfoza z KDPV:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

Piękno, prawda?

Pozostaje skonfigurować powiadomienia, aby były wysyłane na e-mail, gdy termin ważności certyfikatu zbliża się do końca.

1. Najpierw należy stworzyć szablon zdarzenia (Event Template), aby aktywować go, gdy wartość licznika spadnie poniżej ustalonego przez nas progu. W Event Configuration tworzymy dwa nowe szablony o nazwach, powiedzmy CertificateExpireDate_Threshold_Activate ze statusem Warning:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

i analogiczny CertificateExpireDate_Threshold_Deactivate ze statusem Normal.

2. Następnie przechodzimy do właściwości licznika i na zakładce Tresholds ustawiamy próg:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

gdzie wybieramy nasze utworzone zdarzenia CertificateExpireDate_Threshold_Activate i CertificateExpireDate_Threshold_Deactivate, ustawiamy liczbę próbek (Samples) na 1 (konkretnie dla tego licznika nie ma sensu ustawiać więcej), wartość na 30 (dni), na przykład, i, co ważne, konfigurujemy czas powtarzania zdarzenia. Dla certyfikatów w produkcji ustawiam raz na dobę (86400 sekund), inaczej można utopić się w powiadomieniach (co zresztą zdarzyło się raz, w taki sposób, że skrzynka pocztowa przepełniła się na weekend). Na czas debugowania warto ustawić mniej, na przykład 60 sekund.

3. W Konfiguracja akcji tworzymy szablon wiadomości powiadomienia, podobny do tego:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

Wszystkie te %m, %S itd. — to makra, w które zostaną podstawione wartości z naszego parametru. Więcej informacji znajduje się w instrukcji NetXMS.

4. I, wreszcie, łącząc wcześniejsze punkty, w Polityce przetwarzania zdarzeń tworzymy regułę, według której zostanie utworzone alarm i wysłane powiadomienie:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

Zapisujemy politykę, wszystko, możemy testować. Ustawimy wyższy próg dla sprawdzenia. Mój najbliższy certyfikat wygasa za 723 dni, do testu ustawiłem 724. W rezultacie otrzymamy takie alarm:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

i takie powiadomienie mailowe:

Monitorowanie daty wygaśnięcia certyfikatów w Windows na NetXMS

Teraz wszystko na pewno jest gotowe. Oczywiście można by skonfigurować pulpit nawigacyjny, stworzyć wykresy, ale w przypadku certyfikatów będą to raczej bezsensowne i nudne linie proste, w przeciwieństwie do wykresów obciążenia CPU czy pamięci, na przykład. Ale o tym w innym czasie.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster