Övervakning av certifikatens utgångsdatum i Windows på NetXMS

Nyligen stod vi inför uppgiften att övervaka giltighetstiden för certifikat på servrar med Windows. Som sagt, efter att certifikaten flera gånger hade blivit ogiltiga just när den ansvarige för deras förnyelse, vår skäggiga kollega, var på semester. Efter detta började vi misstänka något och bestämde oss för att tänka på det. Eftersom vi långsamt implementerar övervakningssystemet NetXMS blev det huvudsakligen och i princip den enda kandidaten för denna uppgift.

Resultatet blev i slutändan följande:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

Och själva processen vidare.

Låt oss börja. Det finns ingen inbyggd räknare för utgående certifikat i NetXMS, så vi måste skapa vår egen och använda skript för att tillhandahålla data. Självklart på Powershell, det är ju Windows. Skriptet måste läsa alla certifikat i operativsystemet, hämta utgångsdatumet i dagar och överföra detta nummer till NetXMS. Genom dess agent. Så vi börjar där.

Alternativ ett, det enklaste. Bara få antalet dagar tills certifikatets giltighetstid går ut med det närmaste datumet.

För att NetXMS-servern ska bli medveten om vår anpassade parameter måste den få den från agenten. Annars går det inte att lägga till denna parameter på grund av dess frånvaro. Därför i konfigurationsfilen för agenten nxagentd.conf lägger vi till en rad för den externa parametern med namnet HTTPS.CertificateExpireDateSimple, där vi anger körningen av skriptet:

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

Med tanke på att skriptet körs över nätverket får vi inte glömma bort Execution Policy, och inte heller glömma andra "-NoLogo -NoProfile -NonInteractive" som jag utelämnat för att göra koden mer läsbar.

Resultatet blir att agentens konfigurationsfil ser ut ungefär så här:

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

Därefter måste konfigurationen sparas och agenten startas om. Detta kan göras från NetXMS-konsolen: öppna konfigurationsfilen (Edit agent’s configuration file), redigera, utför Save & Apply, vilket ger samma resultat. Sedan kan du läsa om konfigurationen (Poll > Configuration) om du inte har tålamod att vänta. Efter dessa åtgärder ska möjligheten att lägga till vår anpassade parameter dyka upp.

I NetXMS-konsolen går vi till Data Collection Configuration testserver där vi ska övervaka certifikaten och vi skapar en ny parameter där (i framtiden, efter konfiguration, finns det anledning att flytta den till mallarna). Välj HTTPS.CertificateExpireDateSimple från listan, skriv in en beskrivning med ett begripligt namn, ställ in typ till Integer och konfigurera intervall för undersökning. För debuggningssyften är det meningsfullt att göra det kortare, 30 sekunder till exempel. Klart, det räcker så.

Man kan börja kontrollera… nej, det är fortfarande för tidigt. Just nu får vi naturligtvis inget. Blott för att skriptet inte är skrivet än. Vi åtgärdar denna brist. Skriptet kommer bara att ge ett tal, antalet dagar som är kvar tills certifikatets utgångsdatum. Det mest grundläggande av alla tillgängliga. Exempel på skript:

try {
    # Hämta alla certifikat från certifikatlagret
    $lmCertificates = @( Get-ChildItem -Recurse -path 'Cert:LocalMachineMy' -ErrorAction Stop )
     
    # Om det inte finns några certifikat, returnera "10 år"
    if ($lmCertificates.Count -eq 0) { return 3650 }
 
    # Hämta utgångsdatum för alla certifikat
    $expirationDates = @( $lmCertificates | ForEach-Object { return $_.NotAfter } )
 
    # Hämta det närmaste utgångsdatumet
    $minExpirationDate = ($expirationDates | Measure-Object -Minimum -ErrorAction Stop ).Minimum
 
    # Konvertera det närmaste utgångsdatumet till antal dagar kvar, avrundat nedåt
    $daysLeft = [Math]::Floor( ($minExpirationDate - [DateTime]::Now).TotalDays )
 
    # Returnera värdet
    return $daysLeft
}
catch {
    return -1
}

Så här blir resultatet:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

723 dagar, det är nästan två år kvar tills certifikatet går ut. Logiskt, eftersom jag nyligen förnyade certifikaten på Exchange-testmiljön.

Det här var den enkla versionen. Kanske någon kommer att vara nöjd med det, men vi ville ha mer. Vi satte oss målet att få en lista över alla certifikat på servern, namn för namn, och se hur många dagar som är kvar tills certifikatets utgångsdatum.

Andra alternativet, lite mer komplicerat.

Återigen redigerar vi agentens konfiguration och där i stället för raden med ExternalParameter skriver vi två andra:

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

I ExternalList vi får helt enkelt en lista med rader. I vårt fall, en lista med rader som innehåller certifikatnamn. Denna lista får vi med skriptet. Listans namn — HTTPS.CertificateNames.

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

Och redan i ExternalParameter Vi matar in strängar från listan ExternalList, och får ut lika många dagar för varje. Identifieraren är certifikatets Thumbprint. Observera att HTTPS.CertificateExpireDate i detta fall innehåller en asterisk (*). Detta är nödvändigt för att den ska ta emot externa variabler, just vårt CertificateId.

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

I Data Collection Configuration på servern skapar vi en ny parameter. I Parameter väljer vi vår HTTPS.CertificateExpireDate(*) från listan, och (observera!) byter asterisken mot {instance}. Denna viktiga punkt gör det möjligt att skapa en separat räknare för varje instans (certifikat). Resterande fylls i som i föregående alternativ:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

För att räknarna ska kunna skapas, måste vi på fliken Instance Discovery välja Agent List från listan och i fältet List Name skriva namnet på vår ExternalList från skriptet — HTTPS.CertificateNames.

Nästan klar, vänta lite eller gör en manuell Poll > Configuration och Poll > Instance Discovery, om det verkligen är omöjligt att vänta. Resultatet blir att vi får alla våra certifikat med utgångsdatum:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

Är det vad vi behöver? Ja, men den perfektionistiska känslan ser på denna onödiga Thumbprint i räknarens namn med sorgsna ögon och låter oss inte avsluta artikeln. För att ge den nåd, öppnar vi igen räknarens egenskaper och på fliken Instance Discovery i fältet "Instance discovery filter script" lägger vi till ett skript skrivet på NXSL (NetXMS interna språk):

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

som kommer att filtrera bort Thumbprint:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

För att visa det filtrerade, på fliken General i fältet Description byter vi CertificateExpireDate: {instance} till CertificateExpireDate: {instance-name}:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

Klart, slutligen i mål med KDPV:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

Vackert eller hur?

Det återstår att ställa in aviseringar så att de kommer till e-posten när certifikatets giltighetstid närmar sig sitt logiska slut.

1. Först behöver vi skapa en händelsemall (Event Template) för att aktivera den när räknarens värde sjunker till en viss angiven tröskel. I Event Configuration skapar vi två nya mallar med namnen, låt oss säga CertificateExpireDate_Threshold_Activate med status Warning:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

och en liknande CertificateExpireDate_Threshold_Deactivate med status Normal.

2. Gå sedan till räknarens egenskaper och på fliken Tresholds ställer vi in tröskeln:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

där vi väljer våra skapade händelser CertificateExpireDate_Threshold_Activate och CertificateExpireDate_Threshold_Deactivate, sätter antalet mätningar (Samples) till 1 (specifikt för denna mätare finns det ingen anledning att sätta mer), värdet till 30 (dagar), till exempel, och, vad som är viktigt, konfigurerar händelsens repetitionsintervall. För certifikat i produktion sätter jag en gång om dagen (86400 sekunder), annars kan man drunkna i notifieringar (vilket faktiskt hände en gång, så att inkorgarna blev överfulla över helgen). För testsyften är det meningsfullt att sätta en kortare tid, 60 sekunder, till exempel.

3. I Action Configuration skapar vi en mall för notifieringsmail, typ så här:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

Alla dessa %m, %S etc. — är makron, där värdena från vår parameter kommer att sättas in. Mer detaljerat beskrivs de i manualen NetXMS.

4. Och, äntligen, genom att sammanföra de föregående punkterna, i Event Processing Policy skapar vi en regel som kommer att skapa ett Alarm och skicka ett mail:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

Spara policyn, allt är klart, vi kan testa. Vi sätter tröskeln högre för verifiering. Min närmaste certifikat går ut om 723 dagar, för teststället satte jag 724. Som resultat fångar vi en sådan alarm:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

och en sådan notifiering via mail:

Övervakning av certifikatens utgångsdatum i Windows på NetXMS

Nu är allt verkligen klart. Man skulle kunna ställa in en dashboard, bygga diagram, men för certifikat blir det några meningslösa och tråkiga raka linjer, till skillnad från diagram över CPU- eller minnesbelastning, till exempel. Men, det får vi ta en annan gång.

Källa: habr.com

Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar 🔥 Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster