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 Paketverwaltung von 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. Die markierten Stellen müssen an die eigenen Gegebenheiten angepasst werden. Auf dem Icinga2 Server folgenden Script anlegen:
sudo vi /usr/lib/nagios/plugins/check_ip_dns
#!/bin/bash # Version 1.2 # Icinga Plugin # WAN IPv4 Adresse der pfSense auslesen und mit der im DNS hinterlegten IPv4 Adresse vergleichen. SNMPHost='IP SNMP Server' # IP-Adresse der pfSense Username='user' # SNMPv3 User - pfSense SNMPv3 Konfiguration Passwort='geheim' # SNMPv3 Passwort - pfSense SNMPv3 Konfiguration Encryption='secret' # SNMPv3 Pre-Shared-Key (Passphrase) - pfSense SNMPv3 Konfiguration Domain='example.com' # eigene Domain die überwacht werden soll DNSHost='IP DNS Server' # DNS Server, z.B. IP-Adresse der pfSense oder Google DNS Server 8.8.8.8 OIDGateway='iso.3.6.1.2.1.4.21.1.7.0.0.0.0' # Object Identifer: Provider IPv4 Gateway Adresse OID='iso.3.6.1.2.1.4.21.1.7.' # Object Identifer: öffentliche IPv4 Adresse der pfSense # SNMPv3: öffentliche IPv4 Adresse der pfSense ermitteln # Provider IPv4 Gateway Adresse IPGateway=$(/usr/bin/snmpwalk $SNMPHost -v3 -l authPriv -u $Username -A $Passwort -a SHA -X $Encryption -x AES $OIDGateway | awk '{print $4}') # Öffentliche IPv4 Adresse der pfSense: Object Identifer + Provider IPv4 Gateway Adresse IP=$(/usr/bin/snmpwalk $SNMPHost -v3 -l authPriv -u $Username -A $Passwort -a SHA -X $Encryption -x AES $OID$IPGateway | awk '{print $4}') # IPv4 Adresse im öffentlichen DNS mit Icinga Plugin check_dig ermitteln DIG=$(/usr/lib/nagios/plugins/check_dig -H $DNSHost -T A -l $Domain | awk '{print $12}' | sed 's#).*##') # Überprüfen ob eine gültige IPv4 Adresse im öffentlichen DNS existiert echo "$DIG" | 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 "WARNING - No IPv4 DNS address for $Domain" exit 1 else # Ü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 # Überprüfen ob die per SNMP ausgelesene Router IPv4 Adresse gleich der im öffentlichen DNS 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 fi
Anschließend noch die korrekte Berechtigung setzen und den Script für einen Funktionstest auf der Konsole ausführen.
sudo chmod 755 /usr/lib/nagios/plugins/check_ip_dns
/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 Eintrag 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
Historie
- Version 1.2 - Ermittlung der öffentlichen IPv4-Adresse optimiert.
- Version 1.1 - Bug zur Ermittlung der öffentlichen IPv4-Adresse beseitigt.
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. Die markierten Stellen müssen an die eigenen Gegebenheiten angepasst werden.
sudo vi /usr/lib/nagios/plugins/check_ipv6_dns
#!/bin/bash # Version 1.1 # Icinga Plugin # pfSense WAN IPv6 Adresse auslesen und mit DNS IPv6 Adresse vergleichen. SNMPHost='IP SNMP Server' # IP-Adresse der pfSense Username='user' # SNMPv3 User - pfSense SNMPv3 Konfiguration Passwort='geheim' # SNMPv3 Passwort - pfSense SNMPv3 Konfiguration Encryption='secret' # SNMPv3 Pre-Shared-Key - pfSense SNMPv3 Konfiguration Domain='example.com' # eigene Domain die überwacht werden soll DNSHost='IP DNS Server' # DNS Server, z.B. Google DNS Server 8.8.8.8 oder pfSense IP-Adresse OID='iso.3.6.1.2.1.4.34.1.6.2.16.32' # Object Identifer, zum Auslesen der aktuellen öffentlichen IPv6 Adresse (dezimal) am WAN Interface # 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 im DNS existiert echo "$DIG" | egrep '(::[A-Fa-f0-9])|((:[A-Fa-f0-9]{1,4}){2,})' > /dev/null 2>&1; if [ "$?" != "0" ] then echo "WARNING - No IPv6 DNS address for $Domain" exit 1 else # Überprüfen ob eine gültige öffentliche IPv6 Adresse am WAN Interface existiert echo "$IPv6" | egrep '(::[A-Fa-f0-9])|((:[A-Fa-f0-9]{1,4}){2,})' > /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 fi
Anschließend noch die korrekte Berechtigung setzen und den Script für einen Funktionstest auf der Konsole ausführen.
sudo chmod 755 /usr/lib/nagios/plugins/check_ipv6_dns
/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 Eintrag 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
History
- Version 1.1 - Überprüfung der öffentlichen IPv6-Adresse (DNS/WAN) optimiert.