Nagios: Superviser les horloges Windows

L’objectif de ce plugin pour Nagios est de superviser l’heure sur les serveurs Windows non DC.

Les serveurs membres ne peuvent pas par défaut être interrogé en ntp comme les DC pour vérifier leur horloge.

J’utilise l’agent nsclient++ sur les serveurs afin de pouvoir exécuter des scripts PowerShell entre autre. On a donc:

Nagios => check_nrpe => script powershell => retour nagios

Cela fonctionne également sur les serveurs Core.

Si aucun serveur de référence n’est fourni, le script fonctionne ainsi:

  • Si un serveur de référence est fourni, utilisation de celui-ci
  • Sinon:
    • Si joint à un domaine, essaye de récupérer la variable logonserver. Si cela échoue, prend un DC au hasard. en cas d’erreur, essaye avec pool.ntp.org
    • Si n’est pas joint à un domaine, essaye avec pool.ntp.org

Fourni la « jigue » en temps que performance pour les graphes.

Configuration testée

Linux:

  • Centos 6.4 x64
  • Nagios 3.4.4
  • check_nrpe 2.13
  • Centreon 2.4.2

Windows:

  • Windows Server 2003 / 2008 R2 / 2012
  • nsclient++ 0.4.1 x64 et x86
  • Serveurs Core et normaux

Arguments du script

  • refTimeServer (AD find ou pool.ntp.org par défaut)
  • maxWarn (Avertissement si supérieur, en secondes) (1 par défaut)
  • maxError (Critique si supérieur, en secondes) (5 par défaut)

 

maxWarn et maxCrit doivent être des entiers

Exemples d’utilisation

Exemple en exécution directe PowerShell:

PS C:Program FilesNSClient++scripts> . .lotp_check_time.ps1 
OK:-00.0307684s - checked against pool.ntp.org|offset=-00.0307684s;1;5;
PS C:Program FilesNSClient++scripts>

Exécution NRPE:

[root~]# /usr/lib64/nagios/plugins/check_nrpe -H myserver -n -c check_time -a "myPDCServer" 1 5 
OK:+00.0671837s - checked against myPDCServer|'offset'=0.06718s;1;5
[root~]#

Installation:

Sur les Windows:

  • Activer l’exécution de scripts PowerShell non signés : Set-ExecutionPolicy RemoteSigned
  • copier le script dans C:Program FilesNSClient++scripts
  • Ajouter dans le fichier nsclient.ini:
    • [/settings/external scripts/wrapped scripts]
      check_time=lotp_check_time.ps1 -refTimeServer $ARG1$ -maxWarn $ARG2$ -maxError $ARG3$

Configuration:

Par exemple, sur Centreon, en ajoutant la commande:

$USER1$/check_nrpe -H $HOSTADDRESS$ -n -c check_time -a "$ARG1$" $ARG2$ $ARG3$

Téléchargement

(enlever le .txt à la fin)

lotp_check_time.ps1

 

# ====================================================================
# Check time against DC or specified server through NRPE / w32tm
# Author: Mathieu Chateau - LOTP
# mail: mathieu.chateau@lotp.fr
# version 0.1
# ====================================================================

#
# Require Set-ExecutionPolicy RemoteSigned.. or sign this script with your PKI 
#

# ============================================================
#
#  Do not change anything behind that line!
#
param 
(
	[string]$refTimeServer,
	[int]$maxWarn = 1,
	[int]$maxError = 5
)

$output=""
$exitcode=2
$random=
if(($refTimeServer -eq $null) -or ($refTimeServer -eq "") -or ($refTimeServer -eq " "))
{
	$refTimeServer=$env:LOGONSERVER -replace ('\',"")
	if(($refTimeServer -match "^$|^ $") -or ($env:LOGONSERVER -match $refTimeServer))
	{
		if((gwmi win32_computersystem).partofdomain -eq $true)
		{
			#Must use select and not .Name directly. If some DC are down, command will be empty with .Name
			$fromAD=(([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() | % { $_.DomainControllers }))| select Name 
			foreach ($entry in $fromAD)
			{
				if(($env:COMPUTERNAME -match $entry) -or ($entry -match $env:COMPUTERNAME))
				{
					#this server is a DC, can't check time against itself
					$fromAD.Remove($entry)
				}
			}
			if($fromAD.Count -gt 1)
			{
				#get a random DC from AD, as no server provided and no logon server could be found
				$refTimeServer=(Get-Random -InputObject $fromAD).Name
			}
			else
			{
				#only one DC, defaulting to internet
				$refTimeServer="pool.ntp.org"
			}
		}
		else
		{
			#Workgroup but no server to check time against provided. Defaulting to internet to do something
			$refTimeServer="pool.ntp.org"
		}
	}
}

if(($refTimeServer -eq $null) -or ($refTimeServer -eq "") -or ($refTimeServer -eq " "))
{
	#Something bad happened. Should never happen
	Write-Host "CRITICAL: can't auto detect logon server to check against. Need to specify manually using refTimeServer argument"
	exit 2
}

$temp=w32tm /stripchart /computer:$refTimeServer /period:1 /dataonly /samples:1
$temp=($temp | select -Last 1) -replace (".*, ","")
$temp=$temp -replace ("s$","")

if ($temp -match "^(+|-)[0-9]+.[0-9]+$")
{
	$output=$temp+"s - checked against "+$refTimeServer
	if ([math]::abs($temp) -gt $maxError)
	{
		$state="CRITICAL"
		$exitcode=2
	}
	elseif ([math]::abs($temp) -gt $maxWarn)
	{
		$state="WARNING"
		$exitcode=1
	}
	else
	{
		$state="OK"
		$exitcode=0
	}
}
else
{
	$output="Error: - used $refTimeServer as time server - output:$temp"
	$exitcode=2
}

$output=$state+":"+$output+$random+'|'+"offset="+$temp+"s"+";"+$maxWarn+";"+$maxError+";"
Write-Host $output
exit $exitcode

Laisser un commentaire