Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

Нядаўна ў нас устала задача маніторынгу тэрміна дзеяння сертыфікатаў на серверах з Windows. Ну як устала, пасля таго, як сертыфікаты некалькі разоў ператвараліся ў гарбуз, у той самы час, калі адказны за іх падаўжэнне барадаты калега знаходзіўся ў адпачынку. Пасля гэтага мы з ім нешта западозрылі вырашылі над гэтым задумацца. Бо ў нас павольна ўкараняецца сістэма маніторынгу NetXMS, яна і стала галоўным і, у прынцыпе, адзіным кандыдатам на гэтую задачу.

Вынік у выніку быў атрыманы ў такім выглядзе:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

А сам працэс далей.

Паехалі. Убудаванага лічыльніка які сканчаецца тэрміна сертыфікатаў у NetXMS няма, таму трэба ствараць свой і выкарыстоўваць скрыпты для забеспячэння яго дадзенымі. Вядома, на Powershell, гэта ж Windows. Скрыпт павінен прачытаць усе сертыфікаты ў аперацыйнай сістэме, узяць адтуль тэрмін іх заканчэння ў днях і перадаць гэты лік у NetXMS. Праз яго агента. Вось з яго і пачнем.

Варыянт першы, самы просты. Проста атрымаць колькасць дзён да заканчэння тэрміну дзеяння сертыфіката з бліжэйшай датай.

Каб сервер NetXMS даведаўся аб існаванні нашага кастамнага параметра, ён павінен атрымаць яго ад агента. Інакш гэты параметр немагчыма будзе дадаць, з прычыны яго адсутнасці. Таму, у канфігурацыйны файл агента nxagentd.conf мы дадаем радок знешняга параметра з імем HTTPS.CertificateExpireDateSimple, у якой прапісваем запуск скрыпту:

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

Улічваючы, што скрыпт запускаецца па сетцы, трэба не забыцца пра Палітыка выканання, а гэтак жа не забыцца іншыя "-NoLogo -NoProfile -NonInteractive", якія я апусціў для лепшай чытальнасці кода.

У выніку чаго канфіг агента выглядае прыкладна так:

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

Пасля гэтага трэба захаваць канфіг і перазапусціць агента. Можна гэта зрабіць з кансолі NetXMS: адкрыць канфіг (Edit agent's confuguration file), адрэдагаваць, выканаць Save&Apply, у выніку чаго, уласна, адбудзецца тое ж самае. Затым перачытаць канфігурацыю (Poll> Configuration), калі зусім няма сіл пачакаць. Пасля гэтых дзеянняў павінна з'явіцца магчымасць дадаць наш кастамны параметр.

У кансолі NetXMS ідзем у Data Collection Configuration паддоследнага сервера, на якім мы сабраліся маніторыць сертыфікаты і ствараем тамака новы параметр (у далейшым, пасля налады, ёсць сэнс перанесці яго ў шаблоны). Выбіраем HTTPS.CertificateExpireDateSimple са спісу, упісваем Description са зразумелым імем, тып ставім Integer і наладжваем інтэрвал апытання. На час адладкі ёсць сэнс зрабіць яго карацейшым, 30 секунд, напрыклад. Усё, гатова, пакуль дастаткова.

Можна правяраць… не, яшчэ рана. Цяпер, натуральна, нічога мы не атрымаем. Проста таму, што скрыпт яшчэ не напісалі. Выпраўляем гэты недагляд. Скрыпт будзе выдаваць проста лічбу, колькасць дзён, якія засталіся да заканчэння тэрміну дзеяння сертыфіката. Самую мінімальную з усіх наяўных. Прыклад скрыпту:

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
}

Атрымліваецца так:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

723 дні, да заканчэння тэрміну дзеяння сертыфіката яшчэ амаль два гады. Лагічна, таму што сертыфікаты на Exchange тэставага стэнда я перавыпісваў зусім нядаўна.

Гэта быў просты варыянт. Мусіць, кагосьці і такі задаволіць, але нам жадалася большага. Задачу мы сабе паставілі атрымаць спіс усіх сертыфікатаў на серверы, пайменна, і ў кожнага бачыць колькасць дзён, якія засталіся да заканчэння тэрміну дзеяння сертыфіката.

Другі варыянт, некалькі больш складана.

Ізноў рэдагуем канфіг агента і там замест радка з ExternalParameter пішам дзве іншыя:

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

В ExternalList мы атрымліваем проста спіс радкоў. У нашым выпадку, спіс радкоў з імёнамі сертыфікатаў. Спіс гэтых радкоў мы атрымаем скрыптам. Імя спісу HTTPS.CertificateNames.

Скрыпт 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)"
    }
}

А ўжо ў ExternalParameter мы на ўваход падаем радкі са спісу ExternalList, а на выхадзе атрымаем усё тое ж колькасць дзён для кожнай. Ідэнтыфікатарам служыць Thumbprint сертыфіката. Звярніце ўвагу, што HTTPS.CertificateExpireDate у гэтым варыянце змяшчае зорачку (*). Гэта неабходна для таго, каб ён прымаў вонкавыя зменныя, як раз наш CertificateId.

Скрыпт 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)"
}

У Data Collection Configuration сервера ствараем новы параметр. У Parameter выбіраемы наш HTTPS.CertificateExpireDate(*) са спісу, і, (увага!) змяняем зорачку на {instance}. Гэты важны момант дазволіць стварыць асобны лічыльнік для кожнага інстанса (сертыфіката). Астатняе запаўняецца, як у папярэднім варыянце:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

Для таго, каб лічыльнікі было з чаго ствараць, на ўкладцы Instance Discovery трэба абраць Agent List са спісу і ў поле List Name упісаць імя нашага ExternalList са скрыпту - HTTPS.CertificateNames.

Амаль гатова, крыху пачакаць ці прымусова зрабіць Poll > Configuration і Poll > Instance Discovery, калі зусім немагчыма чакаць. У выніку атрымліваем усе нашы сертыфікаты з тэрмінамі дзеяння:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

Тое, што трэба? Ну так, толькі чарвячок перфекцыянізму глядзіць на гэты непатрэбны Thumbprint у імя лічыльніка сумнымі вачыма і ніяк не дае скончыць артыкул. Каб яго накарміць, зноў адчыняны ўласцівасці лічыльніка і на ўкладцы Instance Discovery у поле "Instance discovery filter script" дадаем напісаны на NXSL (унутранай мове NetXMS) скрыпт:

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

які будзе адфільтроўваць Thumbprint:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

А каб яго адлюстраваць адфільтраваным, на ўкладцы General у поле Description змяняем CertificateExpireDate: {instance} на CertificateExpireDate: {instance-name}:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

Усё, нарэшце фініш з КДПВ:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

Прыгажосць жа?

Засталося наладзіць абвесткі, каб яны прыходзілі на пошту, калі тэрмін сертыфіката падыходзіць да свайго лагічнага канца.

1. Спачатку трэба стварыць шаблон падзеі (Event Template) для актывацыі яго пры памяншэнні значэння лічыльніка да нейкага зададзенага намі парога. У Канфігурацыя падзеі ствараем два новыя шаблоны з імёнамі, скажам CertificateExpireDate_Threshold_Activate са статусам Warning:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

і аналагічны CertificateExpireDate_Threshold_Deactivate са статусам Normal.

2. Далей ідзем ва ўласцівасці лічыльніка і на ўкладцы Tresholds наладжваем парог:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

дзе выбіраемы нашы створаныя эвенты CertificateExpireDate_Threshold_Activate і CertificateExpireDate_Threshold_Deactivate, ставім колькасць замераў (Samples) 1 (канкрэтна для гэтага лічыльніка больш ставіць сэнсу няма), значэнне ў 30 (дзён), да прыкладу, і, што важна, на. Для сертыфікатаў у прадакшэне я стаўлю раз у суткі (86400 секунд), інакш можна патануць у абвестках (што, дарэчы і здарылася адзін раз, прычым так, што перапоўнілася паштовая скрыня за выходныя). На час адладкі ёсць сэнс паставіць паменш, 60 секунд, напрыклад.

3. У Action Configuration ствараем шаблон ліста абвесткі, тыпу такога:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

Усе гэтыя %m, %S і да т.п. - макрасы, у якія будуць падстаўлены значэння з нашага параметру. Больш падрабязна яны апісаны ў мануале NetXMS.

4. І, нарэшце, аб'ядноўваючы папярэднія пункты, у Event Processing Policy ствараем правіла, па якім будзе стварацца Alarm і апраўляцца ліст:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

Захоўваем палітыку, усё, можна тэсціраваць. Паставім парог вышэй, для праверкі. У мяне найбліжэйшы сертыфікат заканчваецца праз 723 дні, для праверкі паставіў 724. У выніку атрымаем такі аларм:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

і такое апавяшчэнне па пошце:

Маніторынг тэрміна дзеяння сертыфікатаў у Windows на NetXMS

Вось зараз сапраўды ўсё. Можна было б, вядома, наладзіць дашборд, пабудаваць графікі, але для сертыфікатаў гэта будуць некалькі бессэнсоўныя і сумныя прамыя лініі, у адрозненне ад графікаў загрузкі працэсара ці памяці, напрыклад. Але, пра гэта як-небудзь іншым разам.

Крыніца: habr.com

Дадаць каментар