Monitorando a data de expiração do certificado no Windows no NetXMS

Recentemente nos deparamos com a tarefa de monitorar o período de validade dos certificados em servidores Windows. Pois bem, como me levantei depois que os certificados viraram abóbora várias vezes, no exato momento em que o colega barbudo responsável pela renovação estava de férias. Depois disso, ele e eu suspeitamos de algo e decidimos pensar a respeito. Como estamos implementando lentamente o sistema de monitoramento NetXMS, ele se tornou o principal e, em princípio, o único candidato para esta tarefa.

O resultado foi finalmente obtido da seguinte forma:

Monitorando a data de expiração do certificado no Windows no NetXMS

E o processo em si continua.

Ir. Não há contador integrado para certificados expirados no NetXMS, então você precisa criar o seu próprio e usar scripts para fornecer dados. Claro, no Powershell, este é o Windows. O script deve ler todos os certificados do sistema operacional, calcular a data de validade em dias a partir daí e passar esse número para o NetXMS. Através de seu agente. É por aí que começaremos.

Uma opção, mais simples. Basta obter o número de dias até a data de vencimento do certificado com a data mais próxima.

Para que o servidor NetXMS saiba da existência do nosso parâmetro customizado, ele deve recebê-lo do agente. Caso contrário, este parâmetro não poderá ser adicionado devido à sua ausência. Portanto, no arquivo de configuração do agente nxagentd.conf adicionamos uma string de parâmetro externo chamada HTTPS.CertificateExpireDateSimple, no qual registramos o lançamento do script:

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

Considerando que o script é lançado pela rede, é preciso lembrar Política de Execução, e também não se esqueça do outro “-NoLogo -NoProfile -NonInteractive”, que omiti para melhor legibilidade do código.

Como resultado, a configuração do agente é mais ou menos assim:

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

Depois disso, você precisa salvar a configuração e reiniciar o agente. Você pode fazer isso a partir do console NetXMS: abrir o config (Editar arquivo de configuração do agente), editá-lo, executar Save&Apply, e como resultado, de fato, acontecerá a mesma coisa. Em seguida, releia a configuração (Enquete > Configuração), se você não tiver forças para esperar. Após essas etapas, você poderá adicionar nosso parâmetro personalizado.

No console NetXMS vá para Configuração de coleta de dados servidor experimental no qual vamos monitorar os certificados e aí criar um novo parâmetro (no futuro, após a configuração, faz sentido transferi-lo para templates). Selecione HTTPS.CertificateExpireDateSimple na lista, insira uma Descrição com um nome claro, defina o tipo como Inteiro e configure o intervalo de pesquisa. Para fins de depuração, faz sentido torná-lo mais curto, 30 segundos, por exemplo. Está tudo pronto, por enquanto chega.

Você pode verificar... não, é muito cedo. Agora, é claro, não conseguiremos nada. Simplesmente porque o roteiro ainda não foi escrito. Vamos corrigir esta omissão. O script simplesmente exibirá um número, o número de dias restantes até que o certificado expire. O mais mínimo de todos disponíveis. Roteiro de exemplo:

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
}

Acontece assim:

Monitorando a data de expiração do certificado no Windows no NetXMS

723 dias, faltam quase dois anos para o certificado expirar. É lógico, porque reemiti certificados para o banco de testes do Exchange recentemente.

Foi uma opção fácil. Provavelmente alguém ficará satisfeito com isso, mas queríamos mais. Nos propusemos a obter uma lista de todos os certificados do servidor, por nome, e para cada um ver quantos dias faltam para o certificado expirar.

A segunda opção, um pouco mais complicado.

Novamente editamos a configuração do agente e ali, ao invés da linha com ExternalParameter, escrevemos outras duas:

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

В Lista externa apenas obtemos uma lista de strings. No nosso caso, uma lista de strings com nomes de certificados. Receberemos uma lista dessas linhas usando o script. Lista de nomes - HTTPS.CertificateNames.

Script 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)"
    }
}

E já em Parâmetro Externo Inserimos linhas da lista ExternalList e, na saída, obtemos o mesmo número de dias para cada uma. O identificador é a impressão digital do certificado. Observe que HTTPS.CertificateExpireDate contém um asterisco (*) nesta variante. Isso é necessário para que ele aceite variáveis ​​externas, apenas o nosso CertificateId.

Script 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)"
}

Na Configuração de Coleta de Dados do servidor, criamos um novo parâmetro. Em Parâmetro selecionamos nosso HTTPS.CertificateExpireDate(*) da lista e (atenção!) mude o asterisco para {instância}. Este ponto importante permitirá criar um contador separado para cada instância (certificado). O restante é preenchido como na versão anterior:

Monitorando a data de expiração do certificado no Windows no NetXMS

Para ter algo para criar contadores, na guia Descoberta de Instância você precisa selecionar Lista de Agentes na lista e no campo Nome da Lista inserir o nome de nossa Lista Externa do script - HTTPS.CertificateNames.

Quase pronto, espere um pouco ou force Poll > Configuration and Poll > Instance Discovery se for completamente impossível esperar. Como resultado, obtemos todos os nossos certificados com prazos de validade:

Monitorando a data de expiração do certificado no Windows no NetXMS

O que você precisa? Pois é, só o verme do perfeccionismo olha com tristeza para essa impressão digital desnecessária no nome do contador e não me deixa terminar o artigo. Para alimentá-lo, abra novamente as propriedades do contador e na aba Instance Discovery, no campo “Instance Discovery filter script”, adicione aquele escrito em NXSL Script (linguagem interna NetXMS):

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

que filtrará a impressão digital:

Monitorando a data de expiração do certificado no Windows no NetXMS

E para exibi-lo filtrado, na aba Geral do campo Descrição, altere CertificateExpireDate: {instance} para CertificateExpireDate: {nome da instância}:

Monitorando a data de expiração do certificado no Windows no NetXMS

É isso, finalmente a linha de chegada do KDPV:

Monitorando a data de expiração do certificado no Windows no NetXMS

É beleza?

Resta configurar alertas para que cheguem por e-mail quando o certificado expirar.

1. Primeiro precisamos criar um Event Template para ativá-lo quando o valor do contador diminuir para algum limite que definimos. EM Configuração do evento vamos criar dois novos modelos com nomes como CertificadoExpireDate_Threshold_Activate com status de aviso:

Monitorando a data de expiração do certificado no Windows no NetXMS

e semelhante CertificadoExpireDate_Threshold_Deactivate com status Normal.

2. Em seguida, vá para as propriedades do contador e defina o limite na guia Limites:

Monitorando a data de expiração do certificado no Windows no NetXMS

onde selecionamos nossos eventos criados CertificateExpireDate_Threshold_Activate e CertificateExpireDate_Threshold_Deactivate, definimos o número de amostras (Samples) como 1 (especificamente para este contador não faz sentido definir mais), o valor é 30 (dias), por exemplo, e, mais importante, definir o tempo de repetição do evento. Para certificados em produção, configurei uma vez por dia (86400 segundos), caso contrário você pode se afogar em notificações (o que, aliás, aconteceu uma vez, tanto que a caixa de correio ficou cheia no fim de semana). Para o tempo de depuração, faz sentido defini-lo para menos, 60 segundos, por exemplo.

3. Em Configuração da ação crie um modelo de carta de notificação, como este:

Monitorando a data de expiração do certificado no Windows no NetXMS

Todos esses %m, %S, etc. — macros nas quais os valores do nosso parâmetro serão substituídos. Eles são descritos com mais detalhes em manual NetXMS.

4. E por fim, combinando os pontos anteriores, em Política de Processamento de Eventos crie uma regra segundo a qual um Alarme será criado e uma carta será enviada:

Monitorando a data de expiração do certificado no Windows no NetXMS

Salvamos a política, tudo pode ser testado. Vamos definir um limite mais alto para verificar. Meu certificado mais próximo expira em 723 dias, configurei-o para 724 para verificar. Como resultado, recebemos o seguinte alarme:

Monitorando a data de expiração do certificado no Windows no NetXMS

e esta notificação por e-mail:

Monitorando a data de expiração do certificado no Windows no NetXMS

Isso é tudo certo agora. Seria possível, claro, montar um dashboard e construir gráficos, mas para certificados seriam linhas retas um tanto sem sentido e enfadonhas, ao contrário de gráficos de carga de processador ou memória, por exemplo. Mas, falaremos mais sobre isso em outra ocasião.

Fonte: habr.com

Adicionar um comentário