Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

Nedávno jsme stáli před úkolem sledovat dobu platnosti certifikátů na Windows serverech. No, jak jsem vstával poté, co se certifikáty několikrát proměnily v dýni, zrovna v době, kdy byl vousatý kolega zodpovědný za jejich obnovu na dovolené. Poté jsme spolu s ním něco tušili a rozhodli jsme se o tom přemýšlet. Jelikož monitorovací systém NetXMS pomalu zavádíme, stal se hlavním a v zásadě jediným kandidátem na tento úkol.

Výsledek byl nakonec získán v následující podobě:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

A samotný proces pokračuje.

Jít. V NetXMS není vestavěný čítač pro vypršení platnosti certifikátů, takže si musíte vytvořit vlastní a pomocí skriptů mu poskytnout data. V Powershell je to samozřejmě Windows. Skript by měl přečíst všechny certifikáty v operačním systému, zjistit datum vypršení jejich platnosti ve dnech a předat toto číslo NetXMS. Prostřednictvím svého agenta. Tím začneme.

Option One, nejjednodušší. Jednoduše získáte počet dní do konce platnosti certifikátu s nejbližším datem.

Aby se server NetXMS dozvěděl o existenci našeho vlastního parametru, musí jej obdržet od agenta. Jinak tento parametr nelze přidat z důvodu jeho absence. Proto v konfiguračním souboru agenta nxagentd.conf přidáme řetězec externích parametrů nazvaný HTTPS.CertificateExpireDateSimple, ve kterém registrujeme spuštění skriptu:

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

Vzhledem k tomu, že skript je spouštěn přes síť, musíte mít na paměti Zásady provádění, a také nezapomeňte na další „-NoLogo -NoProfile -NonInteractive“, které jsem vynechal kvůli lepší čitelnosti kódu.

V důsledku toho vypadá konfigurace agenta nějak takto:

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

Poté musíte uložit konfiguraci a restartovat agenta. Můžete to udělat z konzole NetXMS: otevřete config (Upravit konfigurační soubor agenta), upravte jej, spusťte Save&Apply, v důsledku čehož se ve skutečnosti stane to samé. Pak si znovu přečtěte konfiguraci (Anketa > Konfigurace), pokud vůbec nemáte sílu čekat. Po těchto krocích byste měli být schopni přidat náš vlastní parametr.

V konzole NetXMS přejděte na Konfigurace sběru dat experimentální server, na kterém budeme hlídat certifikáty a vytvářet tam nový parametr (v budoucnu po konfiguraci má smysl jej přenášet do šablon). Ze seznamu vyberte HTTPS.CertificateExpireDateSimple, zadejte Popis s jasným názvem, nastavte typ na Integer a nakonfigurujte interval dotazování. Pro účely ladění má smysl to zkrátit, například 30 sekund. Vše je připraveno, zatím to stačí.

Můžete zkontrolovat... ne, je příliš brzy. Teď samozřejmě nic nedostaneme. Jednoduše proto, že scénář ještě nebyl napsán. Opravme toto opomenutí. Skript jednoduše zobrazí číslo, počet dní zbývajících do vypršení platnosti certifikátu. Nejmenší ze všech dostupných. Příklad skriptu:

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
}

Ukázalo se, že takto:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

723 dní, téměř dva roky do konce platnosti certifikátu. Je to logické, protože nedávno jsem znovu vydal certifikáty pro testovací stolici Exchange.

Byla to snadná možnost. Asi se s tím někdo spokojí, ale my jsme chtěli víc. Dali jsme si za úkol získat seznam všech certifikátů na serveru podle názvu a u každého vidět počet dní zbývajících do konce platnosti certifikátu.

Druhá možnost, poněkud složitější.

Opět upravíme konfiguraci agenta a tam místo řádku s ExternalParameter napíšeme dva další:

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

В ExternalList dostaneme pouze seznam řetězců. V našem případě seznam řetězců s názvy certifikátů. Seznam těchto řádků obdržíme pomocí skriptu. Název seznamu - 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)"
    }
}

A už dovnitř ExterníParametr Vložíme řádky ze seznamu ExternalList a na výstupu pro každý dostaneme stejný počet dní. Identifikátorem je otisk certifikátu. Všimněte si, že HTTPS.CertificateExpireDate obsahuje v této variantě hvězdičku (*). To je nezbytné, aby akceptoval externí proměnné, pouze naše 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)"
}

V konfiguraci sběru dat serveru vytvoříme nový parametr. V Parametru vybereme naše HTTPS.CertificateExpireDate(*) ze seznamu a (pozor!) změňte hvězdičku na {instance}. Tento důležitý bod vám umožní vytvořit samostatné počítadlo pro každou instanci (certifikát). Zbytek je vyplněn jako v předchozí verzi:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

Abyste měli z čeho vytvářet čítače, je potřeba na záložce Instance Discovery vybrat ze seznamu Agent List a do pole List Name zadat ze skriptu název našeho ExternalList - HTTPS.CertificateNames.

Téměř připraveno, chvíli počkejte nebo si vynucte hlasování > Konfigurace a dotazování > zjišťování instance, pokud je zcela nemožné čekat. V důsledku toho získáváme všechny naše certifikáty s dobou platnosti:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

Co potřebuješ? No ano, jen červ perfekcionismu se na tento nepotřebný Palec jménem pultu dívá smutnýma očima a nenechá mě článek dokončit. Chcete-li jej načíst, znovu otevřete vlastnosti počítadla a na kartě Zjišťování instancí do pole „Skript filtru zjišťování instancí“ přidejte skript zapsaný v NXSL (interní jazyk NetXMS) skript:

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

který bude filtrovat otisk:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

A chcete-li jej zobrazit filtrovaný, na kartě Obecné v poli Popis změňte CertificateExpireDate: {instance} na CertificateExpireDate: {instance-name}:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

To je vše, konečně cílová čára z KDPV:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

Je to krása?

Zbývá jen nastavit upozornění, aby přicházely emailem, když certifikát vyprší.

1. Nejprve musíme vytvořit šablonu události, která ji aktivuje, když hodnota čítače klesne na určitou prahovou hodnotu, kterou jsme nastavili. V Konfigurace události pojďme vytvořit dvě nové šablony s názvy jako CertificateExpireDate_Threshold_Activate se stavem varování:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

a podobně CertificateExpireDate_Threshold_Deactivate s Normálním stavem.

2. Dále přejděte do vlastností čítače a nastavte práh na záložce Tresholds:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

kde vybereme námi vytvořené události CertificateExpireDate_Threshold_Activate a CertificateExpireDate_Threshold_Deactivate, nastavíme počet vzorků (Samples) na 1 (konkrétně u tohoto čítače nemá smysl nastavovat více), hodnota je např. 30 (dní) a co je důležité, nastavíme dobu opakování události. U certifikátů ve výrobě to nastavuji jednou denně (86400 sekund), jinak se můžete utopit v notifikacích (což se mimochodem jednou stalo, až byla schránka přes víkend plná). Pro dobu ladění má smysl nastavit ji nižší, například 60 sekund.

3. V Konfigurace akce vytvořte šablonu dopisu s oznámením, jako je tato:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

Všechny tyto %m, %S atd. — makra, do kterých budou nahrazeny hodnoty z našeho parametru. Podrobněji jsou popsány v manuál NetXMS.

4. A nakonec, spojením předchozích bodů, do Zásady zpracování událostí vytvořte pravidlo, podle kterého se vytvoří Alarm a odešle dopis:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

Zásadu ukládáme, vše lze otestovat. Pro kontrolu nastavíme vyšší práh. Platnost mého nejbližšího certifikátu vyprší za 723 dní, pro kontrolu jsem jej nastavil na 724. Výsledkem je následující alarm:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

a toto upozornění e-mailem:

Sledování data vypršení platnosti certifikátu ve Windows na NetXMS

To je nyní jisté. Dalo by se samozřejmě nastavit dashboard a sestavit grafy, ale pro certifikáty by to byly poněkud nesmyslné a nudné přímky, na rozdíl například od grafů zatížení procesoru nebo paměti. O tom ale více někdy jindy.

Zdroj: www.habr.com

Přidat komentář