Table of Contents
Monitoraggio SNMP
Introduzione
L'architettura SNMP è di tipo client server. Il server viene interrogato o impostato dal client con i comandi GET, GET-NEXT, GET-RESPONSE e SET. Il server può informare il client con il comando TRAP.
Gli attributi monitorabili sono organizzati in un MIB (Management Information Base) che ha una struttora ad albero. Ogni oggetto ho un identificativo (OID) che indica anche la sua gerarchia (es: “1.1.0”) e pure una label descrittiva (es: “system.sysDescr.0”). Quindi si puo' usare indifferentemente una di queste sintassi per riferirsi ad un attributo:
1.1.0 system.sysDescr.0 1.sysDescr.0
La gerarchia (albero) dei simboli e i loro nomi sono codificati nel RFC1066 MIB. La radice degli oggetti - se non indicata - è per convenzione .iso.org.dod.internet.mgmt.mib.
cioè in numeri .1.3.6.1.2.1.
. Vedi a proposito man variables(5snmp)
. Nota che i nomi dei simboli distinguono le maiuscole/minuscole a differenza di quello che dice la man page.
Per convertire il formato numerico di un OID nella suo nome simbolico si usa snmptranslate:
snmptranslate .1.3.6.1.2.1.25.2 HOST-RESOURCES-MIB::hrStorage
Se non funziona verificare che sia stato installato il pacchetto snmp-mibs-downloader (che provvede a scaricare e installare il database dei MIBS) e commentare la riga che definisce MIBS= nel file /etc/default/snmpd.
Per convertire viceversa i nomi degli attributi dal formato testuale a quello numerico:
# snmptranslate -On IF-MIB::ifName.2 .1.3.6.1.2.1.31.1.1.1.1.2 # snmptranslate -m ALL .1.3.6.1.2.1.31.1.1.1.1.2 IF-MIB::ifName.2 # snmptranslate -Of IF-MIB::ifName.2 .iso.org.dod.internet.mgmt.mib-2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifName.2 # snmpget -v1 -c public 127.0.0.1 IF-MIB::ifName.2 IF-MIB::ifName.2 = STRING: eth0 # snmpget -v1 -c public 127.0.0.1 1.3.6.1.2.1.31.1.1.1.1.2 IF-MIB::ifName.2 = STRING: eth0 # snmptranslate -Td IF-MIB::ifName IF-MIB::ifName ifName OBJECT-TYPE -- FROM IF-MIB -- TEXTUAL CONVENTION DisplayString SYNTAX OCTET STRING (0..255) DISPLAY-HINT "255a" MAX-ACCESS read-only STATUS current DESCRIPTION "The textual name of the interface. The value of this object should be the name of the interface as assigned by the local device and should be suitable for use in commands entered at the device's `console'. This might be a text ...
Nota che snmptranslate e' in grado anche di cercare espressioni regolari in tutta la gerarchia MIB, cosi' che trovare un certo OID diventa piu' facile:
# snmptranslate -Ib 'sys.*ime' SNMPv2-MIB::sysORUpTime
SNMP
Sulla macchina da monitorare deve essere installato il demone SNMP, si installa il pacchetto snmpd. Anche se il firewall blocca l'accesso al demone dall'esterno, conviene fare una configurazione un po' più accorta di /etc/snmp/snmpd.conf
, vedere man snmpd.conf(5)
.
La configurazione di default di Debian è già particolarmente paranoica, si deve dare accesso almeno in sola lettura a 127.0.0.1 per fare in modo che MRTG possa fare le sue statistiche: aggiunta la riga:
com2sec readonly 127.0.0.1 public
Impostate anche syslocation
e syscontact
in modo che diano informazioni sensate.
Per vedere se funziona si installa il pacchetto snmp (tool client) e si prova ad usare uno dei comandi:
snmpwalk -v 1 -c public 127.0.0.1 snmpget -v 1 -c public 127.0.0.1 system.sysDescr.0 snmpnetstat -v 1 -c public -o -n 127.0.0.1
L'interrogazione funziona utilizzando la versione 1 o 2c del protocollo (opzione -v), per la versione 3 sarebbe richiesto impostare altre opzioni tipo la securityName, ecc.
Ovviamente si deve conoscere il nome della community (“public” in questo esempio), ed avere i permessi per fare la richiesta. Con snmpwalk si ha l'elenco di tutte le label degli OID interrogabili. Con snmpget si legge il valore dell'attributo. Snmpnetstat presenta alcuni dati relativi alle interfacce di rete in modo più leggibile.
La versione più recente del pacchetto Debian binda il demone solo sull'indirizzo 127.0.0.1, per mettersi in ascolto su tutti gli indirizzi IP bisogna togliere tale indirizzo dalla variabile SNMPDOPTS
dal file /etc/default/snmpd
.
Controllo del log
L'installazione predefinita di Debian Wheezy genera una riga di log per ogni interrogazione SNMP, se pare eccessiva basta modificare il livello di log agendo sulla variabile SNMPDOPTS
del file /etc/default/snmpd
:
SNMPDOPTS='-LS0-5d ...
In questo caso S0-5 significa loggare su syslog da LOG_EMERG
to LOG_NOTICE
, d indica la facility LOG_DAEMON
. Vedere snmpcmd(1)
.
Aggiunta di sensori SNMP
Creato uno script per interfacciare snmpd a varie utility di sistema come i sensori della scheda madre, utility per misurare latenza e pacchetti
persi (netmonitor), ecc. Poi si aggiungono in /etc/snmp/snmpd.conf
delle righe del tipo:
exec sensors1 /usr/local/sbin/snmpd-helper fan exec sensors2 /usr/local/sbin/snmpd-helper cpu
A questo punto il sensore è leggibile con:
snmpwalk -v1 -c public 127.0.0.1 UCD-SNMP-MIB::extOutput.1
Come si vede il valore è disponibile sotto un MIB differente, la radice in questo caso è .1.3.6.1.4.1.2021.8.1. (UCD-SNMP-MIB::).
Con la nuova sintassi di snmpd.conf
(introdotta con la versione 5.2.x e quindi da preferire ad esempio con snmpd
5.4.3) la direttiva exec
viene deprecata, al suo posto si usa extend
:
extend sensors_cpu_fan /usr/local/sbin/snmpd-helper fan extend sensors_sys_fan /usr/local/sbin/snmpd-helper fan2
in questo caso l'OID da leggere è:
snmpwalk -v1 -c public 127.0.0.1 'NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."sensors_cpu_fan"'
Il vantaggio è che l'OID viene indirizzato non con l'indice numerico (che dipende dall'ordine in cui è definito nel file di configurazione), ma da una etichetta.
Notare l'uso degli apici nel comando da shell, in quanto le doppie virgolette fanno parte a tutti gli effetti del nome dell'OID.
Esempi configurazione
Per comodità si può suddividere la configurazione in diversi file ed includerli nel file /etc/mrtg/mrtg.cfg
:
#LoadMIBs: /usr/share/snmp/mibs/UCD-SNMP-MIB.txt LoadMIBs: /usr/share/mibs/netsnmp/UCD-SNMP-MIB WorkDir: /var/www/mrtg Include: eth0 Include: cpu1 Include: fan1 Include: free
### Interface eth0 Target[eth0]: \eth0:public@localhost: Title[eth0]: Traffic for interface eth0 PageTop[eth0]: <H1>Traffic for interface eth0</H1> Options[eth0]: growright,bits,noinfo,unknaszero MaxBytes[eth0]: 13107200 #Unscaled[eth0]: dwm
### CPU Load Target[cpu1]: ( ssCpuRawUser.0&ssCpuRawUser.0:public@localhost + ssCpuRawSystem.0&ssCpuRawSystem.0:public@localhost + ssCpuRawNice.0&ssCpuRawNice.0:public@localhost ) / 2 Title[cpu1]: CPU LOAD PageTop[cpu1]: <H1>Active CPU Load %</H1> Colours[cpu1]: ORANGE#ff5c00,BLACK#000000,DARK GREEN#006600,VIOLET#ff00ff MaxBytes[cpu1]: 100 Unscaled[cpu1]: dwmy ShortLegend[cpu1]: % YLegend[cpu1]: CPU Utilization Legend1[cpu1]: Active CPU in % (Load) Legend2[cpu1]: Legend3[cpu1]: Legend4[cpu1]: LegendI[cpu1]: Load: LegendO[cpu1]: #Options[cpu1]: noo,growright,nopercent,noinfo,unknaszero Options[cpu1]: growright,nopercent,noinfo,unknaszero
NOTA: Il carico della CPU deve essere diviso per il numero di core presenti (vedere con cat /proc/cpuinfo
, 2 nell'esempio sopra). Il contatore SNMP infatti fornisce il numero di ticks di CPU spesi nell'eseguire i processi, ci sono 100 ticks per CPU al secondo.
### CPU Fan Target[fan1]: .1.3.6.1.4.1.2021.8.1.101.1&.1.3.6.1.4.1.2021.8.1.101.2:public@localhost Title[fan1]: CPU Fan PageTop[fan1]: <H1>CPU and System Fans</H1> Options[fan1]: gauge,growright,nopercent,noinfo,unknaszero,integer Colours[fan1]: CYAN#92D5FF,BLUE#1000ff,DARK GREEN#006600,VIOLET#ff00ff YLegend[fan1]: RPM ShortLegend[fan1]: rpm MaxBytes[fan1]: 5000 Unscaled[fan1]: dwmy kMG[fan1]: Legend1[fan1]: CPU Fan RPM Legend2[fan1]: System Fan RPM Legend3[fan1]: Legend4[fan1]: LegendI[fan1]: CPU Fan: LegendO[fan1]: Sys Fan:
### Free memory Target[free]: .1.3.6.1.4.1.2021.4.4.0&.1.3.6.1.4.1.2021.4.6.0:public@localhost Title[free]: Free memory PageTop[free]: <H1>Free memory</H1> Options[free]: gauge,growright,nopercent,noinfo,unknaszero Colours[free]: LIGHT GREEN#73d290,GREEN#0c680c,DARK GREEN#006600,VIOLET#ff00ff MaxBytes1[free]: 1000000 MaxBytes2[free]: 2000000 kMG[free]: k,M,G,T,P,X YLegend[free]: bytes ShortLegend[free]: bytes Legend1[free]: Free swap memory, in bytes Legend2[free]: Free memory, not including swap, in bytes LegendI[free]: Free swap: LegendO[free]: Free memory:
The follogin example is for disk free graph. You need to adjust the MaxBytes
to the size of your partition:
Target[df_md0]: `/usr/local/bin/mrtg-diskfree /dev/md0` Title[df_md0]: Disk Usage /dev/md0 Unscaled[df_md0]: dwym MaxBytes[df_md0]: 4814824 PageTop[df_md0]: <H1>Disk Usage /dev/md0</H1> kmg[df_md0]: KB,MB,GB Colours[df_md0]: BLUE#0000ff,VIOLET#ff00ff,RED#ff0000,DARK BLUE#00007f LegendI[df_md0]: Used Disk Space LegendO[df_md0]: Total Disk Space Legend1[df_md0]: Used Disk Space Legend2[df_md0]: Total Disk Space YLegend[df_md0]: bytes ShortLegend[df_md0]: bytes Options[df_md0]: gauge, growright, noinfo
you also need the following script mrtg-diskfree:
#!/bin/sh # It assumes that the command output(df -klP) looks like this: # # Filesystem 1K-blocks Used Available Use% Mounted on # /dev/md0 4814824 781300 3788944 18% / # tmpfs 1037648 0 1037648 0% /lib/init/rw # udev 10240 64 10176 1% /dev # tmpfs 1037648 4 1037644 1% /dev/shm # /dev/md2 148483184 208412 148274772 1% /home DEV="$1" if [ ! -b "$DEV" ]; then echo "Usage: $(basename $0) <device>" exit 1 fi df="$(df -klP | egrep "^${DEV}\b")" size="$(echo $df | awk '{print $2}')" used="$(echo $df | awk '{print $3}')" echo $used echo $size
This graph displays the packet loss percentage with a remote host. It requires the mrtg-ping-probe
script, available also as a Debian package:
### Packet loss Target[loss_192.168.2.2]: `/usr/bin/mrtg-ping-probe -p loss/loss 217.58.146.19` Title[loss_192.168.2.2]: Packet loss 192.168.2.2 PageTop[loss_192.168.2.2]: <H1>Packet loss 192.168.2.2</H1> Options[loss_192.168.2.2]: noo,gauge,growright,nopercent,noinfo,unknaszero,withzeroes Colours[loss_192.168.2.2]: RED#d60000,BLUE#1000ff,DARK GREEN#006600,VIOLET#ff00ff MaxBytes[loss_192.168.2.2]: 100 Unscaled[loss_192.168.2.2]: dwmy YLegend[loss_192.168.2.2]: Packet loss % ShortLegend[loss_192.168.2.2]: % Legend1[loss_192.168.2.2]: Packet loss in % Legend2[loss_192.168.2.2]: LegendI[loss_192.168.2.2]: loss LegendO[loss_192.168.2.2]:
This graph displays the packet max/min round-trip time (ping) with a remote host. It requires the mrtg-ping-probe
script, available also as a Debian package:
### Ping Target[ping_88.149.128.3]: `/usr/bin/mrtg-ping-probe -p avg/max 88.149.128.3` Title[ping_88.149.128.3]: Ping 88.149.128.3 (ping.ngi.it) PageTop[ping_88.149.128.3]: <H1>Ping 88.149.128.3 (ping.ngi.it)</H1> Options[ping_88.149.128.3]: gauge,growright,nopercent,noinfo Colours[ping_88.149.128.3]: YELLOW#d37d00,RED#910000,YELLOW#d37d00,RED#910000 MaxBytes[ping_88.149.128.3]: 3000 YLegend[ping_88.149.128.3]: Ping time (ms) ShortLegend[ping_88.149.128.3]: ms Legend1[ping_88.149.128.3]: Average Round Trip Time in ms Legend2[ping_88.149.128.3]: Maximum Round Trip Time in ms LegendI[ping_88.149.128.3]: Avg: LegendO[ping_88.149.128.3]: Max:
Temperature graph using lmsensors. Verify that the version of Net-SNMP on the target system was compiled with the lmSensors extension by running snmpd -Dmib_init
and looking through the output for the lmSensors
string. Then you need to discover the MIB of your sensor:
snmpwalk -v2c -c public localhost 1.3.6.1.4.1.2021.13.16
In my case the temperature is multiplied by 1000:
### Sensor temp1 Target[temp1]: iso.3.6.1.4.1.2021.13.16.2.1.3.1&iso.3.6.1.4.1.2021.13.16.2.1.3.1:public@localhost Factor[temp1]: 0.001 YTicsFactor[temp1]: 0.001 Title[temp1]: Temperature temp1 PageTop[temp1]: <H1>Temperature temp1</H1> Options[temp1]: noo,gauge,growright,nopercent,noinfo,unknaszero,withzeroes Colours[temp1]: RED#d60000,BLUE#1000ff,DARK GREEN#006600,VIOLET#ff00ff MaxBytes[temp1]: 150000 Unscaled[temp1]: dwmy YLegend[temp1]: Temp C° ShortLegend[temp1]: C° Legend1[temp1]: Temperature in C° Legend2[temp1]: LegendI[temp1]: Temp C° LegendO[temp1]:
It seems that MRTG does not support UTF-8 (even version 2.17.4), so the configuration file should be encoded in ISO_8859-1. Special characters used in HTML output should be encoded properly.
See this article: lmSensors/Net-SNMP Sensor Readings .
MIBs e Debian (Squeeze e successive)
Vedere il wiki Debian.
Tradizionalmente i file contenenti i MIBs di IETF e di IANA venivano distribuiti con il pacchetto libsnmp-base
, per problemi di licenza questo non è più possibile (dalla versione net-snmp 5.4.2.1~dfsg-1).
Tuttavia installando il pacchetto non-free snmp-mibs-downloader è possibile scaricare i file in questione, che verranno salvati nella directory /var/lib/mibs/
.
Per utilizzare i file scaricati bisogna commentare una riga nel file /etc/snmp/snmp.conf
:
# If you added the MIBs you can reenable # loaging them by commenting out the following line. #mibs :
Stessa cosa bisogna farla per il demone snmpd, aggiungendo una riga in /etc/default/snmpd
:
export MIBS=UCD-SNMP-MIB
Utilizzare almeno la versione 1.1 del pacchetto snmp-mibs-downloader, con versioni precedenti alcuni MIBs non vengono scaricati e si incappa in errori del tipo:
snmptranslate -O n UCD-SNMP-MIB::extOutput.2 No log handling enabled - turning on stderr logging Cannot find module (IANAifType-MIB): At line 13 in /usr/share/mibs/ietf/IF-MIB Did not find 'IANAifType' in module #-1 (/usr/share/mibs/ietf/IF-MIB) Cannot find module (IANA-RTPROTO-MIB): At line 12 in /usr/share/mibs/ietf/IP-FORWARD-MIB Did not find 'IANAipRouteProtocol' in module #-1 (/usr/share/mibs/ietf/IP-FORWARD-MIB) .1.3.6.1.4.1.2021.8.1.101.2
Nuova sintassi per snmpd.conf
Con Debian Squeeze la configurazione di snmpd utilizza per default un nuovo formato che comprende regole di ACL, ecc.
Come mettere il demone in ascolto su tutte le interfacce di rete:
#agentAddress udp:127.0.0.1:161 agentAddress udp:161
Come esporre tutte le informazioni disponibili alla community public:
#rocommunity public default -V systemonly rocommunity public default
Come aggiungere grandezze da monitorare tramite script esterni:
extend mail_incoming /usr/bin/sudo /usr/local/sbin/mail-io-stats incoming extend mail_cmpleted /usr/bin/sudo /usr/local/sbin/mail-io-stats completed
Per leggere le grandezze aggiuntive si utilizza un OID indicizzato con l'etichetta invece che dalla posizione in cui compare. Notare che le doppie virgolette fanno parte dell'OID:
snmpwalk -v 2c -c public 127.0.0.1 'NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."mail_incoming"' NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."mail_incoming" = STRING: 14
SNMP su ipv6
Con Debian Wheezy sono necessarie alcune accortezze perché SNMP risponda anche su IPV6, in particolare /etc/snmp/snmpd.conf
:
agentAddress udp::161 agentaddress udp6:161 rocommunity public default rocommunity6 public default
SNMP con systemd su Debian 9 e seguenti
Debian 9 Stretch utilizza il sistema di init systemd invece del vecchio sysvinit. Le personalizzazioni all'avvio non si fanno più in /etc/default/snmpd
.
La risoluzione degli OIDs nella loro descrizione testuale richiede sempre l'installazione del pacchetto non-free snmp-mibs-downloader. Invece di impostare la variabile d'ambient MIBS si deve modificare il file /etc/snmp/snmp.conf, commentando (disattivando) la riga:
#mibs :
Eventuali personalizzazioni dei parametri di snmpd non si fanno più con la variabile d'ambiente SNMPDOPTS, bisogna piuttosto creare il file /etc/systemd/system/snmpd.service, prendendo come esempio quello predefinito /lib/systemd/system/snmpd.service
. Il file personalizzato prevale su quello di sistema (basta eseguire systemctl daemon-reload). Pare che non sia necessario aggiornare i link simbolici, ad esempio quello contenuto in /etc/systemd/system/multi-user.target.wants/
.
Ecco ad esempio come modificare la riga ExecStart per diminuire il logging e sopprimere tutte le righe Connection from UDP che riempiono il syslog (nota: si modifica -Lsd in -LSwd):
ExecStart=/usr/sbin/snmpd -LSwd -Lf /dev/null -u Debian-snmp -g Debian-snmp -I -smux,mteTrigger,mteTriggerConf -f -p /run/snmpd.pid
In alternativa a sostituire completamente il file unit (cioè il file /etc/systemd/system/snmpd.service) è possibile creare un file override con solo le modifiche necessarie. Il file override deve stare nella directory /etc/systemd/system/snmpd.service.d/ e può chiamarsi local.conf (è possibile averne più di uno). Fare attenzione al parametro ExecStart che deve essere svuotato prima di essere definito nuovamente:
[Service] Environment="MIBS=" ExecStart= ExecStart=/usr/sbin/snmpd -LSwd -Lf /dev/null -u Debian-snmp -g Debian-snmp -I -smux,mteTrigger,mteTriggerConf -f -p /run/snmpd.pid
Spazio disco
Per monitorare lo spazio disco esistono due famiglie di OID diversi: UCD-SNMP-MIB e HOST-RESOURCES-MIB.
UCD-SNMP-MIB
Ci sono tre OID della famiglia UCD-SNMP-MIB normalmente utilizzati per monitorare lo spazio disco disponibile:
- UCD-SNMP-MIB::dskUsed
- UCD-SNMP-MIB::dskAvail
- UCD-SNMP-MIB::dskTotal
Ognuno di essi viene indicizzato con un intero che rappresenta una partizione in uso al sistema operativo. Per interrogare il server SNMP si può usare la riga di comando:
snmpwalk host.domain.org -v2c -c public UCD-SNMP-MIB::dskAvail
Sul server si deve aver abilitato questo OID con una direttiva disk per ogni filesystem montato oppure con la direttiva includeAllDisks. Ciascuna direttiva è seguita da MINPERCENT%, valore che può essere interrogato dal client con l'OID UCD-SNMP-MIB::dskMinPercent. Ad esempio si possono aggiungere le seguenti righe al file di configurazione /etc/snmp/snmpd.conf:
# Disk Monitoring # 10MBs required on root disk, 5% free on /var, 10% free on all other disks disk / 10000 disk /var 5% includeAllDisks 10%
HOST-RESOURCES-MIB
Esistono anche gli OID della famiglia HOST-RESOURCES-MIB per interrogare lo spazio disco; lo spazio disponibile deve essere calcolato come differenza fra dimensione totale e spazio usato:
- HOST-RESOURCES-MIB::hrStorageSize
- HOST-RESOURCES-MIB::hrStorageUsed
- HOST-RESOURCES-MIB::hrStorageDescr
Per attivare questi OID sul server non è necessario alcuna direttiva particolare nel file di configurazione /etc/snmp/snmpd.conf.