Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

Ostatnio stanęliśmy przed zadaniem monitorowania okresu ważności certyfikatów na serwerach Windows. No cóż, jak wstałem po tym, jak certyfikaty kilka razy zamieniły się w dynię, w tym samym czasie, gdy brodaty kolega odpowiedzialny za ich odnowienie był na wakacjach. Potem on i ja coś podejrzewaliśmy i postanowiliśmy się nad tym zastanowić. Ponieważ powoli wdrażamy system monitorowania NetXMS, stał się on głównym i w zasadzie jedynym kandydatem do tego zadania.

Ostatecznie otrzymano wynik w następującej postaci:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

A sam proces trwa.

Iść. W NetXMS nie ma wbudowanego licznika wygasających certyfikatów, dlatego trzeba stworzyć własny i za pomocą skryptów dostarczać mu dane. Oczywiście w Powershell jest to Windows. Skrypt powinien odczytać wszystkie certyfikaty w systemie operacyjnym, przyjąć ich datę wygaśnięcia w dniach i przekazać tę liczbę do NetXMS. Przez swojego agenta. Od tego zaczniemy.

Option One, najprostszy. Wystarczy uzyskać liczbę dni do daty wygaśnięcia certyfikatu z najbliższą datą.

Aby serwer NetXMS wiedział o istnieniu naszego niestandardowego parametru, musi otrzymać go od agenta. W przeciwnym razie nie można dodać tego parametru ze względu na jego brak. Dlatego w pliku konfiguracyjnym agenta nxagentd.conf dodajemy zewnętrzny ciąg parametrów o nazwie HTTPS.CertificateExpireDateSimple, w którym rejestrujemy uruchomienie skryptu:

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

Biorąc pod uwagę, że skrypt uruchamiany jest przez sieć, trzeba o tym pamiętać Polityka realizacji, i nie zapomnij także o innym „-NoLogo -NoProfile -NonInteractive”, które pominąłem dla lepszej czytelności kodu.

W rezultacie 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"

Następnie musisz zapisać konfigurację i zrestartować agenta. Możesz to zrobić z konsoli NetXMS: otwórz plik konfiguracyjny (Edytuj plik konfiguracyjny agenta), edytuj go, wykonaj polecenie Save&Apply, w wyniku czego faktycznie stanie się to samo. Następnie ponownie przeczytaj konfigurację (Ankieta > Konfiguracja), jeśli w ogóle nie masz siły czekać. Po wykonaniu tych kroków powinno być możliwe dodanie naszego parametru niestandardowego.

W konsoli NetXMS przejdź do Konfiguracja zbierania danych serwer eksperymentalny, na którym będziemy monitorować certyfikaty i tam tworzyć nowy parametr (w przyszłości, po konfiguracji, warto przenieść go na szablony). Wybierz z listy HTTPS.CertificateExpireDateSimple, wprowadź Opis z wyraźną nazwą, ustaw typ na Integer i skonfiguruj interwał odpytywania. Do celów debugowania sensowne jest skrócenie go, na przykład 30 sekund. Wszystko jest gotowe, na razie wystarczy.

Możesz sprawdzić... nie, jest za wcześnie. Teraz oczywiście nic nie dostaniemy. Po prostu dlatego, że scenariusz nie został jeszcze napisany. Poprawmy to pominięcie. Skrypt po prostu wyświetli liczbę, liczbę dni pozostałych do wygaśnięcia certyfikatu. Najbardziej minimalny ze wszystkich dostępnych. Przykładowy skrypt:

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
}

Okazuje się tak:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

723 dni, czyli prawie dwa lata do wygaśnięcia certyfikatu. To logiczne, bo całkiem niedawno ponownie wystawiałem certyfikaty na stanowisko probiercze Exchange.

To była łatwa opcja. Pewnie komuś to będzie usatysfakcjonowane, ale my chcieliśmy więcej. Postawiliśmy sobie za zadanie uzyskanie listy wszystkich certyfikatów na serwerze, według nazwy i dla każdego z nich sprawdzenie, ile dni pozostało do wygaśnięcia certyfikatu.

Druga opcja, nieco bardziej skomplikowane.

Ponownie edytujemy konfigurację agenta i tam zamiast linii z Parametrem Zewnętrznym piszemy dwa inne:

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

В Lista zewnętrzna po prostu otrzymujemy listę ciągów. W naszym przypadku lista stringów z nazwami certyfikatów. Listę tych linii otrzymamy za pomocą skryptu. Nazwa listy - HTTPS.Nazwy certyfikatów.

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

I już w Parametr zewnętrzny Wprowadzamy wiersze z listy OutsideList, a na wyjściu otrzymujemy dla każdego taką samą liczbę dni. Identyfikatorem jest odcisk palca certyfikatu. Należy pamiętać, że w tym wariancie HTTPS.CertificateExpireDate zawiera gwiazdkę (*). Jest to konieczne, aby akceptował zmienne zewnętrzne, tylko nasz identyfikator certyfikatu.

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 Parametrze wybieramy nasze HTTPS.CertificateExpireDate(*) z listy i (uwaga!) zmień gwiazdkę na {instancja}. Ten ważny punkt pozwoli Ci stworzyć osobny licznik dla każdej instancji (certyfikatu). Reszta jest wypełniona jak w poprzedniej wersji:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

Aby mieć z czego tworzyć liczniki, na zakładce Instance Discovery należy z listy wybrać Listę Agentów i w polu Nazwa Listy wpisać nazwę naszej Listy Zewnętrznej ze skryptu - HTTPS.CertificateNames.

Prawie gotowe, poczekaj trochę lub wymuś ankietę > konfiguracja i ankietę > wykrywanie instancji, jeśli oczekiwanie jest całkowicie niemożliwe. Dzięki temu wszystkie nasze certyfikaty otrzymujemy z okresami ważności:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

Czego potrzebujesz? No tak, tylko robak perfekcjonizmu smutnymi oczami patrzy na ten niepotrzebny Odcisk Kciuka w imię lady i nie pozwala mi dokończyć artykułu. Aby go zasilić należy ponownie otworzyć właściwości licznika i w zakładce Instance Discovery w polu „Instance Discovery filter script” dodać ten napisany w NXSL (język wewnętrzny NetXMS) skrypt:

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

który będzie filtrować odcisk palca:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

Aby wyświetlić go jako filtrowany, na karcie Ogólne w polu Opis zmień wartość CertyfikatExpireDate: {instance} na CertyfikatExpireDate: {nazwa-instancji}:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

To wszystko, wreszcie meta z KDPV:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

Czy to piękno?

Pozostaje tylko skonfigurować alerty, aby docierały e-mailem po wygaśnięciu certyfikatu.

1. Najpierw musimy utworzyć Szablon Zdarzenia, który będzie aktywowany, gdy wartość licznika spadnie do określonego przez nas progu. W Konfiguracja zdarzenia utwórzmy dwa nowe szablony o nazwach takich jak CertyfikatExpireDate_Threshold_Activate ze statusem Ostrzeżenie:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

i podobne CertyfikatExpireDate_Threshold_Deactivate ze statusem Normalny.

2. Następnie przejdź do właściwości licznika i w zakładce Progi ustaw próg:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

gdzie wybieramy utworzone przez nas zdarzenia CertyfikatExpireDate_Threshold_Activate i CertyfikatExpireDate_Threshold_Deactivate, ustawiamy liczbę próbek (Samples) na 1 (specjalnie dla tego licznika nie ma sensu ustawiać większej), wartość wynosi np. 30 (dni) i co ważne, ustawiamy czas powtórzenia zdarzenia. Dla certyfikatów w produkcji ustawiam to raz dziennie (86400 sekund), inaczej można utonąć w powiadomieniach (co swoją drogą zdarzyło się raz, do tego stopnia, że ​​przez weekend skrzynka pocztowa była pełna). W przypadku czasu debugowania sensowne jest ustawienie go na niższą wartość, na przykład 60 sekund.

3. w Konfiguracja akcji utwórz szablon listu z powiadomieniem, taki jak ten:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

Wszystkie te %m, %S itd. — makra, w które zostaną podstawione wartości z naszego parametru. Bardziej szczegółowo opisano je w podręcznik NetXMS.

4. I na koniec, łącząc poprzednie punkty, w Polityka przetwarzania zdarzeń utwórz regułę, według której zostanie utworzony Alarm i wysłany zostanie list:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

Zapisujemy polisę, wszystko można przetestować. Ustawmy próg wyżej w celu sprawdzenia. Mój najbliższy certyfikat wygasa za 723 dni, dla sprawdzenia ustawiam go na 724. W rezultacie pojawia się następujący alarm:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

i to powiadomienie e-mail:

Monitorowanie daty ważności certyfikatów w systemie Windows na platformie NetXMS

To wszystko jest teraz pewne. Można by oczywiście skonfigurować dashboard i zbudować wykresy, ale w przypadku certyfikatów byłyby to nieco bezsensowne i nudne linie proste, w przeciwieństwie do na przykład wykresów obciążenia procesora czy pamięci. Ale o tym innym razem.

Źródło: www.habr.com

Dodaj komentarz