====== 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]: Traffic for interface eth0
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]: Active CPU Load %
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]: CPU and System Fans
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]: Free memory
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]: Disk Usage /dev/md0
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) "
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]: Packet loss 192.168.2.2
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]: Ping 88.149.128.3 (ping.ngi.it)
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]: Temperature temp1
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: [[http://www.eric-a-hall.com/software/cacti-netsnmp-lmsensors/|lmSensors/Net-SNMP Sensor Readings ]].
===== MIBs e Debian (Squeeze e successive) =====
Vedere il [[https://wiki.debian.org/SNMP|wiki Debian]].
Tradizionalmente i file contenenti i MIBs di [[http://www.ietf.org/|IETF]] e di [[http://www.iana.org/|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**.