Hiljuti tekkis meil probleem Windows-serverite sertifikaatide kehtivuse jälgimisega. Kuidas see tekkis? Pärast seda, kui sertifikaadid korduvalt „prinssideks” muundusid, just siis, kui nende pikendamise eest vastutav habe omav kolleeg oli puhkusele läinud. Seetõttu hakkasime kahtlema ja otsustasime sellele mõelda. Kuna meil on järk-järgult kasutusele võetud NetXMS jälgimissüsteem, sai sellest peamine ja põhimõtteliselt ainus kandidaat selle ülesande täitmiseks.
Lõpp tulemuseks saadi sellisel kujul:

Ja nüüd protsess ise.
Hakkame pihta. NetXMS-is ei ole sisseehitatud sertifikaatide aegumise loendust, seega tuleb luua oma ja kasutada skripte selle andmete hankimiseks. Muidugi Powershellis, see ju Windows. Skript peab lugema kõik sertifikaadid operatsioonisüsteemis, võtma sealt nende aegumise päevade arvu ja edastama selle arvu NetXMS-ile. Läbi selle agendi. Alustame just sellest.
Esimene variant, kõige lihtsam. Lihtsalt võtta päevade arv, mis on jäänud kuni sertifikaadi aegumise kuupäevani.
Kuna NetXMS-server peab teadma meie kohandatud parameetri olemasolust, peab ta selle saama agentilt. Vastasel korral ei ole võimalik seda parameetrit lisada, kuna selle olemasolu puudub. Seetõttu lisame agendi konfiguratsioonifaili nxagentd.conf välist parameetri rea nimega HTTPS.CertificateExpireDateSimple, kuhu kirjutame skripti käivitamise:
ExternalParameter = HTTPS.CertificateExpireDateSimple: powershell.exe -File "servershareNetXMS_CertExpireDateSimple.ps1"Arvestades, et skript käivitatakse võrgus, tuleb mitte unustada , samuti mitte unustada muid „-NoLogo -NoProfile -NonInteractive” lippude väärtusi, mille ma koodi arusaadavuse nimel jätan välja.
Kuna tulemuseks on agentide konfiguratsioon, näeb see välja umbes nii:
#
# 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 taaskäivitada. Seda saab teha NetXMS-i konsoolist: avada konfiguratsioon (Edit agent’s configuration file), redigeerida, teha Save&Apply, mille tulemusena toimub tegelikult see sama. Seejärel võib konfiguratsiooni uuesti lugeda (Poll > Configuration), kui ei ole jõudu oodata. Pärast neid toiminguid peaks olema võimalik lisada meie kohandatud parameeter.
NetXMS-i konsoolis liigume Andmekogumise konfiguratsiooni katsetusserverist, millel me plaanime sertifikaate jälgida, ja loome seal uue parameetri (hiljem, pärast seadistamist, on mõistlik see malli viia). Valime loendist HTTPS.CertificateExpireDateSimple, sisestame Kirjelduse arusaadava nimega, määrame tüübiks Integer ja seadistame küsitluse vaheaja. Veidiks ajaks on mõistlik teha see lühemaks, näiteks 30 sekundiks. Kõik, valmis, praegu piisab.
Saame kontrollida... ei, on veel liiga vara. Praegu ei saa me loomulikult midagi. Lihtsalt sellepärast, et skripti pole veel kirjutatud. Parandame selle puuduse. Skript kuvab lihtsalt numbri, päevade arvu, mis on jäänud sertifikaadi kehtivuse lõpuni. Kõige minimaalne, mis on olemas. Skripti näidis:
try {
# Saame kõik sertifikaadid sertifikaadi hoidjast
$lmCertificates = @( Get-ChildItem -Recurse -path 'Cert:LocalMachineMy' -ErrorAction Stop )
# Kui sertifikaate pole, tagastame "10 aastat"
if ($lmCertificates.Count -eq 0) { return 3650 }
# Saame kõigi sertifikaatide kehtivuse kuupäeva
$expirationDates = @( $lmCertificates | ForEach-Object { return $_.NotAfter } )
# Saame kõigi sertifikaatide hulgast lähima kehtivuse kuupäeva
$minExpirationDate = ($expirationDates | Measure-Object -Minimum -ErrorAction Stop ).Minimum
# Muudame lähima kehtivuse kuupäeva päevade arvuks, ümardades allapoole
$daysLeft = [Math]::Floor( ($minExpirationDate - [DateTime]::Now).TotalDays )
# Tagastame väärtuse
return $daysLeft
}
catch {
return -1
}Tuleb välja nii:

723 päeva, kehtivusaeg sertifikaadi lõpuni on veel peaaegu kaks aastat. Loogiline, kuna ma uuendasin sertifikaate testkeskkonna Exchange'is suhteliselt hiljuti.
See oli lihtne variant. Ehk kellelegi sobib see, aga me tahtsime rohkem. Panime endale ülesande saada serverilt kõigi sertifikaatide loetelu, nimeliselt, ja igaühe puhul näha, kui palju päevi on kehtivuse lõpuni jäänud.
Teine variant, veidi keerulisem.
Taas redigeerime agendi konfiguratsiooni ja seal, ExternalParameter'i rida asemel, kirjutame kaks muud rida:
ExternalList = HTTPS.CertificateNames: powershell.exe -File "serversharenetxms_CertExternalNames.ps1"
ExternalParameter = HTTPS.CertificateExpireDate(*): powershell.exe -File "serversharenetxms_CertExternalParameter.ps1" -CertificateId "$1"Uues ExternalList me saame lihtsalt ridade loetelu. Meie puhul ridade loetelu sertifikaatide nimedest. Selle ridade loetelu saame skriptiga. Loendi 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 juba ExternalParameter Meie sisendiks on ExternalList'i nimekirjast read, mille väljastuseks saame sama arvu päevi igaühe jaoks. Tuvastajana toimib sertifikaadi Thumbprint. Pange tähele, et HTTPS.CertificateExpireDate sisaldab selles versioonis tärni (*). See on vajalik selleks, et see aktsepteeriks väliseid muutujaid, 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 seadistustes loome uue parameetri. Valige Parameetri alt meie HTTPS.CertificateExpireDate(*) loendist ja (tähelepanu!) vahetame tärni {instance}. See oluline detail võimaldab luua iga instantsi (sertifikaadi) jaoks eraldi loenduri. Ülejäänu täidetakse nagu eelnevas versioonis:

Loendurite loomiseks tuleb Instantsi avastamise vahelehel valida Agent List loendist ja kirjutada Loendi nime väljale meie ExternalList'i nimi skriptist — HTTPS.CertificateNames.
Peaaegu valmis, veidi oodata või sundida Poll > Configuration ja Poll > Instance Discovery, kui on tõeliselt raske oodata. Tulemusena saame kõik meie sertifikaadid kehtivusajad:
Kas see on see, mida vaja? Jah, aga perfektsionismi kripeldus vaatab selle vajalikku Thumbprint’i loendi nime ja ei lase artiklit lõpetada. Selle rahuldamiseks avame uuesti loenduri omadused ja Instantsi avastamise vahelehel lisame välja «Instance discovery filter script» järgmise kirjutatud (NetXMS-i sisekeeles) skripti:
instance = $1;
if (instance ~= "^(.*)s-s[T:[a-zA-Z0-9]+]$")
{
return %(true, instance, $1);
}
return true;mis filtreerib Thumbprint’i:

Ja et seda filtreerituna kuvada, muudame Üldine vahekaart Description väljale CertificateExpireDate: {instance} kuju CertificateExpireDate: {instance-name}:

Oleme lõpuks finiši joone taga:
Kas pole ilus?
Jäänud on seadistada teavitused, et need saadetaks meilile, kui sertifikaadi aeg lõpeb.
1. Esiteks tuleb luua sündmuse mall (Event Template), et aktiveerida see, kui loenduri väärtus langeb meie poolt määratud piirini. A Event Configuration loome kaks uut malli, nimetades need näiteks CertificateExpireDate_Threshold_Activate hoiatuse staatuses:

ja analoogne CertificateExpireDate_Threshold_Deactivate või normaalse staatusena.
2. Seejärel liigume loenduri omadustesse ja vahekaartide Tresholds all seadistame piiri:

Kus valime meie loodud üritusi CertificateExpireDate_Threshold_Activate ja CertificateExpireDate_Threshold_Deactivate, määrame mõõtmiste arvu (Samples) 1 (konkreetselt selle arvesti jaoks pole mõtet rohkem määrata), väärtuse 30 (päeva) näiteks ja, mis oluline, seadistame ürituse kordamise aja. Tootmise sertifikaatide puhul seadsin igapäevaseks (86400 sekundit), muidu võib teavitustega ära uppuda (mida juhtuski üks kord, nii et nädalavahetusel sai postkast üle voolatud). Silumise ajal on mõistlik seada väiksem, näiteks 60 sekundit.
3. V Action Configuration loome teavituse e-kirja mall, nagu näiteks:

Kõik need %m, %S jne - makrod, kuhu hõlmatakse väärtused meie parameetrist. Üksikasjalikumalt on need kirjeldatud NetXMS.
4. Ja lõpuks, ühendades eelnevad punktid, loome Event Processing Policy reegli, mille alusel luuakse Alarm ja saadetakse kiri:
Salvestame poliitika, kõik, saab testida. Seame künnise kõrgemaks, et kontrollida. Minu lähim sertifikaat aegub 723 päeva pärast, kontrollimiseks seadsin 724. Tulemuseks saame sellise alarmi:

ja sellise teavituse e-posti teel:

Nüüd on tõepoolest kõik. Loomulikult oleks olnud võimalik seadistada armatuurlaud, luua diagramme, kuid sertifikaatide puhul oleks need mõned mõttetud ja igavad sirged jooned, erinevalt näiteks protsessori või mälu koormuse diagrammidest. Kuid sellest räägime järgmisel korral.
Allikas: habr.com
