pfSense – Scripte für Icinga2 Monitoring

Icinga2 Check -  Öffentliche WAN IP Adresse der pfSense gleich der im DNS vom DynDNS Anbieter

Wenn man an seinem eigenen DSL Anschluss mit Zwangstrennung einen Dienst betreibt, der vom Internet aus erreichbar sein soll, ist es hilfreich zu wissen, ob die beim DynDNS Anbieter hinterlegten IP Adressen mit der des WAN Interfaces vom Router übereinstimmen.

Voraussetzung für das Monitoring ist Icinga2 und eine pfSense mit aktivierten SNMP, oder besser wie in diesem Fall SNMPv3. In der pfSense kann man das Paket net-snmp für SNMPv3 nachinstallieren. Weitere Voraussetzung ist das Paket snmp auf dem Icinga2 Server, welches für den Befehl snmpwalk notwendig ist.

Die Scripte laufen auf einem Ubuntu Server. Bei einer anderen Linux Distribution sind eventuell weitere Anpassungen notwendig.

IPv4 Check

Für IPv4 ist die Überwachung noch recht einfach, da man die Adresse direkt per SNMP auslesen kann. Auf dem Icinga2 Server folgenden Script anlegen:

sudo vi /usr/lib/nagios/plugins/check_ip_dns

#!/bin/bash
# Icinga Plugin
# pfSense WAN IPv4 Adresse auslesen und mit DNS IPv4 Adresse vergleichen.

SNMPHost='IP SNMP Server' # SNMP Host Adresse
Username='User' # SNMPv3 User
Passwort='Geheim' # SNMPv3 Passwort
Encryption='Secret' # SNMPv3 Pre-Shared-Key
OID='iso.3.6.1.2.1.4.20.1.1' # SNMP IPv4 Object Identifer
Domain='example.com' # Domain für die IPv4 Abfrage
DNSHost='IP DNS Server' # DNS Server zur IPv4 Auflösung

# IPv4 Adresse DNS
DIG=$(/usr/lib/nagios/plugins/check_dig -H $DNSHost -T A -l $Domain | awk '{print $12}' | sed 's#).*##')

# SNMPv3 IPv4
IP=$(/usr/bin/snmpwalk $SNMPHost -v3 -l authPriv -u $Username -A $Passwort -a SHA -X $Encryption -x AES $OID | sed -n '1p' | awk '{print $4}')

# Überprüfen ob eine gültige öffentliche IPv4 Adresse am WAN Interface existiert
echo "$IP" | grep -q -E '^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|[0-9a-e:]{1,39})$'

if [ "$?" != "0" ]
then
echo CRITICAL - No Public IPv4 address on the WAN interface!
exit 2
else

# Vergleich ob die per SNMP ausgelesene Router IPv4 Adresse gleich der DNS IPv4 Adresse ist
if [ $IP == $DIG ]
then
echo "($IP) OK - Public IPv4 address is equal to DynDNS address ($DIG)"
exit 0
else
echo "($IP) CRITICAL - Public IPv4 address is not equal to DynDNS address! ($DIG)"
exit 2
fi
fi

Anschließend noch die korrekte Berechtigung setzen.

sudo chmod 755 /usr/lib/nagios/plugins/check_ip_dns

In der commands.conf auf dem Icinga2 Server folgenden Eintrag hinzufügen:

sudo vi /etc/icinga2/conf.d/commands.conf

object CheckCommand "check_ip_dns" {
import "plugin-check-command"
command = [PluginDir + "/check_ip_dns" ]
}

In dem jeweiligen Service Template muss noch folgendes Objekt hinzugefügt werden:

object Service "Router IPv4-Adresse = DynDNS IPv4-Adresse" {
import "generic-service"
host_name = "router"
check_command = "check_ip_dns"
vars.sla = "24x7"
}

Der host_name = "router" ist nur ein Beispiel und muss durch den Host ersetzt werden, für dem der Icinga2 Check angezeigt werden soll.

Icinga2 Service neu starten.

sudo systemctl restart icinga2.service

IPv6 Check

Der Script für IPv6 ist etwas aufwendiger. Die per SNMP aus dem pfSense Router ausgelesene Adresse liegt in Dezimalform vor und muss anschließend in Hexadezimal umgewandelt werden. Danach ist noch eine Anpassung des IPv6 Format an die verschiedenen Schreibweisen notwendig.

sudo vi /usr/lib/nagios/plugins/check_ipv6_dns

#!/bin/bash
# Icinga Plugin
# pfSense WAN IPv6 Adresse auslesen und mit DNS IPv6 Adresse vergleichen.

SNMPHost='IP SNMP Server' # SNMP Host Adresse
Username='User' # SNMPv3 User
Passwort='Geheim' # SNMPv3 Passwort
Encryption='Secret' # SNMPv3 Pre-Shared-Key
OID='iso.3.6.1.2.1.4.34.1.6.2.16.32' # SNMP IPv6 (dezimal) Object Identifer
Domain='example.com' # Domain für die IPv6 Abfrage
DNSHost='IP DNS Server' # DNS Server zur IPv6 Auflösung

# IPv6 Adresse DNS
DIG=$(/usr/lib/nagios/plugins/check_dig -H $DNSHost -T AAAA -l $Domain | awk '{print $12}' | sed 's#).*##')

# SNMPv3 IPv6 Dezimal
SNMPDez=$(/usr/bin/snmpwalk $SNMPHost -v3 -l authPriv -u $Username -A $Passwort -a SHA -X $Encryption -x AES $OID | tail -fn1 | awk '{ print $1 }' | cut -c29- | tr -s '.' ' ')

# Umwandlung der per SNMP ausgelesenen Router WAN IPv6 Adresse von Dezimal in Hexadezimal
# Dxx -> Dezimal
# Hxx -> Hexadezimal

# SNMP 1. Dezimalzahl -> Hex
D01=$(echo $SNMPDez | awk '{ print $1 }')
HX01=$(printf "%x\n" $D01)
if [ "$HX01" = 0 ]
then
echo führende Nullen werden weggelassen > /dev/null 2>&1
else
H01=$HX01
fi

# SNMP 2. Dezimalzahl -> Hex, zweistellig
D02=$(echo $SNMPDez | awk '{ print $2 }')
H02=$(printf "%02x\n" $D02)

# : #######################################################################

# SNMP 3. Dezimalzahl -> Hex
D03=$(echo $SNMPDez | awk '{ print $3 }')
HX03=$(printf "%x\n" $D03)
if [ "$HX03" = 0 ]
then
echo führende Nullen werden weggelassen > /dev/null 2>&1
else
H03=$HX03
fi

# SNMP 4. Dezimalzahl -> Hex, zweistellig
D04=$(echo $SNMPDez | awk '{ print $4 }')
H04=$(printf "%02x\n" $D04)

# : ######################################################################

# SNMP 5. Dezimalzahl -> Hex
D05=$(echo $SNMPDez | awk '{ print $5 }')
HX05=$(printf "%x\n" $D05)
if [ "$HX05" = 0 ]
then
echo führende Nullen werden weggelassen > /dev/null 2>&1
else
H05=$HX05
fi

# SNMP 6. Dezimalzahl -> Hex, zweistellig
D06=$(echo $SNMPDez | awk '{ print $6 }')
H06=$(printf "%02x\n" $D06)

# : ######################################################################

# SNMP 7. Dezimalzahl -> Hex
D07=$(echo $SNMPDez | awk '{ print $7 }')
HX07=$(printf "%x\n" $D07)
if [ "$HX07" = 0 ]
then
echo führende Nullen werden weggelassen > /dev/null 2>&1
else
H07=$HX07
fi

# SNMP 8. Dezimalzahl -> Hex, zweistellig
D08=$(echo $SNMPDez | awk '{ print $8 }')
H08=$(printf "%02x\n" $D08)

# : ######################################################################

# SNMP 9. Dezimalzahl -> Hex
D09=$(echo $SNMPDez | awk '{ print $9 }')
HX09=$(printf "%x\n" $D09)
if [ "$HX09" = 0 ]
then
echo führende Nullen werden weggelassen > /dev/null 2>&1
else
H09=$HX09
fi

# SNMP 10. Dezimalzahl -> Hex, zweistellig
D10=$(echo $SNMPDez | awk '{ print $10 }')
H10=$(printf "%02x\n" $D10)

# : ######################################################################

# SNMP 11. Dezimalzahl -> Hex
D11=$(echo $SNMPDez | awk '{ print $11 }')
HX11=$(printf "%x\n" $D11)
if [ "$HX11" = 0 ]
then
echo führende Nullen werden weggelassen > /dev/null 2>&1
else
H11=$HX11
fi

# SNMP 12. Dezimalzahl -> Hex, zweistellig
D12=$(echo $SNMPDez | awk '{ print $12 }')
H12=$(printf "%02x\n" $D12)

# : ######################################################################

# SNMP 13. Dezimalzahl -> Hex
D13=$(echo $SNMPDez | awk '{ print $13 }')
HX13=$(printf "%x\n" $D13)
if [ "$HX13" = 0 ]
then
echo führende Nullen werden weggelassen > /dev/null 2>&1
else
H13=$HX13
fi

# SNMP 14. Dezimalzahl -> Hex, zweistellig
D14=$(echo $SNMPDez | awk '{ print $14 }')
H14=$(printf "%02x\n" $D14)

# : ######################################################################

# SNMP 15. Dezimalzahl -> Hex
D15=$(echo $SNMPDez | awk '{ print $15 }')
HX15=$(printf "%x\n" $D15)
if [ "$HX15" = 0 ]
then
echo führende Nullen werden weggelassen > /dev/null 2>&1
else
H15=$HX15
fi

# SNMP 16. Dezimalzahl -> Hex, zweistellig
D16=$(echo $SNMPDez | awk '{ print $16 }')
H16=$(printf "%02x\n" $D16)

# IPv6 Adresse SNMP Router
IPv6=$(echo $H01$H02:$H03$H04:$H05$H06:$H07$H08:$H09$H10:$H11$H12:$H13$H14:$H15$H16)

# Überprüfen ob eine gültige öffentliche IPv6 Adresse am WAN Interface existiert
echo "$IPv6" | egrep '2001|2002|2003|240|260|261|262|280|2a0|2b0|2c0' > /dev/null 2>&1;

if [ "$?" != "0" ]
then
echo "CRITICAL - No public IPv6 address on the WAN interface!";
exit 2

else

# Vergleich ob die per SNMP ausgelesene Router IPv6 Adresse gleich der DNS IPv6 Adresse ist
if [ $IPv6 = $DIG ]
then
echo "($IPv6) OK - Public IPv6 address is equal to DynDNS address ($DIG)"
exit 0
else
echo "($IPv6) CRITICAL - Public IPv6 address is not equal to DynDNS address! ($DIG)"
exit 2
fi
fi

Anschließend noch die korrekte Berechtigung setzen.

sudo chmod 755 /usr/lib/nagios/plugins/check_ipv6_dns

In der commands.conf auf dem Icinga2 Server folgenden Eintrag hinzufügen:

sudo vi /etc/icinga2/conf.d/commands.conf

object CheckCommand "check_ipv6_dns" {
import "plugin-check-command"
command = [PluginDir + "/check_ipv6_dns" ]
}

In dem jeweiligen Service Template muss noch folgendes Objekt hinzugefügt werden:

object Service "Router IPv6-Adresse = DynDNS IPv6-Adresse" {
import "generic-service"
host_name = "router"
check_command = "check_ipv6_dns"
vars.sla = "24x7"
}

Der host_name = "router" ist nur ein Beispiel und muss durch den Host ersetzt werden, für dem der Icinga2 Check angezeigt werden soll.

Icinga2 Service neu starten.

sudo systemctl restart icinga2.service