Дата на изтичане на сертификата за наблюдение в 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: отворете конфигурацията (Редактиране на конфигурационния файл на агента), редактирайте го, изпълнете Save&Apply, в резултат на което всъщност ще се случи същото. След това прочетете отново конфигурацията (Анкета > Конфигурация), ако изобщо нямате сили да чакате. След тези стъпки трябва да можете да добавите нашия персонализиран параметър.

В конзолата NetXMS отидете на Конфигурация за събиране на данни експериментален сървър, на който ще наблюдаваме сертификати и ще създадем там нов параметър (в бъдеще, след конфигуриране, има смисъл да го прехвърлим в шаблоните). Изберете HTTPS.CertificateExpireDateSimple от списъка, въведете описание с ясно име, задайте типа на 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"

В Външен списък просто получаваме списък от низове. В нашия случай списък от низове с имена на сертификати. Ще получим списък с тези редове с помощта на скрипта. Име на списъка - 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)"
    }
}

И вече в Външен параметър Въвеждаме редове от списъка 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)"
}

В конфигурацията за събиране на данни на сървъра създаваме нов параметър. В Parameter избираме нашия HTTPS.CertificateExpireDate(*) от списъка и (внимание!) променете звездичката на {instance}. Тази важна точка ще ви позволи да създадете отделен брояч за всеки екземпляр (сертификат). Останалото се попълва както в предишната версия:

Дата на изтичане на сертификата за наблюдение в Windows на NetXMS

За да има от какво да създаваме броячи, в раздела Instance Discovery трябва да изберете Agent List от списъка и в полето List Name да въведете името на нашия ExternalList от скрипта - HTTPS.CertificateNames.

Почти готово, изчакайте малко или принудете Анкета > Конфигурация и Анкета > Откриване на екземпляр, ако е напълно невъзможно да чакате. В резултат на това получаваме всички наши сертификати със срокове на валидност:

Дата на изтичане на сертификата за наблюдение в Windows на NetXMS

Какво ти е необходимо? Ами да, само червеят на перфекционизма гледа този ненужен Thumbprint в името на брояча с тъжни очи и не ми дава да довърша статията. За да го подадете, отворете отново свойствата на брояча и в раздела Откриване на екземпляр, в полето „Скрипт за филтър за откриване на екземпляр“, добавете написаното в NXSL (вътрешен език на NetXMS) скрипт:

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

който ще филтрира Thumbprint:

Дата на изтичане на сертификата за наблюдение в Windows на NetXMS

И за да го покажете филтриран, в раздела Общи в полето Описание променете CertificateExpireDate: {instance} на CertificateExpireDate: {instance-name}:

Дата на изтичане на сертификата за наблюдение в Windows на NetXMS

Това е всичко, най-накрая финалната линия от KDPV:

Дата на изтичане на сертификата за наблюдение в Windows на NetXMS

Не е ли красота?

Остава само да настроите известия, така че да пристигат по имейл, когато сертификатът изтече.

1. Първо трябва да създадем шаблон за събитие, за да го активираме, когато стойността на брояча намалее до някакъв праг, който сме задали. IN Конфигурация на събитието нека създадем два нови шаблона с имена като CertificateExpireDate_Threshold_Activate със статус Предупреждение:

Дата на изтичане на сертификата за наблюдение в Windows на NetXMS

и други подобни CertificateExpireDate_Threshold_Deactivate с нормално състояние.

2. След това отидете на свойствата на брояча и задайте прага в раздела Прагове:

Дата на изтичане на сертификата за наблюдение в Windows на NetXMS

където избираме нашите създадени събития CertificateExpireDate_Threshold_Activate и CertificateExpireDate_Threshold_Deactivate, задаваме броя на пробите (Samples) на 1 (конкретно за този брояч няма смисъл да задаваме повече), стойността е 30 (дни) например и, което е важно, задаваме времето за повторение на събитието. За сертификати в производство го задавам веднъж на ден (86400 секунди), в противен случай можете да се удавите в известия (което, между другото, се случи веднъж, толкова много, че пощенската кутия беше пълна през уикенда). За времето за отстраняване на грешки има смисъл да го зададете по-ниско, например 60 секунди.

3. В Конфигурация на действие създайте шаблон за уведомително писмо, като този:

Дата на изтичане на сертификата за наблюдение в Windows на NetXMS

Всички тези %m, %S и т.н. — макроси, в които ще бъдат заменени стойностите от нашия параметър. Те са описани по-подробно в ръководство NetXMS.

4. И накрая, комбинирайки предишните точки, в Политика за обработка на събития създайте правило, според което ще бъде създадена аларма и ще бъде изпратено писмо:

Дата на изтичане на сертификата за наблюдение в Windows на NetXMS

Запазваме полицата, всичко може да се тества. Нека зададем прага по-висок, за да проверим. Най-близкият ми сертификат изтича след 723 дни, за проверка го настроих на 724. В резултат на това получаваме следната аларма:

Дата на изтичане на сертификата за наблюдение в Windows на NetXMS

и това имейл известие:

Дата на изтичане на сертификата за наблюдение в Windows на NetXMS

Това вече е сигурно. Би било възможно, разбира се, да се създаде табло и да се изградят графики, но за сертификатите това биха били малко безсмислени и скучни прави линии, за разлика от графиките на натоварването на процесора или паметта, например. Но за това някой друг път.

Източник: www.habr.com

Добавяне на нов коментар