Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

Recientemente nos enfrentamos a la tarea de controlar el período de validez de los certificados en servidores Windows. Pues cómo me levanté después de que los certificados se convirtieran varias veces en calabaza, en el mismo momento en que el colega barbudo responsable de su renovación estaba de vacaciones. Después de eso, él y yo sospechamos algo y decidimos pensar en ello. Dado que poco a poco estamos implementando el sistema de monitorización NetXMS, se ha convertido en el principal y, en principio, el único candidato para esta tarea.

El resultado finalmente se obtuvo de la siguiente forma:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

Y el proceso en sí continúa.

Ir. No hay un contador incorporado para certificados vencidos en NetXMS, por lo que debe crear el suyo propio y utilizar scripts para proporcionarle datos. Por supuesto, en Powershell, esto es Windows. El script debe leer todos los certificados en el sistema operativo, tomar su fecha de vencimiento en días y pasar este número a NetXMS. A través de su agente. Ahí es donde comenzaremos.

Opción Uno, más simple. Simplemente obtenga el número de días hasta la fecha de vencimiento del certificado con la fecha más cercana.

Para que el servidor NetXMS sepa de la existencia de nuestro parámetro personalizado debe recibirlo del agente. De lo contrario, este parámetro no se podrá agregar debido a su ausencia. Por lo tanto, en el archivo de configuración del agente nxagentd.conf agregamos una cadena de parámetro externo llamada HTTPS.CertificateExpireDateSimple, en el que registramos el lanzamiento del script:

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

Teniendo en cuenta que el script se inicia a través de la red, debe recordar acerca de Política de ejecución, y tampoco olvide el otro "-NoLogo -NoProfile -NonInteractive", que omití para mejorar la legibilidad del código.

Como resultado, la configuración del agente se parece a esto:

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

Después de esto, debe guardar la configuración y reiniciar el agente. Puede hacer esto desde la consola NetXMS: abra la configuración (Editar el archivo de configuración del agente), edítela, ejecute Guardar y Aplicar, como resultado de lo cual, de hecho, sucederá lo mismo. Luego vuelva a leer la configuración (Encuesta > Configuración), si no tiene fuerzas para esperar. Después de estos pasos, debería poder agregar nuestro parámetro personalizado.

En la consola NetXMS, vaya a Configuración de recopilación de datos Servidor experimental en el que monitorearemos los certificados y crearemos un nuevo parámetro allí (en el futuro, después de la configuración, tiene sentido transferirlo a plantillas). Seleccione HTTPS.CertificateExpireDateSimple de la lista, ingrese una Descripción con un nombre claro, establezca el tipo en Integer y configure el intervalo de sondeo. Para fines de depuración, tiene sentido acortarlo, 30 segundos, por ejemplo. Todo está listo, por ahora es suficiente.

Puedes comprobarlo... no, es demasiado pronto. Ahora, por supuesto, no obtendremos nada. Simplemente porque aún no se ha escrito el guión. Corrijamos esta omisión. El script simplemente mostrará un número, el número de días que quedan hasta que caduque el certificado. El más minimalista de todos los disponibles. Guión de ejemplo:

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
}

Resulta así:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

723 días, faltan casi dos años para que caduque el certificado. Es lógico, porque recientemente volví a emitir certificados para el banco de pruebas de Exchange.

Fue una opción fácil. Probablemente alguien estará satisfecho con esto, pero queríamos más. Nos propusimos la tarea de obtener una lista de todos los certificados que hay en el servidor, por nombre, y para cada uno ver el número de días que faltan para que caduque el certificado.

La segunda opción, algo más complicado.

Nuevamente editamos la configuración del agente y allí, en lugar de la línea con ExternalParameter, escribimos otras dos:

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

В Lista externa solo obtenemos una lista de cadenas. En nuestro caso, una lista de cadenas con nombres de certificados. Recibiremos una lista de estas líneas usando el script. Lista de nombres - HTTPS.Nombres de certificados.

Secuencia de comandos 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)"
    }
}

Y ya en Parámetro externo Ingresamos filas de la lista ExternalList y en la salida obtenemos la misma cantidad de días para cada una. El identificador es la huella digital del certificado. Tenga en cuenta que HTTPS.CertificateExpireDate contiene un asterisco (*) en esta variante. Esto es necesario para que acepte variables externas, solo nuestro CertificateId.

Secuencia de comandos 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)"
}

En la Configuración de Recogida de Datos del servidor, creamos un nuevo parámetro. En Parámetro seleccionamos nuestro HTTPS.CertificadoExpireDate(*) de la lista y (¡atención!) cambie el asterisco a {instancia}. Este importante punto le permitirá crear un contador separado para cada instancia (certificado). El resto se rellena como en la versión anterior:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

Para tener algo para crear contadores, en la pestaña Descubrimiento de instancias debe seleccionar Lista de agentes de la lista y en el campo Nombre de lista ingrese el nombre de nuestra Lista Externa del script: HTTPS.CertificateNames.

Ya casi listo, espera un poco o fuerza Encuesta > Configuración y Encuesta > Descubrimiento de Instancia si es completamente imposible esperar. Como resultado, obtenemos todos nuestros certificados con periodos de validez:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

¿Qué necesitas? Pues sí, sólo el gusano del perfeccionismo mira con ojos tristes esta innecesaria Huella Digital en el nombre del mostrador y no me deja terminar el artículo. Para alimentarlo, abra las propiedades del contador nuevamente y en la pestaña Descubrimiento de instancias, en el campo “Script de filtro de descubrimiento de instancias”, agregue el escrito en NXSL Script (lenguaje interno de NetXMS):

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

que filtrará la huella digital:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

Y para mostrarlo filtrado, en la pestaña General en el campo Descripción, cambie CertificateExpireDate: {instance} a CertificateExpireDate: {nombre-instancia}:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

Eso es todo, finalmente la línea de meta de KDPV:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

¿Es belleza?

Ya sólo queda configurar las alertas para que lleguen por correo electrónico cuando caduque el certificado.

1. Primero, necesitamos crear una plantilla de evento para activarla cuando el valor del contador disminuya hasta algún umbral que establezcamos. EN Configuración de eventos creemos dos nuevas plantillas con nombres como CertificadoExpireDate_Threshold_Activate con estado de Advertencia:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

y similar CertificateExpireDate_Threshold_Deactivate con estado Normal.

2. A continuación, vaya a las propiedades del contador y establezca el umbral en la pestaña Umbrales:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

donde seleccionamos nuestros eventos creados CertificateExpireDate_Threshold_Activate y CertificateExpireDate_Threshold_Deactivate, establecemos el número de muestras (Muestras) en 1 (específicamente para este contador no tiene sentido configurar más), el valor es 30 (días), por ejemplo, y, lo más importante, configuramos el tiempo de repetición del evento. Para los certificados en producción, lo configuro una vez al día (86400 segundos); de lo contrario, puede ahogarse en notificaciones (lo que, por cierto, sucedió una vez, tanto que el buzón estuvo lleno durante el fin de semana). Para el tiempo de depuración, tiene sentido establecerlo en un valor inferior, 60 segundos, por ejemplo.

3. En Configuración de acciones cree una plantilla de carta de notificación, como esta:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

Todos estos %m, %S, etc. — macros en las que se sustituirán los valores de nuestro parámetro. Se describen con más detalle en manual NetXMS.

4. Y finalmente, combinando los puntos anteriores, en Política de procesamiento de eventos cree una regla según la cual se creará una alarma y se enviará una carta:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

Guardamos la póliza, todo se puede probar. Establezcamos el umbral más alto para comprobarlo. Mi certificado más cercano caduca en 723 días, lo configuré en 724 para verificar. Como resultado, recibimos la siguiente alarma:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

y esta notificación por correo electrónico:

Monitoreo de la fecha de vencimiento del certificado en Windows en NetXMS

Eso es todo seguro ahora. Por supuesto, sería posible configurar un panel de control y crear gráficos, pero para los certificados estas serían líneas rectas aburridas y sin sentido, a diferencia de los gráficos de carga del procesador o de la memoria, por ejemplo. Pero hablaremos más sobre esto en otro momento.

Fuente: habr.com

Añadir un comentario