Hiljuti seisis meil ees ülesanne sertifikaatide kehtivuse jälgimiseks Windowsi serverites. Noh, kuidas ta nüüd öelda, pärast seda, kui sertifikaadid paar korda kõrvitsaks muudetud said, just siis, kui nende pikendamise eest vastutav koleeg puhkusel viibis. Pärast seda kahtlesime millegis ja otsustasime sellele mõtlema hakata. Kuna meil on rahulikult käimas NetXMS jälgimissüsteemi rakendamine, sai see ülesanne peamiseks ja, põhimõtteliselt, ainsaks kandidaadiks.
Lõpptulemus saadi sellisel kujul:

Ja edaspidine protsess.
Hakkame pihta. NetXMS-is ei ole sisseehitatud sertifikaatide kehtivuse aja loendurit, seega tuleb luua oma ja kasutada skripte selle andmete kogumiseks. Loomulikult, PowerShellis, see on Windows. Skript peab lugema kõik sertifikaadid operatsioonisüsteemis, võtma sealt välja nende aegumiskuupäeva päevade arvu ja edastama selle numbri NetXMS-ile. Selle agendi kaudu. Sellega me alustame.
Esimene võimalus, kõige lihtsam. Lihtsalt saada teada, mitu päeva on kuni kõige lähima aegumiskuupäevani.
Ettevõte NetXMS peab meie kohandatud parameetrist teadlik olema, et see agent sellisest parameetrist teada saaks. Vastasel korral ei saa seda parameetrit lisada, kuna see puudub. Seetõttu lisame agendi konfiguratsioonifaili nxagentd.conf välise parameetri rea nimega HTTPS.CertificateExpireDateSimple, kus määratleme skripti käivitamise:
ExternalParameter = HTTPS.CertificateExpireDateSimple: powershell.exe -File "servershareNetXMS_CertExpireDateSimple.ps1"Kuna skripti käivitatakse võrgu kaudu, ei tohi unustada , samuti ei tohi unustada muid teateid nagu „-NoLogo -NoProfile -NonInteractive”, mille ma koodi parema loetavuse huvides igaks juhuks välja jätsin.
Kuna tulemuseks on agendi konfiguratsioon, näeb see välja umbes selline:
#
# 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"Seejärel tuleb konfiguratsioon salvestada ja agent uuesti käivitada. Seda saab teha NetXMS keskuses: avada konfiguratsioon (Edit agent’s configuration file), redigeerida, rakendada Save&Apply, mille tulemusena toimub sama asi. Seejärel loetakse konfiguratsioon uuesti (Poll > Configuration), kui ei jaksa oodata. Pärast neid toiminguid peaks olema võimalik lisada meie kohandatud parameeter.
NetXMS keskuses läheneme Andmete kogumise konfiguratsioon server, mille me kavatseme sertifikaate jälgida ja loome seal uue parameetri (hiljem, pärast seadistamist, on mõtet see malli viia). Valime nimekirjast HTTPS.CertificateExpireDateSimple, kirjutame Descriptioni mõistetava nimega, seame tüübiks Integer ja kohandame küsitavuse intervalli. Debugimise ajaks on mõistlik teha see lühemaks, näiteks 30 sekundiks. Kõik, valmis, praegu piisab.
Saame kontrollida... ei, on veel vara. Praegu ei saa me loomulikult midagi. Lihtsalt seetõttu, et skripti pole veel kirjutatud. Parandame selle puuduva osa. Skript väljastab lihtsalt numbri, päevade arvu, mis on jäänud sertifikaadi kehtivusaja lõpuni. Kõige minimaalne kõigist olemasolevatest. Skripti näide:
proovida {
# Saame kõik sertifikaadid sertifikaadihoidlast
$lmSertifikaadid = @( Get-ChildItem -Recurse -path 'Cert:LocalMachineMy' -ErrorAction Stop )
# Kui sertifikaate pole, tagastame "10 aastat"
if ($lmSertifikaadid.Count -eq 0) { return 3650 }
# Saame kõigi sertifikaatide lõppkuupäeva
$lõppkuupäevad = @( $lmSertifikaadid | ForEach-Object { return $_.NotAfter } )
# Saame kõigist kõige lähem lõppkuupäeva
$minLõppkuupäev = ($lõppkuupäevad | Measure-Object -Minimum -ErrorAction Stop ).Minimum
# Konverteerime kõige lähem lõppkuupäeva allesjäänud päevade arvuks, ümardades allapoole
$päeviJäänud = [Math]::Floor( ($minLõppkuupäev - [DateTime]::Now).TotalDays )
# Tagastame väärtuse
return $päeviJäänud
}
catch {
return -1
}Nii see välja käib:

723 päeva, kuni sertifikaadi kehtivusaeg lõpeb veel peaaegu kaks aastat. Loogiline, sest Exchange'i testkeskkonna sertifikaate uuendasin ma täiesti hiljuti.
See oli lihtne variant. Tõenäoliselt meeldib see kellelegi, kuid meie soovisime midagi enamat. Seadsime endale eesmärgi saada loetelu kõigist serveris olevatest sertifikaatidest koos nimedega ja nähtavaks, kui palju päevi on sertifikaadi kehtivusajani jäänud.
Teine variant, mõnevõrra keerulisem.
Jällegi redigeerime agendi konfiguratsiooni ja seal, selle rea asemel, mis sisaldab ExternalParameter, kirjutame kaks teist:
ExternalList = HTTPS.CertificateNames: powershell.exe -File "serversharenetxms_CertExternalNames.ps1"
ExternalParameter = HTTPS.CertificateExpireDate(*): powershell.exe -File "serversharenetxms_CertExternalParameter.ps1" -CertificateId "$1"V ExternalList saame lihtsalt nimekirja. Meie puhul on see nimekiri sertifikaatide nimedega. Saame selle nimekirja skripti abil. Nimekirja nimi on — 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)"
}
}Ja ExternalParameter sisestame me nimekirjast ExternalList read ja väljundiks saame sama arvu päevi igaühe jaoks. Identifikaatorina kasutatakse sertifikaadi Thumbprint'i. Pange tähele, et HTTPS.CertificateExpireDate selles variandis sisaldab tärni (*). See on vajalik selleks, et see võtaks vastu välised muutujad, nimelt meie 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)"
}Serveri Andmete Kogumise Konfiguratsioonis loome uue parameetri. Parameetri valimisel valime meie HTTPS.CertificateExpireDate(*) nimekirjast ja, (tähelepanu!) muudame tärni {instance}. See oluline hetk võimaldab luua iga instantsi (sertifikaadi) jaoks eraldi arvesti. Ülejäänud täidetakse nagu eelnevas variandis:

Selleks, et loota saaks luua, tuleb vahekaardil Instance Discovery valida Agent List ja kirjutada List Name väljale meie ExternalListi nimi skriptist — HTTPS.CertificateNames.
Peaaegu valmis, veidi oodata või sundida Poll > Configuration ja Poll > Instance Discovery, kui tõeliselt ei saa oodata. Tulemusena saame kõik meie sertifikaadid koos kehtivusaegadega:
Kas see on see, mida vaja? Jah, aga perfektsionismi pisik vaatab selle tarbetu Thumbprint'i nime sees kurbade silmadega ja ei lase artiklit lõpetada. Selle ära toidmiseks avame jälle loendi omadused ja vahekaardil Instance Discovery lisame väljale „Instance discovery filter script” kirjutatud (NetXMSi sisekeele) skripti:
instance = $1;
if (instance ~= "^(.*)s-s[T:[a-zA-Z0-9]+]$")
{
return %(true, instance, $1);
}
return true;mis filtreerib välja Thumbprint'i:

Ja et seda kuvataks filtreerituna, muudame vahekaardil General Description väljas CertificateExpireDate: {instance} järgmiseks CertificateExpireDate: {instance-name}:

Kõik, lõpuks finish KDPV-st:
Kena, eks?
Küsimus on vaid veel seadistada teavitused, et need tuleksid e-posti, kui sertifikaadi tähtaeg läheneb oma loogilisele lõpule.
1. Esiteks tuleb luua sündmuste mall (Event Template), et aktiveerida see, kui loenduri väärtus langeb meie määratud lävepunkti. Näiteks Sündmuse seadistamine loome kaks uut mall, näiteks nimega CertificateExpireDate_Threshold_Activate hoiatusseisundiga:

ja sarnane CertificateExpireDate_Threshold_Deactivate tavaseisundiga.
2. Järgmine samm on minna loenduri omadustesse ja vahekaardil Tresholds seadistada läve:

valime meie loodud sündmused CertificateExpireDate_Threshold_Activate ja CertificateExpireDate_Threshold_Deactivate, määrame mõõtmisarvu (Samples) 1 (konkreetse selle loenduri puhul pole enam mõtet määrata), väärtus 30 (päeva), näiteks, ja mis oluline, seadistame sündmuse kordamise aja. Tootmises olevate sertifikaatide puhul seadistan korduse iga päev (86400 sekundit), vastasel juhul võib teateid tulla liiga palju (nagu juhtus ka ühel korral, nii et postkast täitus nädalavahetusega). Läbivaatamise ajal on mõistlik seadistada lühem, näiteks 60 sekundit.
3. A Tegevuse seadistamine loome teate emaili šablooni, näiteks sellise:

Kõik need %m, %S jne on makrod, kuhu sisestatakse väärtused meie parameetrist. Rohkem teavet on kirjeldatud NetXMS.
4. Ja lõpuks, kokku ühendades eelnevad punktid, Sündmuste töötlemise poliitika loome reegli, mille alusel luuakse Alarm ja saadetakse kiri:
Salvestame poliitika, kõik, saame testida. Seame künnise veidi kõrgemaks, et kontrollida. Mul on lähim sertifikaat aegumas 723 päeva pärast, seetõttu seadsin 724. Tulemuseks saame sellise alarmi:

ja sellise teate e-postile:

Nüüd on tõesti kõik. Loomulikult oleks võimalik seadistada armatuurlaud, koostada diagramme, kuid sertifikaatide puhul oleks need üsna mõttetud ja igavad sirged jooned, erinevalt näiteks protsessori või mälu koormuse graafikutest. Kuid sellest räägime kunagi hiljem.
Allikas: habr.com
