Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

Nedavno smo se suočili sa zadatkom praćenja roka valjanosti certifikata na Windows poslužiteljima. Pa kako sam ustao nakon što su se svjedodžbe nekoliko puta pretvorile u tikvu, baš u vrijeme kad je bradati kolega zaslužan za njihovu obnovu bio na godišnjem odmoru. Nakon toga smo on i ja nešto posumnjali i odlučili razmisliti o tome. Budući da polako implementiramo NetXMS sustav nadzora, on je postao glavni i načelno jedini kandidat za ovu zadaću.

Na kraju je dobiven rezultat u sljedećem obliku:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

A sam proces se nastavlja.

Ići. U NetXMS-u nema ugrađenog brojača za istjecajuće certifikate, pa trebate izraditi vlastite i koristiti skripte da biste mu dostavili podatke. Naravno, na Powershellu, ovo je Windows. Skripta bi trebala pročitati sve certifikate u operativnom sustavu, od tamo uzeti njihov datum isteka u danima i proslijediti taj broj NetXMS-u. Preko svog agenta. Odatle ćemo početi.

Opcija Jedan, najjednostavniji. Jednostavno nabavite broj dana do datuma isteka certifikata s najbližim datumom.

Kako bi NetXMS poslužitelj znao za postojanje našeg prilagođenog parametra, mora ga primiti od agenta. Inače se ovaj parametar ne može dodati jer ga nema. Stoga, u konfiguracijskoj datoteci agenta nxagentd.conf dodajemo niz vanjskih parametara tzv HTTPS.CertificateExpireDateSimple, u kojem registriramo pokretanje skripte:

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

S obzirom da se skripta pokreće preko mreže, morate zapamtiti o Politika izvršenja, a također ne zaboravite drugi "-NoLogo -NoProfile -NonInteractive", koji sam izostavio radi bolje čitljivosti koda.

Kao rezultat toga, konfiguracija agenta izgleda otprilike ovako:

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

Nakon toga morate spremiti konfiguraciju i ponovno pokrenuti agenta. To možete učiniti iz NetXMS konzole: otvorite config (Edit agent's configuration file), uredite ga, izvršite Save&Apply, uslijed čega će se zapravo dogoditi isto. Zatim ponovno pročitajte konfiguraciju (Anketa > Konfiguracija), ako uopće nemate snage čekati. Nakon ovih koraka trebali biste moći dodati naš prilagođeni parametar.

U NetXMS konzoli idite na Konfiguracija prikupljanja podataka eksperimentalni poslužitelj na kojem ćemo pratiti certifikate i tamo kreirati novi parametar (ubuduće ga nakon konfiguracije ima smisla prebaciti u predloške). Odaberite HTTPS.CertificateExpireDateSimple s popisa, unesite Opis s jasnim nazivom, postavite vrstu na Integer i konfigurirajte interval prozivanja. Za potrebe ispravljanja pogrešaka, ima smisla da bude kraći, 30 sekundi, na primjer. Sve je spremno, za sada je dosta.

Možete provjeriti... ne, prerano je. Sada, naravno, nećemo dobiti ništa. Jednostavno zato što scenarij još nije napisan. Ispravimo ovaj propust. Skripta će jednostavno prikazati broj, broj dana preostalih do isteka certifikata. Najminimalniji od svih dostupnih. Primjer skripte:

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
}

Ispada ovako:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

Još 723 dana, skoro dvije godine do isteka certifikata. To je logično, jer sam nedavno ponovo izdao certifikate za Exchange test bench.

Bila je to laka opcija. Vjerojatno će netko biti zadovoljan s ovim, ali mi smo htjeli više. Zadali smo si zadatak nabaviti popis svih certifikata na serveru, po imenu, te za svaki vidjeti koliko je dana preostalo do isteka certifikata.

Druga opcija, nešto kompliciranije.

Opet uređujemo konfiguraciju agenta i tamo, umjesto retka s ExternalParameterom, pišemo dva druga:

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

В VanjskiList dobivamo samo popis nizova. U našem slučaju, popis nizova s ​​nazivima certifikata. Pomoću skripte primit ćemo popis ovih redaka. Lista imena - HTTPS.CertificateNames.

Skripta 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 već unutra Vanjski parametar Unosimo retke iz ExternalList liste, a na izlazu dobivamo isti broj dana za svaki. Identifikator je otisak prsta certifikata. Imajte na umu da HTTPS.CertificateExpireDate sadrži zvjezdicu (*) u ovoj varijanti. Ovo je neophodno kako bi prihvatio vanjske varijable, samo naš CertificateId.

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

U konfiguraciji prikupljanja podataka poslužitelja stvaramo novi parametar. U Parametru odabiremo naš HTTPS.CertificateExpireDate(*) s popisa i (pozor!) promijenite zvjezdicu u {primjer}. Ova važna točka omogućit će vam stvaranje zasebnog brojača za svaku instancu (certifikat). Ostatak se popunjava kao u prethodnoj verziji:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

Da biste imali iz čega kreirati brojače, na kartici Instance Discovery potrebno je iz liste odabrati Agent List i u polje List Name unijeti naziv naše ExternalList iz skripte - HTTPS.CertificateNames.

Skoro spremno, pričekajte malo ili forsirajte Anketa > Konfiguracija i Anketa > Otkrivanje instance ako je potpuno nemoguće čekati. Kao rezultat toga, dobivamo sve naše certifikate s rokovima valjanosti:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

Što trebaš? Pa da, samo crv perfekcionizma tužnim očima gleda ovaj nepotrebni Otisak palca u nazivu brojača i ne da mi dovršiti članak. Da biste ga dodali, ponovno otvorite svojstva brojača i na kartici Otkrivanje instance, u polju "Skripta filtra za otkrivanje instance", dodajte onu napisanu u NXSL (NetXMS interni jezik) skripta:

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

koji će filtrirati otisak palca:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

A da biste ga prikazali filtriranog, na kartici Općenito u polju Opis promijenite CertificateExpireDate: {instance} u CertificateExpireDate: {instance-name}:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

To je to, konačno cilj iz KDPV-a:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

Zar nije ljepota?

Ostaje još samo postaviti upozorenja da stižu e-poštom kada certifikat istekne.

1. Prvo moramo stvoriti predložak događaja kako bismo ga aktivirali kada se vrijednost brojača smanji na neki prag koji smo postavili. U Konfiguracija događaja stvorimo dva nova predloška s imenima poput CertificateExpireDate_Threshold_Activate sa statusom upozorenja:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

i slično CertificateExpireDate_Threshold_Deactivate s normalnim stanjem.

2. Zatim idite na svojstva brojača i postavite prag na kartici Pragovi:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

gdje izaberemo naše kreirane događaje CertificateExpireDate_Threshold_Activate i CertificateExpireDate_Threshold_Deactivate, postavimo broj uzoraka (Samples) na 1 (konkretno za ovaj brojač nema smisla postavljati više), vrijednost je npr. 30 (dana) i što je bitno, postavimo vrijeme ponavljanja događaja. Za certifikate u produkciji postavljam jednom dnevno (86400 sekundi), inače se možete utopiti u obavijestima (što se, usput, dogodilo jednom, toliko da je sandučić bio pun preko vikenda). Za vrijeme otklanjanja pogrešaka ima smisla postaviti niže, na primjer 60 sekundi.

3.U Konfiguracija akcije izradite predložak pisma obavijesti, ovako:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

Svi ovi %m, %S itd. — makronaredbe u koje će se zamijeniti vrijednosti iz našeg parametra. Oni su detaljnije opisani u priručnik NetXMS.

4. I na kraju, kombinirajući prethodne točke, u Politika obrade događaja kreirajte pravilo prema kojem će se kreirati Alarm i poslati pismo:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

Čuvamo polisu, sve se može isprobati. Postavimo prag više za provjeru. Moj najbliži certifikat istječe za 723 dana, za provjeru sam ga postavio na 724. Kao rezultat toga, dobivamo sljedeći alarm:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

i ovu obavijest e-poštom:

Praćenje datuma isteka certifikata u sustavu Windows na NetXMS-u

To je sada sve sigurno. Bilo bi, naravno, moguće postaviti nadzornu ploču i napraviti grafikone, ali za certifikate bi to bile pomalo besmislene i dosadne ravne linije, za razliku od npr. grafikona opterećenja procesora ili memorije. No, o tome više nekom drugom prilikom.

Izvor: www.habr.com

Dodajte komentar