SNMP
Konzept
SNMP ist eigentlich zur Verwaltung ausgedehnter Netzwerke mit vielen Knoten gedacht. Über das SNMP-Protokoll kann man Daten über den Zustand eines Netzknotens abrufen, also beispielsweise über die Auslastung, den Datendurchsatz, etc. Mit einer geeigneten Software, beispielsweise HP OpenView, kann man sich ein ausgedehntes Netzwerk auch komplett visualisieren und dann gezielt auf einzelne Netzknoten “klicken”, um detaillierte Daten abzurufen. Aber auch im SOHO-Netzwerk kann man mit SNMP einige nützliche Dinge anstellen. Außerdem wird SNMP auch für mrtg benötigt.
Manche SNMP-fähigen Geräte können auch noch beim Auftreten bestimmter Bedingungen eine Nachricht an eine zentrale Station schicken. Man nennt dies einen Trap. Beispielsweise können Router eine Nachricht schicken, wenn eine Verbindung ausfällt.
Auf meinen Maschinen ist SNMP daher natürlich auch eingerichtet. Dabei werden Dienste auf Funktionsfähigkeit geprüft, Log-Dateien und die Maschinenauslastung überwacht, Verkehrsdaten erfasst und auch noch der angeschlossene WLAN-Router überwacht, der ebenfalls SNMP-fähig ist.
Weiterführende Informationen zum Thema SNMP gibt es bei Net-SNMP [1], bei Cisco [2] und natürlich bei Wikipedia [3]. Eine Übersicht von Standard-MIBs und OIDs findet sich bei ByteSphere [4] sowie auf [5] und [6].
Einrichtung des SNMP-Dienstes
Um SNMP einzurichten, muss das Paket net-snmp installiert werden. Dann führt man entweder das interaktive Skript snmpconf -g basic_setup
aus, um eine erste Version der SNMP-Konfiguration zu erstellen oder man passt gleich die Datei /etc/snmp/snmpd.conf an, so wie sie hier abgedruckt ist. Eine Beispielkonfiguration mit verschiedenen Einstellungen findet sich auf [7].
########################################################################### # SNMP-Konfiguration # # 05-Dec-2012 Gabriel Rüeck # rouser public rocommunity public localhost rocommunity public 192.168.2.0/24 rocommunity public 192.168.3.0/24 rocommunity public 192.168.4.0/24 ########################################################################### # SECTION: System Information Setup # syslocation "中国110016 沈阳市和平区文体路" syscontact "Gabriel Rüeck <gabriel@caipirinha.homelinux.org>" sysservices 78 ########################################################################### # SECTION: Monitor Various Aspects of the Running Host # # The results are reported in the dskTable section. disk / 30% disk /home 10% disk /home/public/Video 5% disk /var 20% disk /backup 10% # The results are reported in the fileTable section file /var/log/messages 100000 file /var/log/warn 100000 # The results are reported in the laTable section. load 15 10 10 # The results are reported in the prTable section. proc amavisd 3 1 proc apcupsd 1 1 proc atd 1 1 proc authdaemond 10 1 proc clamd 1 1 proc couriertcpd 2 2 proc cron 4 1 proc cupsd 1 1 proc dhcpd 1 1 proc fail2ban-server 1 1 proc famd 1 1 proc freshclam 1 1 proc httpd2-prefork 50 1 proc icecast 10 1 proc master 1 1 proc mdadm 1 1 proc minidlna 5 1 proc mrtg 1 1 proc mysqld 2 1 proc named 1 1 proc nmbd 1 1 proc ntpd 1 1 proc openvpn 6 5 proc pure-ftpd 1 1 proc rsyncd 5 1 proc rsyslogd 1 1 proc saslauthd 1 1 proc sensord 1 1 proc smartd 1 1 proc smbd 20 1 proc sshd 20 1 proc tlsmgr 1 1 ########################################################################### # SECTION: Custom Programs # exec mbox_gabriel /root/bin/mailsize.sh gabriel exec mbox_joselia /root/bin/mailsize.sh joselia exec bw_rueeck /root/bin/bandwidth.sh rueeck.name exec bw_caipiroska /root/bin/bandwidth.sh caipiroska.homelinux.org exec ping_gw0 /root/bin/pingtimes.sh gw0 exec ping_tun0 /root/bin/pingtimes.sh tun0 exec ping_gw1 /root/bin/pingtimes.sh gw1 exec ping_tun1 /root/bin/pingtimes.sh tun1 exec ping_gw2 /root/bin/pingtimes.sh gw2 exec ping_tun2 /root/bin/pingtimes.sh tun2 exec vpn_tun0_r /root/bin/vpn_traffic.sh tun0 read exec vpn_tun0_w /root/bin/vpn_traffic.sh tun0 write exec vpn_tun1_r /root/bin/vpn_traffic.sh tun1 read exec vpn_tun1_w /root/bin/vpn_traffic.sh tun1 write exec vpn_tun2_r /root/bin/vpn_traffic.sh tun2 read exec vpn_tun2_w /root/bin/vpn_traffic.sh tun2 write ########################################################################### # SECTION: Trap Destinations # authtrapenable 2 iquerySecName public createUser public MD5 auth_pwd_local DES crypto_pwd_local #trap2sink localhost public informsink localhost public #trapsess -Ci -v3 -u public -a MD5 -A auth_pwd_trap -x DES -X crypto_pwd_trap -l authPriv localhost monitor -o prNames -o prErrMessage "process table" prErrorFlag != 0 monitor -o dskPath -o dskErrorMsg "dskTable" dskErrorFlag != 0 monitor -o laNames -o laErrMessage "laTable" laErrorFlag != 0 monitor -o fileName -o fileErrorMsg "fileTable" fileErrorFlag != 0
Den Community-Namen public sollte man aus Sicherheitsgründen durch einen selbst gewählten Namen ersetzen. Dieser muss dann aber bei allen SNMP-Knoten im Netzwerk gleich gewählt werden. Gleichermaßen müssen auth_pwd_local und crypto_pwd_local durch möglichst komplexe Passworte ersetzt werden. Diese Passworte dienen zur Authentifizierung (auth_pwd_local) und zur Verschlüsselung (crypto_pwd_local) beim Zugriff auf SNMP-Daten, wenn SNMP in der Version 3 (SNMPv3) zum Einsatz kommt.
Die hier gezeigte Konfigurationsdatei /etc/snmp/snmpd.conf
gliedert sich in fünf Teile und beinhaltet Konfigurationsanweisungen
sowohl für SNMPv2 als auch für SNMPv3. Im ersten Teil werden die
Zugriffsberechtigungen festgelegt; aus Sicherheitsgründen sind diese auf
reine Lesezugriffe vom Server selbst und aus dem SOHO-Netzwerk
beschränkt. Dort sind 3 Netzwerke angegeben, weil der Caipirinha-Server
über mehrere VPNs mit verschiedenen Netzwerken verbunden ist oder selbst
über VPN-Dienste anbietet. Weiterhin wird für SNMPv3 ein Benutzername
(hier: public) angelegt. SNMPv3 kennt verschiedene Sicherheitsmechanismen, welche man sich mit man 5 snmpd.conf
vergegenwärtigen kann. Als Standard wird beim Zugriff auf SNMP-Daten
über SNMPv3 zumindest Authentifizierung verlangt. Verschlüsselung ist
optional.
Im zweiten Abschnitt sind die Kontaktdaten für den Administrator des Caipirinha-Servers und der Maschinenstandort angegeben. Diese Daten erleichtern bei einem umfangreichen Netzwerk die Lokalisierung von Ansprechpartnern, wenn Probleme auf der Maschine auftreten. Der Wert bei sysservices spiegelt die Fähigkeiten des Netzknotens wieder. Details zur Berechnung dieses Wertes finden sich auf [8].
Der dritten Abschnitt selbst gliedert sich in drei Unterabschnitte, in denen verschiedene Kenngrößen überwacht werden. Sobald eine Kenngröße in eine kritische Richtung durchschritten wird, wird eine Mitteilung an den snmptrapd geschickt.
- Bei den angegebenen Partitionen ist der kritische Augenblick das Unterschreiten des angegeben Mindest-Prozentsatzes an freiem Speicher.
- Bei den angegebenen Log-Dateien ist der kritische Augenblick das Überschreiten der Größe. Der angegebene Zahlenwert bezieht sich auf kB als Einheit.
- Bei der Maschinenlast ist der kritische Augenblick das Überschreiten der angegebenen Grenzen. Die drei Werte entsprechen den Zeitintervallen der letzten Minute, der letzten 5 Minuten und der letzten 15 Minuten.
- Bei den Prozessen ist die erste angegebene Zahl der zulässige Maximalwert und die zweite angegebene Zahl der zulässige Minimalwert. Ein Überschreiten des Maximalwertes oder ein Unterschreiten des Minimalwertes setzt ein Fehler-Flag und in der abgedruckten Konfiguration auch dazu, dass ein Trap geschickt wird. Der snmptrap-Dienst wird daraus eine E-Mail erzeugen und an den Systemadministrator schicken. Es macht natürlich nur Sinn, hier solche Prozesse beobachten zu lassen, die eigentlich ununterbrochen laufen sollen.
Im vierten Abschnitt sind Skripte angegeben, die aus dem SNMP-Dienst heraus mit festzulegenden Argumenten aufgerufen werden können. Jeder Aufruf selbst bekommt auch noch einen Namen (beispielsweise mbox_gabriel oder mbox_joselia). Die hier erwähnten Shell-Skripte mailsize.sh, bandwidth.sh, pingtimes.sh und vpn_traffic.sh sind in Admin-Skripte dokumentiert.
Im fünften Abschnitt sind schließlich die Daten für den snmptrapd angegeben. Man erkennt mehrere Schlüsselworte. Mit authtrapenable werden versuchte SNMP-Abfragen mit einem fehlerhaften Login entweder an den snmptrapd geschickt (authtrapenable 1) oder eben nicht (authtrapenable 2). Mit iquerySecName wird der SNMPv3-Benutzername festgelegt, unter dem die Abfragen beim snmpd durchgeführt werden. Dieser Name muss gleich dem unter dem Schlüsselwort rouser angegebenen Benutzernamen sein. Mit createUser werden die Algorithmen und die Passworte zur Authentifizierung (auth_pwd_local) und zur Verschlüsselung (crypto_pwd_local) beim Zugriff mit dem entsprechenden SNMPv3-Benutzernamen auf lokale SNMP-Daten festgelegt. Man kann das Verschlüsselungspasswort (crypto_pwd_local) auch weglassen und die Authentifizierung und Verschlüsselung mit dem gleichen Passwort (in diesem Fall dann auth_pwd_local) durchführen. In diesem Fall muss die createUser-Anweisung so lauten:
createUser public MD5 auth_pwd_local DES crypto_pwd_local
Das Schlüsselwort trap2sink gibt das Ziel und den SNMPv2-Community-Namen an, an den die Traps geschickt werden. Achtung, hier wird SNMPv2 benutzt, während die Abfrage der SNMP-Werte beim snmpd mit SNMPv3 läuft! trap2sink ist hier allerdings auskommentiert, zu Gunsten von informsink. Durch informsink wird kein Trap, sondern eine Inform-Mitteilung an den snmptrapd geschickt. Das hat den Vorteil, dass der snmptrapd den Erhalt der Mitteilung bestätigt. Laufen sowohl snmpd als auch snmptrapd auf der gleichen Maschine, ist das unwichtig. Ist aber der snmptrapd auf einer entfernten Maschine, ist informsink eindeutig die bessere Wahl, denn so vermeidet man, dass die UDP-Pakete eines Trap verloren gehen können. Man kann bei beiden Schlüsselworten sowohl eine lokale als auch eine entfernte Maschine angeben. Beim Caipirinha-Server und Caipiroska-Server laufen die snmptrapd auf den gleichen Maschinen. Damit kann auch ein Trap gesendet werden, wenn die Netzwerkverbindung gerade down ist. In einem lokalen Netz, bei dem man sich sicher ist, dass die Verbindungen immer up sind, kann man den snmptrapd auch auf einer Maschine zentralisieren und von dort aus das gesamte Netzwerk überwachen.
Die vier monitor-Anweisungen legen fest, dass beim
Auftreten einer Fehlerbedingung ein Trap zu schicken ist. Die
entsprechende Syntax habe ich direkt aus man 5 snmpd.conf
heraus kopiert. Man hätte auch die Anweisung defaultMonitors yes benutzen können, aber diese beinhaltet noch weitere Prüfungen, die ich hier nicht haben wollte.
Mit dem Schlüsselwort trapsess kann man Traps und Informs auch über SNMPv3 zu einem snmptrapd auf einer lokalen oder entfernten Maschine schicken. Im falle einer entfernten Maschine muss man localhost durch den Maschinennamen oder die IP-Adresse ersetzen. Die Parameter public, auth_pwd_trap und crypto_pwd_trap müssen denen des snmptrapd entsprechen. Mit dieser Konfiguration wird die Nachricht vom snmpd zum snmptrapd dann sowohl an einen gültigen Login gebunden als auch verschlüsselt. Die Option -Ci legt fest, dass eine Inform-Mitteilung geschickt wird. Fehlt diese Option, wird lediglich eine (unbestätigte) Trap-Mitteilung geschickt.
Zum Vergleich ist hier eine Konfigurationsdatei angegeben, bei der Inform-Mittelungen an eine entfernte Maschine geschickt werden:
########################################################################### # SNMP-Konfiguration # # 05-Dec-2012 Gabriel Rüeck # rouser public rocommunity public localhost rocommunity public 124.95.128.109/32 ########################################################################### # SECTION: System Information Setup # syslocation "辽宁省沈阳市" syscontact "Gabriel Rüeck <gabriel@rueeck.de>" sysservices 78 ########################################################################### # SECTION: Monitor Various Aspects of the Running Host # # The results are reported in the dskTable section. disk / 50% disk /home 10% disk /tmp 20% disk /var 20% # The results are reported in the fileTable section file /var/log/messages 50000 file /var/log/warn 50000 # The results are reported in the laTable section. load 5 3 1 # The results are reported in the prTable section. proc atd 1 1 proc clamd 1 1 proc cron 4 1 proc fail2ban-server 1 1 proc famd 1 1 proc freshclam 1 1 proc httpd2-prefork 600 1 proc master 1 1 proc mdadm 1 1 proc mrtg 1 1 proc mysqld 2 1 proc named 1 1 proc ntpd 1 1 proc openvpn 2 1 proc rsyncd 5 1 proc rsyslogd 1 1 proc sensord 1 1 proc smartd 1 1 proc sshd 20 1 ########################################################################### # SECTION: Custom Programs # exec bw_rueeck /root/bin/bandwidth.sh rueeck.name exec bw_caipiroska /root/bin/bandwidth.sh caipiroska.homelinux.org ########################################################################### # SECTION: Trap Destinations # authtrapenable 1 iquerySecName public createUser public MD5 auth_pwd_local DES crypto_pwd_local #informsink caipirinha.homelinux.org public trapsess -Ci -v3 -u public -a MD5 -A auth_pwd_trap -x DES -X crypto_pwd_trap -l authPriv caipirinha.homelinux.org monitor -o prNames -o prErrMessage "process table" prErrorFlag != 0 monitor -o dskPath -o dskErrorMsg "dskTable" dskErrorFlag != 0 monitor -o laNames -o laErrMessage "laTable" laErrorFlag != 0 monitor -o fileName -o fileErrorMsg "fileTable" fileErrorFlag != 0
Nach der Anpassung der Konfigurationsdatei /etc/snmp/snmpd.conf muss man noch den snmpd noch starten. Eigentlich geschieht dies ja mit /etc/init.d/snmpd start
. Allerdings liest der snmpd beim Start gleich alle möglichen Konfigurationsdateien aus unterschiedlichen Verzeichnissen ein (siehe man 5 snmp_config
). Das ist eine böse Falle, die mich viel Zeit gekostet hat. So werden unter anderem existierende SNMPv3-Benutzerdaten aus /var/lib/net-snmp/snmpd.conf
eingelesen, die dann die Einstellungen aus der aktuellen
Konfigurationsdatei zunichte machen. Deshalb sollte man nach dem
Anpassen der Konfigurationsdatei den snmpd mit snmpd -C -c /etc/snmp/snmpd.conf
unter alleiniger Berücksichtigung dieser Konfigurationsdatei neu starten. In diesem Fall werden dann die SNMPv3-Benutzer in /var/lib/net-snmp/snmpd.conf von der Konfigurationsdatei /etc/snmp/snmpd.conf übernommen.
Einrichtung des SNMPTRAP-Dienstes
Wie bereits erwähnt, läuft auf meinen Maschinen nicht nur der snmpd, sondern auch noch der snmptrapd. Der Caipirinha-Server [9] ist damit zugleich Quelle von SNMP-Mitteilungen, die den Server selbst betreffen als auch zentrale Station zur Aufnahme aller Meldungen von Geräten aus dem entsprechenden lokalen Netz. Es handelt sich also bei snmptrapd um einen eigenständigen Dienst, der auf Port 162/udp auf eingehende Mitteilungen von SNMP-Agenten wartet.
Auch für den snmptrapd gibt es eine Konfigurationsdatei, nämlich /etc/snmp/snmptrapd.conf. Diese ist hier abgedruckt:
########################################################################### # SNMPTRAP-Konfiguration # # 30-Nov-2012 Gabriel Rüeck # # donotfork: Do not fork from the shell # arguments: (1|yes|true|0|no|false) doNotFork no # pidfile: Store Process ID in file # arguments: PID file pidFile /var/run/snmptrapd.pid # ignoreauthfailure: Ignore authentication failure traps # arguments: (1|yes|true|0|no|false) ignoreAuthFailure yes authCommunity log,execute public authUser log,execute public authUser log,execute public_2 createUser public MD5 auth_pwd_trap DES crypto_pwd_trap createUser public_2 MD5 auth_pwd_trap_2 DES crypto_pwd_trap_2 traphandle default /usr/bin/traptoemail -f "System Administrator <root@caipirinha.homelinux.org>" root@caipirinha.homelinux.org format1 %04.4y-%02.2m-%02.2l %02.2h:%02.2j From %B: %W \n format2 %04.4y-%02.2m-%02.2l %02.2h:%02.2j From %B: %W \n
Auch hier muss der Community-Name public durch den im gesamten Netzwerk einheitlich benutzten Community-Namen ersetzt werden. Mit authUser und createUser wird ein SNMPv3-Benutzer angelegt. auth_pwd_trap ist das Passwort zur Authentifizierung beim snmptrapd, und crypto_pwd_trap ist das Passwort zum Verschlüsseln der Daten. MD5 ist der bei der Authentifizierung zum Einsatz kommende Algorithmus, und DES kommt bei der Verschlüsselung zum Einsatz. auth_pwd_trap und crypto_pwd_trap müssen gleich sein wie bei der Konfiguration des snmpd auf einer Maschine, die diesem snmptrapd einen Trap oder eine Inform-Mitteilung schicken will. Auch hier kann man das Verschlüsselungspasswort (crypto_pwd_trap) weglassen und die Authentifizierung und Verschlüsselung mit dem gleichen Passwort (in diesem Fall dann auth_pwd_trap) durchführen. In diesem Fall muss die createUser-Anweisung so lauten:
createUser public MD5 auth_pwd_trap DES
Es ist auch möglich, mehrere SNMPv3-Benutzer anzulegen. Im Beispiel hier wurde mit public_2, auth_pwd_trap_2 und crypto_pwd_trap_2 ein zweiter SNMPv3-Benutzer angelegt, der diesem snmptrapd Mitteilungen schicken kann. Dies macht dann Sinn, wenn der snmptrapd Traps von unterschiedlichen Maschinen in Empfang nehmen soll, bei denen aber die jeweiligen Administratoren nichts von den Logins der anderen Maschinen wissen sollen. Man könnte natürlich auch generell für den snmptrapd einen ganz anderen SNMPv3-Benutzer nehmen, der nichts mit irgendeinem SNMPv3-Benutzer auf einer der Maschinen zu tun hat. Dies wäre ohne Zweifel die sicherste Lösung.
Die Anweisung traphandle legt fest, was beim Auftreten eines Traps zu tun ist. In diesem Fall wird eine E-Mail an root geschickt. format1 und format2 legen das Format für SNMPv1-Traps und SNMPv2/SNMPv3-Traps fest. Ich habe hier noch ein Format für SNMPv1 festgelegt, obwohl SNMPv1 nun inzwischen wirklich aus der Mode kommt, weil einige einfachen Router tatsächlich auch heute nur SNMPv1 beherrschen.
Es gibt für die Konfigurationsdatei auch eine Anweisung logOption,
mit dem man in der Konfigurationsdatei einstellen können sollte, wohin
die Meldungen geloggt werden sollen. Allerdings funktioniert diese bei
OpenSuSE 11.4 nicht, und wenn man snmptrapd -H
aufruft,
kommt ja auch eine entsprechende Meldung, die besagt, lass kein
Log-Handling aktiv ist. Alle Mitteilungen werden daher leider nach /var/log/messages geschrieben, ob man das will oder nicht. Beim Caipiroska-Server [10] sieht das dann beispielsweise so aus:
Nov 26 07:40:49 caipiroska snmptrapd[18445]: localhost [UDP: [127.0.0.1]:56402->[127.0.0.1]:162]: Trap , DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (22) 0:00:00.22, SNMPv2-MIB::snmpTrapOID.0 = OID: DISMAN-EVENT-MIB::mteTriggerFired, DISMAN-EVENT-MIB::mteHotTrigger.0 = STRING: process table, DISMAN-EVENT-MIB::mteHotTargetName.0 = STRING: , DISMAN-EVENT-MIB::mteHotContextName.0 = STRING: , DISMAN-EVENT-MIB::mteHotOID.0 = OID: UCD-SNMP-MIB::prErrorFlag.24, DISMAN-EVENT-MIB::mteHotValue.0 = INTEGER: 1, UCD-SNMP-MIB::prNames.24 = STRING: smbd, UCD-SNMP-MIB::prErrMessage.24 = STRING: No smbd process running Nov 26 07:40:49 caipiroska snmptrapd[18445]: localhost [UDP: [127.0.0.1]:56402->[127.0.0.1]:162]: Trap , DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (23) 0:00:00.23, SNMPv2-MIB::snmpTrapOID.0 = OID: DISMAN-EVENT-MIB::mteTriggerFired, DISMAN-EVENT-MIB::mteHotTrigger.0 = STRING: dskTable, DISMAN-EVENT-MIB::mteHotTargetName.0 = STRING: , DISMAN-EVENT-MIB::mteHotContextName.0 = STRING: , DISMAN-EVENT-MIB::mteHotOID.0 = OID: UCD-SNMP-MIB::dskErrorFlag.3, DISMAN-EVENT-MIB::mteHotValue.0 = INTEGER: 1, UCD-SNMP-MIB::dskPath.3 = STRING: /home/public/Video, UCD-SNMP-MIB::dskErrorMsg.3 = STRING: /home/public/Video: less than 5% free (= 100%)
Die erste Meldung sagt aus, dass kein smbd-Prozess läuft. Die zweite Meldung sagt aus, dass auf der Partition /home/public/Video weniger als 5% freier Festplattenspeicher ist. Der snmptrapd schickt auch entsprechende E-Mails, und die zu den zwei Meldungen gehörenden E-Mails haben genau den gleichen Inhalt, wie man hier erkennen kann:
Host: localhost (UDP: [127.0.0.1]:56402->[127.0.0.1]:162) DISMAN-EVENT-MIB::sysUpTimeInstance 0:0:00:00.22 SNMPv2-MIB::snmpTrapOID.0 DISMAN-EVENT-MIB::mteTriggerFired DISMAN-EVENT-MIB::mteHotTrigger.0 process table DISMAN-EVENT-MIB::mteHotTargetName.0 DISMAN-EVENT-MIB::mteHotContextName.0 DISMAN-EVENT-MIB::mteHotOID.0 UCD-SNMP-MIB::prErrorFlag.24 DISMAN-EVENT-MIB::mteHotValue.0 1 UCD-SNMP-MIB::prNames.24 smbd UCD-SNMP-MIB::prErrMessage.24 No smbd process running
Host: localhost (UDP: [127.0.0.1]:56402->[127.0.0.1]:162) DISMAN-EVENT-MIB::sysUpTimeInstance 0:0:00:00.23 SNMPv2-MIB::snmpTrapOID.0 DISMAN-EVENT-MIB::mteTriggerFired DISMAN-EVENT-MIB::mteHotTrigger.0 dskTable DISMAN-EVENT-MIB::mteHotTargetName.0 DISMAN-EVENT-MIB::mteHotContextName.0 DISMAN-EVENT-MIB::mteHotOID.0 UCD-SNMP-MIB::dskErrorFlag.3 DISMAN-EVENT-MIB::mteHotValue.0 1 UCD-SNMP-MIB::dskPath.3 /home/public/Video UCD-SNMP-MIB::dskErrorMsg.3 /home/public/Video: less than 5% free (= 100%)
Durch den E-Mail-Mechanismus kann man sich als Systemadministrator daher direkt informieren lassen, wenn auf einem der Server etwas aus dem Ruder läuft. Das ist eine sehr praktische Sache, insbesondere, wenn man eine solche E-Mail gleich noch auf dem Smartphone empfangen kann.
Der snmptrapd muss über das Kommando snmptrapd
gestartet werden. Es ist leider nicht möglich, einen automatischen Start über den Runlevel-Editor
einzustellen. Dies wird auf dem Caipirinha-Server im Rahmen eines
Skripts durchgeführt, welches der Systemadministrator nach dem Start des
Systems ausführen muss. Wie beim spnmd sollte man den snmptrapd nach
dem Ändern der Konfigurationsdatei mit snmptrapd -C -c /etc/snmp/snmptrapd.conf
starten, weil auch der snmptrapd beim Start mehrere Konfigurationsdateien aus unterschiedlichen Verzeichnissen einliest (siehe man 5 snmp_config
), unter anderem aus /var/lib/net-snmp/snmptrapd.conf.
Konfiguration von SNMP bei DSL-Routern
Oft ist es möglich, selbst bei SOHO-Routern SNMP zu konfigurieren; das nebenstehende Bild zeigt, wie man dies bei der “EasyBox 602” von Vodafone macht. Trägt man dort die IP-Adresse des Caipiroska-Servers im Heimnetzwerk ein und konfiguriert den Community-Namen korrekt, so kann der DSL-Router Traps an den Caipiroska-Server schicken, beispielsweise, wenn die DSL-Verbindung wegen des in Deutschland einmal am Tag stattfindenden IP-Adresswechsels kurzzeitig zusammenbricht. Dann bekommt man mindestens einen Trap mit der “Line down”-Information und einen mit der “Line up”-Information, üblicherweise kurze Zeit danach. Man erkennt hier auch, dass es Sinn macht, einen snmptrapd im Heimnetz laufen zu lassen und nicht auf eine entfernte Maschine zu verweisen, die ja dann nicht verfügbar ist, wenn die DSL-Verbindung gerade zusammengebrochen ist. Bei der von snmptrapd erzeugten E-Mail wird dagegen vom smtpd über einen längeren Zeitraum hinweg mehrmals eine Zustellung versucht.
Beispiele für SNMP-Abfragen
Einen ersten Überblick über die SNMP-Variablen einer Maschine verschafft man sich mit snmpwalk -v2c -cpublic localhost
oder, wenn SNMPv3 zum Einsatz kommen soll, mit snmpwalk -v3 -u public -l authNoPriv -a MD5 -A auth_pwd_local localhost
. Die Option authNoPriv
besagt, dass hier zwar eine Authentifizierung durchgeführt wird, aber
keine Verschlüsselung der Daten, die übertragen werden. Leider habe ich
mit der Option authPriv und der Angabe des crypto_pwd_local nur eine Fehlermeldung bekommen.
Die Ausgabe dieser Abfrage kann jedenfalls zu einer recht langen Liste führen.
System-Statistiken kann man sich mit snmpwalk -v2c -cpublic localhost .1.3.6.1.4.1.2021.11
bzw. snmpwalk -v3 -u public -l authNoPriv -a MD5 -A auth_pwd_local localhost .1.3.6.1.4.1.2021.11
anzeigen lassen [11], [12]. Dies liefert beispielsweise:
UCD-SNMP-MIB::ssIndex.0 = INTEGER: 1 UCD-SNMP-MIB::ssErrorName.0 = STRING: systemStats UCD-SNMP-MIB::ssSwapIn.0 = INTEGER: 0 kB UCD-SNMP-MIB::ssSwapOut.0 = INTEGER: 0 kB UCD-SNMP-MIB::ssIOSent.0 = INTEGER: 353 blocks/s UCD-SNMP-MIB::ssIOReceive.0 = INTEGER: 0 blocks/s UCD-SNMP-MIB::ssSysInterrupts.0 = INTEGER: 537 interrupts/s UCD-SNMP-MIB::ssSysContext.0 = INTEGER: 796 switches/s UCD-SNMP-MIB::ssCpuUser.0 = INTEGER: 0 UCD-SNMP-MIB::ssCpuSystem.0 = INTEGER: 1 UCD-SNMP-MIB::ssCpuIdle.0 = INTEGER: 95 UCD-SNMP-MIB::ssCpuRawUser.0 = Counter32: 7043838 UCD-SNMP-MIB::ssCpuRawNice.0 = Counter32: 1157149 UCD-SNMP-MIB::ssCpuRawSystem.0 = Counter32: 5023506 UCD-SNMP-MIB::ssCpuRawIdle.0 = Counter32: 147653397 UCD-SNMP-MIB::ssCpuRawWait.0 = Counter32: 9671287 UCD-SNMP-MIB::ssCpuRawKernel.0 = Counter32: 0 UCD-SNMP-MIB::ssCpuRawInterrupt.0 = Counter32: 352 UCD-SNMP-MIB::ssIORawSent.0 = Counter32: 1866410120 UCD-SNMP-MIB::ssIORawReceived.0 = Counter32: 2797478450 UCD-SNMP-MIB::ssRawInterrupts.0 = Counter32: 597294992 UCD-SNMP-MIB::ssRawContexts.0 = Counter32: 1239253106 UCD-SNMP-MIB::ssCpuRawSoftIRQ.0 = Counter32: 338170 UCD-SNMP-MIB::ssRawSwapIn.0 = Counter32: 0 UCD-SNMP-MIB::ssRawSwapOut.0 = Counter32: 0
Angaben über Partitionen und dere Auslastung bekommt man mit snmpwalk -v2c -cpublic localhost .1.3.6.1.4.1.2021.9
bzw. snmpwalk -v3 -u public -l authNoPriv -a MD5 -A auth_pwd_local localhost .1.3.6.1.4.1.2021.9
[13], [14]. Auf dem Caipirinha-Server ergibt dies dann:
UCD-SNMP-MIB::dskIndex.1 = INTEGER: 1 UCD-SNMP-MIB::dskIndex.2 = INTEGER: 2 UCD-SNMP-MIB::dskIndex.3 = INTEGER: 3 UCD-SNMP-MIB::dskIndex.4 = INTEGER: 4 UCD-SNMP-MIB::dskIndex.5 = INTEGER: 5 UCD-SNMP-MIB::dskPath.1 = STRING: / UCD-SNMP-MIB::dskPath.2 = STRING: /home UCD-SNMP-MIB::dskPath.3 = STRING: /home/public/Video UCD-SNMP-MIB::dskPath.4 = STRING: /var UCD-SNMP-MIB::dskPath.5 = STRING: /backup UCD-SNMP-MIB::dskDevice.1 = STRING: rootfs UCD-SNMP-MIB::dskDevice.2 = STRING: /dev/mapper/cr_md2 UCD-SNMP-MIB::dskDevice.3 = STRING: /dev/md3 UCD-SNMP-MIB::dskDevice.4 = STRING: /dev/mapper/cr_md1 UCD-SNMP-MIB::dskDevice.5 = STRING: /dev/mapper/cr_sde1 ... UCD-SNMP-MIB::dskMinPercent.1 = INTEGER: 30 UCD-SNMP-MIB::dskMinPercent.2 = INTEGER: 10 UCD-SNMP-MIB::dskMinPercent.3 = INTEGER: 5 UCD-SNMP-MIB::dskMinPercent.4 = INTEGER: 20 UCD-SNMP-MIB::dskMinPercent.5 = INTEGER: 10 UCD-SNMP-MIB::dskTotal.1 = INTEGER: 51612944 UCD-SNMP-MIB::dskTotal.2 = INTEGER: 901563648 UCD-SNMP-MIB::dskTotal.3 = INTEGER: 2147483647 UCD-SNMP-MIB::dskTotal.4 = INTEGER: 8253744 UCD-SNMP-MIB::dskTotal.5 = INTEGER: 1922857728 UCD-SNMP-MIB::dskAvail.1 = INTEGER: 37133060 UCD-SNMP-MIB::dskAvail.2 = INTEGER: 622951360 UCD-SNMP-MIB::dskAvail.3 = INTEGER: 922618048 UCD-SNMP-MIB::dskAvail.4 = INTEGER: 2117264 UCD-SNMP-MIB::dskAvail.5 = INTEGER: 1687921664 UCD-SNMP-MIB::dskUsed.1 = INTEGER: 11858084 UCD-SNMP-MIB::dskUsed.2 = INTEGER: 232815424 UCD-SNMP-MIB::dskUsed.3 = INTEGER: 2147483647 UCD-SNMP-MIB::dskUsed.4 = INTEGER: 5717212 UCD-SNMP-MIB::dskUsed.5 = INTEGER: 234936064 UCD-SNMP-MIB::dskPercent.1 = INTEGER: 24 UCD-SNMP-MIB::dskPercent.2 = INTEGER: 27 UCD-SNMP-MIB::dskPercent.3 = INTEGER: 76 UCD-SNMP-MIB::dskPercent.4 = INTEGER: 73 UCD-SNMP-MIB::dskPercent.5 = INTEGER: 12 ... UCD-SNMP-MIB::dskErrorFlag.1 = INTEGER: noError(0) UCD-SNMP-MIB::dskErrorFlag.2 = INTEGER: noError(0) UCD-SNMP-MIB::dskErrorFlag.3 = INTEGER: noError(0) UCD-SNMP-MIB::dskErrorFlag.4 = INTEGER: noError(0) UCD-SNMP-MIB::dskErrorFlag.5 = INTEGER: noError(0) UCD-SNMP-MIB::dskErrorMsg.1 = STRING: UCD-SNMP-MIB::dskErrorMsg.2 = STRING: UCD-SNMP-MIB::dskErrorMsg.3 = STRING: UCD-SNMP-MIB::dskErrorMsg.4 = STRING: UCD-SNMP-MIB::dskErrorMsg.5 = STRING:
Einen Überblick über die Interfaces an einer Maschine bekommt man mit snmpwalk -v2c -cpublic localhost .1.3.6.1.2.1.2.2.1
bzw. snmpwalk -v3 -u public -l authNoPriv -a MD5 -A auth_pwd_local localhost .1.3.6.1.2.1.2.2.1
[15]. Dies liefert als Ausgabe auf dem Caipirinha-Server:
IF-MIB::ifIndex.1 = INTEGER: 1 IF-MIB::ifIndex.2 = INTEGER: 2 IF-MIB::ifIndex.3 = INTEGER: 3 IF-MIB::ifIndex.68 = INTEGER: 68 IF-MIB::ifIndex.70 = INTEGER: 70 IF-MIB::ifIndex.72 = INTEGER: 72 IF-MIB::ifIndex.73 = INTEGER: 73 IF-MIB::ifIndex.74 = INTEGER: 74 IF-MIB::ifDescr.1 = STRING: lo IF-MIB::ifDescr.2 = STRING: eth0 IF-MIB::ifDescr.3 = STRING: eth1 IF-MIB::ifDescr.68 = STRING: tun2 IF-MIB::ifDescr.70 = STRING: tun0 IF-MIB::ifDescr.72 = STRING: tun1 IF-MIB::ifDescr.73 = STRING: tun4 IF-MIB::ifDescr.74 = STRING: tun3 ... IF-MIB::ifMtu.1 = INTEGER: 16436 IF-MIB::ifMtu.2 = INTEGER: 1500 IF-MIB::ifMtu.3 = INTEGER: 1500 IF-MIB::ifMtu.68 = INTEGER: 1500 IF-MIB::ifMtu.70 = INTEGER: 1500 IF-MIB::ifMtu.72 = INTEGER: 1500 IF-MIB::ifMtu.73 = INTEGER: 1500 IF-MIB::ifMtu.74 = INTEGER: 1500 IF-MIB::ifSpeed.1 = Gauge32: 10000000 IF-MIB::ifSpeed.2 = Gauge32: 1000000000 IF-MIB::ifSpeed.3 = Gauge32: 10000000 IF-MIB::ifSpeed.68 = Gauge32: 0 IF-MIB::ifSpeed.70 = Gauge32: 0 IF-MIB::ifSpeed.72 = Gauge32: 0 IF-MIB::ifSpeed.73 = Gauge32: 0 IF-MIB::ifSpeed.74 = Gauge32: 0 ... IF-MIB::ifAdminStatus.1 = INTEGER: up(1) IF-MIB::ifAdminStatus.2 = INTEGER: up(1) IF-MIB::ifAdminStatus.3 = INTEGER: down(2) IF-MIB::ifAdminStatus.68 = INTEGER: up(1) IF-MIB::ifAdminStatus.70 = INTEGER: up(1) IF-MIB::ifAdminStatus.72 = INTEGER: up(1) IF-MIB::ifAdminStatus.73 = INTEGER: up(1) IF-MIB::ifAdminStatus.74 = INTEGER: up(1) IF-MIB::ifOperStatus.1 = INTEGER: up(1) IF-MIB::ifOperStatus.2 = INTEGER: up(1) IF-MIB::ifOperStatus.3 = INTEGER: down(2) IF-MIB::ifOperStatus.68 = INTEGER: up(1) IF-MIB::ifOperStatus.70 = INTEGER: up(1) IF-MIB::ifOperStatus.72 = INTEGER: up(1) IF-MIB::ifOperStatus.73 = INTEGER: up(1) IF-MIB::ifOperStatus.74 = INTEGER: up(1) ... IF-MIB::ifInOctets.1 = Counter32: 123922180 IF-MIB::ifInOctets.2 = Counter32: 2916738370 IF-MIB::ifInOctets.3 = Counter32: 0 IF-MIB::ifInOctets.68 = Counter32: 3764554219 IF-MIB::ifInOctets.70 = Counter32: 99214022 IF-MIB::ifInOctets.72 = Counter32: 5293853 IF-MIB::ifInOctets.73 = Counter32: 0 IF-MIB::ifInOctets.74 = Counter32: 0 ...
Interessanter is es aber, diese Abfrage bei einem Router zu machen. Ein solches Beispiel ist hier wiedergegeben:
IF-MIB::ifIndex.1 = INTEGER: 1 IF-MIB::ifIndex.2 = INTEGER: 2 IF-MIB::ifIndex.3 = INTEGER: 3 IF-MIB::ifIndex.4 = INTEGER: 4 IF-MIB::ifIndex.12 = INTEGER: 12 IF-MIB::ifIndex.21 = INTEGER: 21 IF-MIB::ifIndex.22 = INTEGER: 22 IF-MIB::ifIndex.23 = INTEGER: 23 IF-MIB::ifIndex.24 = INTEGER: 24 IF-MIB::ifIndex.25 = INTEGER: 25 IF-MIB::ifIndex.26 = INTEGER: 26 IF-MIB::ifDescr.1 = STRING: LOCAL_LOOPBACK IF-MIB::ifDescr.2 = STRING: LAN IF-MIB::ifDescr.3 = STRING: WLAN IF-MIB::ifDescr.4 = STRING: ATM1 IF-MIB::ifDescr.12 = STRING: PPPoE1 IF-MIB::ifDescr.21 = STRING: WDS1 IF-MIB::ifDescr.22 = STRING: WDS2 IF-MIB::ifDescr.23 = STRING: WDS3 IF-MIB::ifDescr.24 = STRING: WDS4 IF-MIB::ifDescr.25 = STRING: WAN2 IF-MIB::ifDescr.26 = STRING: COM1 ... IF-MIB::ifMtu.1 = INTEGER: 1500 IF-MIB::ifMtu.2 = INTEGER: 1500 IF-MIB::ifMtu.3 = INTEGER: 1500 IF-MIB::ifMtu.4 = INTEGER: 1500 IF-MIB::ifMtu.12 = INTEGER: 1492 IF-MIB::ifMtu.21 = INTEGER: 1500 IF-MIB::ifMtu.22 = INTEGER: 1500 IF-MIB::ifMtu.23 = INTEGER: 1500 IF-MIB::ifMtu.24 = INTEGER: 1500 IF-MIB::ifMtu.25 = INTEGER: 1500 IF-MIB::ifMtu.26 = INTEGER: 1500 IF-MIB::ifSpeed.1 = Gauge32: 0 IF-MIB::ifSpeed.2 = Gauge32: 100000000 IF-MIB::ifSpeed.3 = Gauge32: 54000000 IF-MIB::ifSpeed.4 = Gauge32: 224000 IF-MIB::ifSpeed.12 = Gauge32: 2304000 IF-MIB::ifSpeed.21 = Gauge32: 54000000 IF-MIB::ifSpeed.22 = Gauge32: 54000000 IF-MIB::ifSpeed.23 = Gauge32: 54000000 IF-MIB::ifSpeed.24 = Gauge32: 54000000 IF-MIB::ifSpeed.25 = Gauge32: 100000000 IF-MIB::ifSpeed.26 = Gauge32: 0 ... IF-MIB::ifAdminStatus.1 = INTEGER: up(1) IF-MIB::ifAdminStatus.2 = INTEGER: up(1) IF-MIB::ifAdminStatus.3 = INTEGER: up(1) IF-MIB::ifAdminStatus.4 = INTEGER: up(1) IF-MIB::ifAdminStatus.12 = INTEGER: up(1) IF-MIB::ifAdminStatus.21 = INTEGER: up(1) IF-MIB::ifAdminStatus.22 = INTEGER: up(1) IF-MIB::ifAdminStatus.23 = INTEGER: up(1) IF-MIB::ifAdminStatus.24 = INTEGER: up(1) IF-MIB::ifAdminStatus.25 = INTEGER: 0 IF-MIB::ifAdminStatus.26 = INTEGER: 0 IF-MIB::ifOperStatus.1 = INTEGER: up(1) IF-MIB::ifOperStatus.2 = INTEGER: up(1) IF-MIB::ifOperStatus.3 = INTEGER: up(1) IF-MIB::ifOperStatus.4 = INTEGER: up(1) IF-MIB::ifOperStatus.12 = INTEGER: up(1) IF-MIB::ifOperStatus.21 = INTEGER: up(1) IF-MIB::ifOperStatus.22 = INTEGER: up(1) IF-MIB::ifOperStatus.23 = INTEGER: up(1) IF-MIB::ifOperStatus.24 = INTEGER: up(1) IF-MIB::ifOperStatus.25 = INTEGER: 0 IF-MIB::ifOperStatus.26 = INTEGER: 0 ... IF-MIB::ifInOctets.1 = Counter32: 210 IF-MIB::ifInOctets.2 = Counter32: 0 IF-MIB::ifInOctets.3 = Counter32: 101309606 IF-MIB::ifInOctets.4 = Counter32: 511415216 IF-MIB::ifInOctets.12 = Counter32: 250011578 IF-MIB::ifInOctets.21 = Counter32: 0 IF-MIB::ifInOctets.22 = Counter32: 0 IF-MIB::ifInOctets.23 = Counter32: 0 IF-MIB::ifInOctets.24 = Counter32: 0 IF-MIB::ifInOctets.25 = Counter32: 0 IF-MIB::ifInOctets.26 = Counter32: 0 ... IF-MIB::ifOutOctets.1 = Counter32: 0 IF-MIB::ifOutOctets.2 = Counter32: 62445328 IF-MIB::ifOutOctets.3 = Counter32: 0 IF-MIB::ifOutOctets.4 = Counter32: 109637356 IF-MIB::ifOutOctets.12 = Counter32: 50021044 IF-MIB::ifOutOctets.21 = Counter32: 0 IF-MIB::ifOutOctets.22 = Counter32: 0 IF-MIB::ifOutOctets.23 = Counter32: 0 IF-MIB::ifOutOctets.24 = Counter32: 0 IF-MIB::ifOutOctets.25 = Counter32: 0 IF-MIB::ifOutOctets.26 = Counter32: 0
Die interessanten Interfaces sind hier #12 (PPPoE1), welches Statistiken der über ADSL transportierten Datenmengen an diesem Router zählt und #3, welches die über das WLAN transportierten Datenmengen protokolliert.
Posted on: 2012-12-08Gabriel Rüeck