NoSpamProxy mit Paessler PRTG überwachen

Inzwischen hat fast jedes Unternehmen ein Monitoring System im Einsatz. Die Standardthemen wie eingehender/ausgehender Datenverkehr, Status von Diensten, freier Arbeitsspeicher und Festplattenkapazität, Prozessorlast, etc…hat jeder auf dem Radar. Anders sieht es aus, wenn Fachanwendungen auf den jeweiligen Server betrieben werden. Hier taucht vor und nach der Implementierung immer die Frage auf: Habe ich alle relevanten Daten im Monitoring System erfasst? Oft merkt man erst bei einer Störung der Anwendung, dass man etwas vergessen. Dann nämlich, wenn das  Monitoring System keinen Alarm anzeigt. So auch in diesem Fall geschehen. 🙂

In dieser Umgebung kommt für die Abwehr von Malware/Spam das Produkt NoSpamProxy (NSP) von Net At Work zum Einsatz. Für die Überwachung der kompletten IT-Landschaft ist bereits PRTG aus dem Hause Paessler implementiert. Eines Tages schlugen über das Ticketsystem nach und nach  Nachfragen in der IT Abteilung auf. Verschickte E-Mails an externe Empfänger kommen dort nicht an. PRTG hat diesbezüglich keinen Alarm angezeigt: Exchange – online, NSP – online, Internetzugang – online, benutzerdefinierte SLA Probes – online. Es hat sich bei der genaueren Analyse herausgestellt, dass der Internet Service Provider Probleme mit dem Routing hatte. Was dazu geführt hatte, dass das NSP Gateway keine Verbindung zum gegenüberliegenden E-Mailserver aufbauen konnte. 🙁

Bei meinen Überlegungen und anschließender Suche im Internet bin ich auf das PowerShell Skript von Thomas Stensitzki gestoßen. Es ist bzw. war am Ende des Tages die einzig brauchbare Seite, welche mich meinem Ziel einen großen Schritt nähergebracht hat.  Das größte Manko an seinem PowerShell Skript ist meiner Meinung nach, dass er auf dem Server auf dem die NSP – Intranet Rolle läuft, auch eine PRTG Probe installiert hat. Der Sensor „Programm/Skript“ führt das hinterlegte Skript wird immer auf der PRTG Probe aus, dem das Gerät und somit auch Sensor zugeordnet ist.

Unsere Anforderungen hingegen waren wie folgt:

  • Auswertung der Nachrichtenverfolgung über alle NSP Gateways hinweg.
  • Auswertung der Nachrichtenverfolgung des angegebenen NSP Gateways.
  • Übergabe des Abfrageintervalls des PRTG Sensors an das Skript. Somit sind manuelle Anpassungen im PowerShell Skript nicht notwendig.

Entstanden ist folgendes PowerShell Skript bzw. PRTG Sensor:

<#
.SYNOPSIS
PRTG Sensor script to monitor a NoSpamProxy environment


THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER. 

.DESCRIPTION
This script returns Xml for a custom PRTG sensor providing the following channels

- In/Out Success             | Total of inbound/outbound successfully delivered messages over the last X minutes
- Inbound Success            | Number of inbound successfully delivered messages over the last X minutes
- Outbound Success           | Number of outbound successfully delivered messages over the last X minutes
- Inbound PermanentlyBlocked | Number of inbound blocked messages over the last X minutes
- Outbound DeliveryPending   | Number of outbound messages with pending delivery over the last X minutes

.PARAMETER PrtgDevice
Name des Servers, auf dem die NoSpamProxy Intranet Rolle installiert ist.

.PARAMETER intMinutes
Dieser Parameter muss indentisch sein, mit dem Abfrage Interverall des PRTG Sensors, welcher dieses Skript ausführt.Angabe in Minuten!

.PARAMETER NspGatewayRoleName
Mit diesem Parameter kann explizit der Name der NoSpamProxy Gateway Rolle angegeben werden, die ausgewertet werden soll

.INPUTS
None
 
.OUTPUTS
Output the values in xml format
 
.NOTES
File:           paessler-prtg_monitor-netatwork-nospamproxy.ps1
Version:        1.1
Author:         Thomas Stensitzki, Daniel Wydler
Creation Date:  02.07.2016, 00:00 Uhr
Purpose/Change:
 
Date                   Comment
-----------------------------------------------
02.07.2016, 00:00 Uhr  Initial community release
07.09.2019, 16:00 Uhr  Code base revised
08.09.2019, 16:31 Uhr  Query all Gateway Roles
17.09.2019, 17:01 Uhr  Rewrited codebase for query gateway role
21.09.2019, 21:20 Uhr  Changed output in Set-PrtgError
21.09.2019, 21:20 Uhr  Fixed variable name in Set-PrtgResult


The following parameters of the message tracking information are available
-Status: Success | DispatcherError | TemporarilyBlocked | PermanentlyBlocked | PartialSuccess | DeliveryPending | Suppressed | DuplicateDrop | All
-Directions: FromLocal | FromExternal | All

.COMPONENT
NoSpamProxy PowerShell Module

.LINK
http://www.granikos.eu/en/scripts
https://github.com/dwydler/Powershell-Skripte/tree/master/Paessler/PRTG

.EXAMPLE
.\paessler-prtg_monitor-netatwork-nospamproxy.ps1 "Computername" "Intervall des PRTG Sensors"
.\paessler-prtg_monitor-netatwork-nospamproxy.ps1 "Computername" "Intervall des PRTG Sensors" "Name der NSP Gateway Rolle"
#>

#---------------------------------------------------------[Initialisations]--------------------------------------------------------
 
Param (
   [Parameter(
        ValueFromPipelineByPropertyName,
        Position=0,
        Mandatory=$true
    )]
   [string] $PrtgDevice,

   [Parameter(
        ValueFromPipelineByPropertyName,
        Position=1,
        Mandatory=$true
    )]
   [int] $intMinutes,

   [Parameter(
        ValueFromPipelineByPropertyName,
        Position=2,
        Mandatory=$false
    )]
   [string] $NspGatewayRoleName
)

Clear-Host

#----------------------------------------------------------[Declarations]----------------------------------------------------------


[array] $aNspSecurityGroups = @("NoSpamProxy Configuration Administrators", "NoSpamProxy Monitoring Administrators")
#[array] $aNspSecurityGroups = @("Benutzer")

# Default warning level for delivery pending messages
[int] $intDeliveryPendingMaxWarn = 10

[string] $strXmlOutput = ""

#-----------------------------------------------------------[Functions]------------------------------------------------------------

function Set-PrtgError {
    Param (
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$PrtgErrorText
    )
    
    $strXmlOutput = "<prtg>`n"
    $strXmlOutput += "`t<error>1</error>`n"
    $strXmlOutput += "`t<text>$PrtgErrorText</text>`n"
    $strXmlOutput += "</prtg>"

    # Output Xml
    $strXmlOutput

    exit
}

function Set-PrtgResult {
    Param (
        [Parameter(mandatory=$True,Position=0)]
        [string]$Channel,
    
        [Parameter(mandatory=$True,Position=1)]
        [string]$Value,
    
        [Parameter(mandatory=$True,Position=2)]
        [string]$Unit,

        [Parameter(mandatory=$False)]
        [alias('mw')]
        [string]$MaxWarn,

        [Parameter(mandatory=$False)]
        [alias('minw')]
        [string]$MinWarn,
    
        [Parameter(mandatory=$False)]
        [alias('me')]
        [string]$MaxError,
    
        [Parameter(mandatory=$False)]
        [alias('wm')]
        [string]$WarnMsg,
    
        [Parameter(mandatory=$False)]
        [alias('em')]
        [string]$ErrorMsg,
    
        [Parameter(mandatory=$False)]
        [alias('mo')]
        [string]$Mode,
    
        [Parameter(mandatory=$False)]
        [alias('sc')]
        [switch]$ShowChart,
    
        [Parameter(mandatory=$False)]
        [alias('ss')]
        [ValidateSet('One','Kilo','Mega','Giga','Tera','Byte','KiloByte','MegaByte','GigaByte','TeraByte','Bit','KiloBit','MegaBit','GigaBit','TeraBit')]
        [string]$SpeedSize,

        [Parameter(mandatory=$False)]
        [ValidateSet('One','Kilo','Mega','Giga','Tera','Byte','KiloByte','MegaByte','GigaByte','TeraByte','Bit','KiloBit','MegaBit','GigaBit','TeraBit')]
        [string]$VolumeSize,
    
        [Parameter(mandatory=$False)]
        [alias('dm')]
        [ValidateSet('Auto','All')]
        [string]$DecimalMode,
    
        [Parameter(mandatory=$False)]
        [alias('w')]
        [switch]$Warning,
    
        [Parameter(mandatory=$False)]
        [string]$ValueLookup
    )
    
    $StandardUnits = @('BytesBandwidth','BytesMemory','BytesDisk','Temperature','Percent','TimeResponse','TimeSeconds','Custom','Count','CPU','BytesFile','SpeedDisk','SpeedNet','TimeHours')
    $LimitMode = $false
    
    $Result  = "`t<result>`n"
    $Result += "`t`t<channel>$Channel</channel>`n"
    $Result += "`t`t<value>$Value</value>`n"
    
    if ($StandardUnits -contains $Unit) {
        $Result += "`t`t<unit>$Unit</unit>`n"
    }
    elseif ($Unit) {
        $Result += "`t`t<unit>custom</unit>`n"
    $Result += "`t`t<customunit>$Unit</customunit>`n"
    }
    
    if (!($Value -is [int])) { $Result += "`t`t<float>1</float>`n" }
    if ($Mode)               { $Result += "`t`t<mode>$Mode</mode>`n" }
    if ($MaxWarn)            { $Result += "`t`t<limitmaxwarning>$MaxWarn</limitmaxwarning>`n"; $LimitMode = $true }
    if ($MinWarn)            { $Result += "`t`t<limitminwarning>$MinWarn</limitminwarning>`n"; $LimitMode = $true }
    if ($MaxError)           { $Result += "`t`t<limitmaxerror>$MaxError</limitmaxerror>`n"; $LimitMode = $true }
    if ($WarnMsg)            { $Result += "`t`t<limitwarningmsg>$WarnMsg</limitwarningmsg>`n"; $LimitMode = $true }
    if ($ErrorMsg)           { $Result += "`t`t<limiterrormsg>$ErrorMsg</limiterrormsg>`n"; $LimitMode = $true }
    if ($LimitMode)          { $Result += "`t`t<limitmode>1</limitmode>`n" }
    if ($SpeedSize)          { $Result += "`t`t<speedsize>$SpeedSize</speedsize>`n" }
    if ($VolumeSize)         { $Result += "`t`t<volumesize>$VolumeSize</volumesize>`n" }
    if ($DecimalMode)        { $Result += "`t`t<decimalmode>$DecimalMode</decimalmode>`n" }
    if ($Warning)            { $Result += "`t`t<warning>1</warning>`n" }
    if ($ValueLookup)        { $Result += "`t`t<ValueLookup>$ValueLookup</ValueLookup>`n" }
    if (!($ShowChart))       { $Result += "`t`t<showchart>0</showchart>`n" }
    
    $Result += "`t</result>`n"
    
    return $Result
}

#-------------------------------------------------------------[Modules]------------------------------------------------------------



#-----------------------------------------------------------[Execution]------------------------------------------------------------

# Überprüfe, ob der Intervall übergeben worden ist
if ($intMinutes -eq 0) {
    Set-PrtgError "Kein Abfrageintervall übergeben!"
}
else {
    [ValueType] $timespan = New-TimeSpan -Minutes $intMinutes
}

# Prüft, ob der ausführenden Benutzer Mitglied in den notwendigen Gruppen ist
$QueryResult = Invoke-Command -Computername $PrtgDevice -ArgumentList (,$aNspSecurityGroups) -ScriptBlock {
    
    param($aNspSecurityGroups)
    
    foreach ($strNspGroup in $aNspSecurityGroups) {
        if( (Get-LocalGroupMember $strNspGroup).Name -contains $([Security.Principal.WindowsIdentity]::GetCurrent().Name) -eq $false ) {
            return "Der Benutzer ist nicht Mitglied der lokalen Gruppe '$strNspGroup'!"
        }
    }
} 

if ($QueryResult -ne $null) {
    Set-PrtgError $QueryResult
}

###
### Abfrage eines bestimmten NoSpamProxy Gateways
###

if ($NspGatewayRoleName) {

    $QueryResult = Invoke-Command -Computername $PrtgDevice -ArgumentList $timespan,$NspGatewayRoleName -ScriptBlock {
    
        param($timespan,$strNspGatewayRoleName)

        if ( -not (Get-NspGatewayRole | Where-Object { $_.Name -eq $strNspGatewayRoleName }) ) {
            return "NspGatewayRoleNotExist"
        }
        
        $outItems = New-Object System.Collections.Generic.List[System.Object]

        $outItems.Add( (Get-NspMessageTrack -Status Success -Age $timespan -Directions FromExternal -GatewayRole $strNspGatewayRoleName).Count)
        $outItems.Add( (Get-NspMessageTrack -Status Success -Age $timespan -Directions FromLocal -GatewayRole $strNspGatewayRoleName).Count)
        $outItems.Add( (Get-NspMessageTrack -Status PermanentlyBlocked -Age $timespan -Directions FromExternal -GatewayRole $strNspGatewayRoleName).Count)
        $outItems.Add( (Get-NspMessageTrack -Status DeliveryPending -Age $timespan -Directions FromLocal -GatewayRole $strNspGatewayRoleName).Count)

        return $outItems
    }

    if ($QueryResult -eq "NspGatewayRoleNotExist") {
        Set-PrtgError "Eine Gatewayrolle mit dem Namen '$NspGatewayRole' existiert nicht!"
    }
}

###
### Abfrage  aller existiernenden NoSpamProxy Gateways
###

else {
    $QueryResult = Invoke-Command -Computername $PrtgDevice -ArgumentList $timespan -ScriptBlock {
    
        param($timespan)

        $outItems = New-Object System.Collections.Generic.List[System.Object]

        $outItems.Add( (Get-NspMessageTrack -Status Success -Age $timespan -Directions FromExternal).Count)
        $outItems.Add( (Get-NspMessageTrack -Status Success -Age $timespan -Directions FromLocal).Count)
        $outItems.Add( (Get-NspMessageTrack -Status PermanentlyBlocked -Age $timespan -Directions FromExternal).Count)
        $outItems.Add( (Get-NspMessageTrack -Status DeliveryPending -Age $timespan -Directions FromLocal).Count)

        return $outItems
    }
}

###
### Generate PRTG Output
###

$xmlOutput = "<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes""?>`n"
$xmlOutput += "<prtg>`n"

$xmlOutput += Set-PrtgResult -Channel "In/Out Success" -Value $($QueryResult[0] + $QueryResult[1]) -Unit Count -ShowChart
$xmlOutput += Set-PrtgResult -Channel "In Success" -Value $QueryResult[0] -Unit Count -ShowChart
$xmlOutput += Set-PrtgResult -Channel "Out Success" -Value $QueryResult[1] -Unit Count -ShowChart
$xmlOutput += Set-PrtgResult -Channel "In PermanentlyBlocked" -Value $QueryResult[2] -Unit Count -ShowChart

if($QueryResult[3] -ne 0) {
    $xmlOutput += Set-PrtgResult -Channel "Out DeliveryPending" -Value $QueryResult[3] -Unit Count -ShowChart -MaxWarn $intDeliveryPendingMaxWarn
}
else {
    $xmlOutput += Set-PrtgResult -Channel "Out DeliveryPending" -Value $QueryResult[3] -Unit Count -ShowChart 
}

$xmlOutput += '</prtg>'

# Return Xml
$xmlOutput

Quelle: Git Repository

Das Skript herunterladen und ggf. einen individuellen Dateinamen vergeben. Wichtig ist der Dateityp muss .ps1 sein. Die Datei auf der PRTG Probe in das Verzeichnis „.\Custom Sensors \EXEXML“ (z.B. C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML) ablegen/abspeichern.

Anschließend die Weboberfläche von PRTG in einem Browser anrufen und anmelden. Zuerst auf der Probe bzw. in der entsprechenden Hierarchie ggf. den Server auf dem die NSP Intranet Rolle installiert als Gerät anlegen. Danach einen neuen Sensor dem Gerät hinzufügen. Im Assistenten den Sensortyp „Programm/Skript (Erweitert)“ auswählen.

Nun erscheint die Maske für die Allgemeinen- und Sensoreinstellungen.

Parameter:

Als erster Parameter muss „%device“ eingegeben werden. PRTG speichert den Computernamen des übergeordneten Geräts in der Variablen %device. Grund dafür ist, dass ich den Computername im PowerShell Skript in eine Variable gepackt habe. Gerade wenn man unabhängige NSP Instanzen in seiner Landschaft hat, ist das PowerShell Skript flexibel und muss nicht unnötig oft dupliziert werden.

Als zweiter Parameter muss der Intervall in Minuten angegeben werden. Hintergrund ist, dass der Sensor natürlich nicht bei jeder Abfrage die gesamte Nachrichtenverfolgung des NSPs auswerten soll. Sondern nur Einträge, die seit der letzten Ausführung des Sensors erfasst worden sind. Wird der Abfrageintervall des Sensors nur alle 30 Minuten ausgeführt, so muss natürlich auch der dieser Parameter geändert werden. Wichtig ist, dass der Wert in Anführungszeichen steht! Bis dato gibt es in PRTG keine Variable für den Abfrageintervalls des Sensors.

Als dritter Parameter kann optional noch der Computername angegeben werden, auf dem die NSP Gateway Rolle läuft. Somit kann explizit für den angegeben Server die Statistik abgerufen und ausgewertet werden. Dies macht meiner Meinung nach Sinn, wenn man mehrere NSP Gateways im Einsatz hat und diese zudem über verschiedene Internetleitungen agieren.

%device "5"
%device "5" "nsp01"

Sicherheitskontext:

Nach einer PRTG Standardinstallation wird der dazugehörige Dienst „PRTG Probe Service“ unter dem Benutzer „Lokales System“ ausgeführt. Mit diesem Systembenutzer ist es nicht möglich, eine PowerShell Remoteverbindung auf einen entfernen Server aufzubauen. Daher muss die zweite Option ausgewählt werden. In 99% der Fälle ist bereits entsprechende Zugangsdaten im übergeordneten Gerät bzw. in der Hierarchie konfiguriert. Denn Sensoren für Windows-Systeme (z.B. WMI) greifen auf dieselben Zugangsdaten zurück.

Sind alle Einstellungen und ein schöner Name für den Sensor vergeben, kann der Sensor erstellt werden.

Nachstehend ein Screenshot des Sensors, wenn dieser eingebunden ist. In diesem Fall handelt es sich um meine Testumgebung, wo natürlich ohne Lizenzschlüssel für NSP und E-Mailserver auch nichts zu sehen ist. 😉

Der Code bzw. Sensor ist sozusagen noch BETA. Ich habe diesen in zwei verschiedenen Umgebungen bisher im Einsatz. Somit würde ich mich natürlich freuen, wenn sich weitere Tester finden lassen. Viel Spaß beim Ausprobieren. 🙂

4
Hinterlasse einen Kommentar

avatar
2 Kommentar Themen
2 Themen Antworten
0 Follower
 
Kommentar, auf das am meisten reagiert wurde
Beliebtestes Kommentar Thema
3 Kommentatoren
dwFrank CariusJan Jäschke Letzte Kommentartoren
  Abonnieren  
neueste älteste
Benachrichtige mich bei
Frank Carius
Gast
Frank Carius

Nett geschrieben und vor allem die Set-PrtgResult-Funktion hat es mir angetan :-). Du schreibst, dass man auf dem NSP dann eine PRTG Probe installieren müsste. Und du verwendest „Invoke-command“, wozu die Rollen aber auch erreichbar sein müssten. Es geht vielleicht eleganter (je nach Sichtweise) ich würde das Skript einfach per Windows Taskplaner alle x Monuten auf dem PC laufen lassen, auf dem die NSP Commandlets vorliegen und die Ergebnisse per HTTP-Push an PRTG posten. https://www.msxfaq.de/tools/prtg/prtghttppushsensoren.htm. Ich nehme ihr Posting mal zum Anlass mal zu schauen, was wir vielleicht ins Produkt einbauen können. NoSpamProxy hat aber schon heute Windows Performance Counter… Weiterlesen »

Jan Jäschke
Gast
Jan Jäschke

Hallo Herr Wydler,

es freut mich sehr zu sehen, dass Sie Ihre Arbeit und Ihr erarbeitet Wissen mit der Öffentlichkeit teilen.
Ich freue mich schon drauf Ihr Skript in meiner Testumgebung auszuprobieren 🙂

Außerdem habe ich mir die Freiheit genommen Ihren Beitrag in unserem Forum zu verlinken (https://forum.nospamproxy.com/showthread.php?tid=17). Es ist ein hervorragendes Beispiel was mit dem NSP unter der Haube alles möglich ist.

Ich freue mich schon auf weitere Beiträge von Ihnen. 🙂

Mit freundlichen Grüßen,
Jan Jäschke

Produktmanager der Net at Work GmbH

Back to top