Uno switch saturo, un disco che si riempie, un alimentatore che cede in un UPS. Per saperlo prima degli utenti, gli apparati devono poter dire come stanno. Dalla fine degli anni '80, è il compito di SNMP.
Il protocollo è ovunque: switch, router, firewall, server, stampanti, UPS, condizionatori della sala server. È anche spesso configurato male, con una community public dimenticata e una versione che invia tutto in chiaro.
Questo articolo riparte dall'inizio: il funzionamento, i dati, le tre versioni e le loro differenze, poi la configurazione e la sicurezza.
A cosa serve SNMP
SNMP significa Simple Network Management Protocol. Serve a due cose.
- Leggere lo stato di un apparato: traffico di un'interfaccia, carico del processore, temperatura, spazio su disco, stato di una porta
- Ricevere avvisi: l'apparato segnala da solo quando un collegamento cade o una ventola si ferma
In teoria permette anche di modificare la configurazione. In pratica non si usa quasi mai per questo, e ci sono buone ragioni per vietarlo.
L'architettura: manager, agent e MIB
Tre elementi lavorano insieme.
- Il manager: il server di monitoraggio (Zabbix, LibreNMS, Centreon). Pone le domande e riceve gli avvisi
- L'agent: un piccolo servizio che gira sull'apparato monitorato. Risponde alle domande e invia gli avvisi
- La MIB: il catalogo delle informazioni che l'agent sa fornire
Gli scambi passano da UDP.
| Porta | Direzione | Uso |
|---|---|---|
| UDP 161 | dal manager all'agent | richieste e risposte |
| UDP 162 | dall'agent al manager | avvisi (trap e inform) |
UDP non offre alcuna garanzia di consegna. Una richiesta persa viene semplicemente reinviata dal manager dopo un certo tempo. Un avviso perso, invece, è perso per sempre. Ci torneremo.
Gli OID e la MIB
Un albero di numeri
Ogni informazione ha un identificatore unico, l'OID (Object Identifier). Gli OID formano un albero mondiale, gestito da enti di standardizzazione.
iso (1)
└─ org (3)
└─ dod (6)
└─ internet (1)
├─ mgmt (2)
│ └─ mib-2 (1) MIB standard: 1.3.6.1.2.1
│ ├─ system (1)
│ └─ interfaces (2)
└─ private (4)
└─ enterprises (1) MIB dei produttori: 1.3.6.1.4.1
├─ cisco (9)
└─ mikrotik (14988)
Alcuni OID che si incontrano ogni giorno:
| Nome | OID | Contenuto |
|---|---|---|
| sysDescr.0 | 1.3.6.1.2.1.1.1.0 | descrizione del sistema |
| sysUpTime.0 | 1.3.6.1.2.1.1.3.0 | tempo dall'avvio dell'agent |
| sysName.0 | 1.3.6.1.2.1.1.5.0 | nome dell'apparato |
| ifDescr | 1.3.6.1.2.1.2.2.1.2 | nome di ogni interfaccia |
| ifOperStatus | 1.3.6.1.2.1.2.2.1.8 | stato reale di ogni interfaccia |
| ifHCInOctets | 1.3.6.1.2.1.31.1.1.1.6 | byte ricevuti, contatore a 64 bit |
Il .0 finale indica l'unica istanza di un valore semplice. Per una tabella, l'ultimo numero è l'indice della riga: ifDescr.3 è il nome dell'interfaccia numero 3.
La MIB
Una MIB è un file di testo che descrive una parte dell'albero: il nome di ogni OID, il suo tipo, i diritti di accesso e il significato. Permette di scrivere IF-MIB::ifDescr invece di 1.3.6.1.2.1.2.2.1.2.
Esistono due famiglie:
- le MIB standard, descritte nelle RFC, come MIB-II (RFC 1213) o IF-MIB (RFC 2863). Tutti gli apparati le capiscono
- le MIB dei produttori, sotto
enterprises. Ogni produttore ci mette le proprie informazioni: temperatura dei moduli Cisco, stato dei tunnel MikroTik
L'agent non ha bisogno dei file MIB per funzionare. Servono al manager e alle persone, per tradurre i numeri in nomi.
I tipi di dati
| Tipo | Uso |
|---|---|
| INTEGER | un valore intero, o uno stato codificato (1 = up, 2 = down) |
| OCTET STRING | testo o byte grezzi |
| Counter32 / Counter64 | un contatore che può solo aumentare |
| Gauge32 | un valore che sale e scende |
| TimeTicks | una durata in centesimi di secondo |
| IpAddress | un indirizzo IPv4 |
Contatore o gauge: la differenza che falsa i grafici
Un gauge dà un valore diretto. Una temperatura di 42 vale 42.
Un contatore può solo salire. ifInOctets vale 8.734.501.223: è il totale dei byte ricevuti dall'avvio, e non dice nulla sul traffico attuale. Per ottenere una velocità, il manager legge il contatore due volte e divide la differenza per il tempo trascorso.
velocità = (valore2 - valore1) / (tempo2 - tempo1)
La trappola viene dai contatori a 32 bit. Arrivano al massimo a 2^32, circa 4,3 miliardi, poi ripartono da zero. Su un'interfaccia a 1 Gbit/s satura, ifInOctets ricomincia il giro in 34 secondi. A 10 Gbit/s, in 3,4 secondi.
Se il manager interroga ogni cinque minuti, non può sapere quanti giri il contatore ha fatto tra due letture. Il grafico diventa sbagliato senza avvisare. La soluzione è usare i contatori a 64 bit della tabella ifXTable: ifHCInOctets e ifHCOutOctets. HC significa High Capacity. Non esistono in SNMPv1.
Stessa logica per sysUpTime: in centesimi di secondo su 32 bit, torna a zero dopo 497 giorni. Un apparato che sembra essersi riavviato potrebbe aver semplicemente superato quel limite.
Le operazioni
I messaggi SNMP si chiamano PDU (Protocol Data Unit).
| PDU | Versione | Ruolo |
|---|---|---|
| GetRequest | v1 | leggere uno o più valori precisi |
| GetNextRequest | v1 | leggere l'OID successivo nell'albero |
| SetRequest | v1 | modificare un valore |
| Response | v1 | risposta dell'agent |
| Trap | v1 | avviso inviato senza conferma di ricezione |
| GetBulkRequest | v2c | leggere molti valori in una volta |
| InformRequest | v2c | avviso con conferma di ricezione |
| Report | v3 | scambi interni alla sicurezza della v3 |
Percorrere una tabella
GetNext permette di percorrere un ramo che non si conosce in anticipo. Si chiede l'OID successivo, poi quello dopo, fino a uscire dal ramo. È quello che fa il comando snmpwalk.
Il difetto: un viaggio di andata e ritorno in rete per ogni valore. Su uno switch a 48 porte, leggere dieci colonne della tabella delle interfacce richiede quasi 500 scambi.
GetBulk, aggiunto nella v2c, risolve il problema. Il manager chiede «i 50 valori successivi» in un solo messaggio. È la stessa idea del problema N+1 in un ORM: raggruppare le letture invece di farle una per una.
Interrogare o essere avvisati
Ci sono due modi per sapere cosa succede.
- Il polling: il manager interroga ogni apparato a intervalli regolari, di solito tra uno e cinque minuti. È affidabile e alimenta i grafici
- Gli avvisi: l'apparato segnala appena succede qualcosa. È immediato, ma solo per gli eventi previsti dall'agent
Una trap parte in UDP senza conferma di ricezione. Se il pacchetto si perde, nessuno lo saprà. Un inform, aggiunto nella v2c, aspetta una conferma e viene reinviato se non la riceve.
In pratica si combinano entrambi. Gli avvisi danno la reattività, il polling recupera ciò che hanno perso.
Le tre versioni
SNMPv1
La prima versione è stata pubblicata nel 1988, poi rivista nel 1990 nella RFC 1157. Pone tutte le basi: manager, agent, MIB, Get, GetNext, Set e Trap.
La sua sicurezza sta in una parola: la community. È una semplice stringa inviata con ogni richiesta, come una password condivisa. Viaggia in chiaro sulla rete. Chiunque possa ascoltare il traffico la legge con Wireshark.
I valori predefiniti peggiorano le cose: public in lettura, private in scrittura, su migliaia di apparati mai riconfigurati.
Altri limiti: nessun contatore a 64 bit, e una gestione degli errori elementare. Se una richiesta chiede dieci OID e uno solo non esiste, fallisce tutta la richiesta.
SNMPv2c
La storia della v2 è un po' caotica. Una prima SNMPv2, pubblicata nel 1993, proponeva un modello di sicurezza ambizioso. Era così complesso che quasi nessuno l'ha implementato. Sono seguite diverse varianti concorrenti, poi nel 1996 si è trovato un accordo sulla più semplice: SNMPv2c.
La «c» significa community-based. La v2c mantiene la sicurezza della v1, con la community in chiaro, e porta i miglioramenti del protocollo.
- GetBulk per leggere le tabelle molto più in fretta
- Inform per avvisi con conferma di ricezione
- Counter64 per i contatori a 64 bit, indispensabili oltre i 100 Mbit/s
- Errori migliori: un OID assente restituisce un'eccezione solo per quella variabile (
noSuchObject,noSuchInstance,endOfMibView), invece di far fallire tutta la richiesta
È ancora oggi la versione più diffusa, perché è semplice da configurare. La sua sicurezza, invece, non è migliorata dal 1988.
SNMPv3
Pubblicata nel 2002 nelle RFC dalla 3411 alla 3418, la v3 mantiene le operazioni della v2c e sostituisce completamente la sicurezza. Si basa su due modelli.
USM (User-based Security Model, RFC 3414) sostituisce la community con veri utenti. Ogni utente ha:
- un protocollo di autenticazione: HMAC con MD5 o SHA-1 all'origine, poi la famiglia SHA-2 (da SHA-224 a SHA-512) aggiunta dalla RFC 7860 nel 2016
- un protocollo di cifratura: DES all'origine, poi AES-128 aggiunto dalla RFC 3826 nel 2004
- due password, una per ogni protocollo
Sono possibili tre livelli di sicurezza:
| Livello | Autenticazione | Cifratura | Uso |
|---|---|---|---|
| noAuthNoPriv | no | no | da evitare, appena meglio di una community |
| authNoPriv | sì | no | i dati viaggiano in chiaro |
| authPriv | sì | sì | l'unico livello da usare |
L'autenticazione garantisce che il messaggio provenga davvero da quell'utente e che non sia stato modificato. La cifratura garantisce che nessuno possa leggerlo lungo il percorso.
Due meccanismi completano il tutto:
- l'engineID: un identificatore unico per ogni agent. Le chiavi sono derivate dalla password e da questo identificatore. La stessa password dà quindi una chiave diversa su ogni apparato. Una chiave rubata su un router non serve a nulla su quello accanto
- la finestra temporale: ogni messaggio contiene il numero di riavvii dell'agent e il suo orologio. Un messaggio più vecchio di 150 secondi viene rifiutato. Riprodurre un pacchetto catturato non funziona
VACM (View-based Access Control Model, RFC 3415) decide cosa ogni utente ha il diritto di vedere. Si definiscono delle viste, cioè dei rami dell'albero, poi dei gruppi di utenti con i loro diritti su queste viste. Il server di monitoraggio legge tutto, lo strumento di inventario vede solo il ramo system.
Il confronto
| v1 | v2c | v3 | |
|---|---|---|---|
| Anno | dal 1988 al 1990 | 1996 | 2002 |
| Identificazione | community | community | utente |
| Autenticazione | nessuna, la community viaggia in chiaro | nessuna, la community viaggia in chiaro | HMAC MD5, SHA-1, SHA-2 |
| Cifratura | no | no | DES, AES |
| Contatori a 64 bit | no | sì | sì |
| GetBulk | no | sì | sì |
| Inform | no | sì | sì |
| Errori per variabile | no | sì | sì |
| Controllo degli accessi fine | no | no | sì (VACM) |
MD5 e DES sono oggi considerati deboli. Scegli SHA (idealmente SHA-256 se i tuoi apparati lo supportano) e AES.
Interrogare un apparato con Net-SNMP
Net-SNMP fornisce gli strumenti a riga di comando di riferimento. Su Debian o Ubuntu si trovano nel pacchetto snmp.
In v2c
# Un valore preciso: la descrizione del sistema
snmpget -v2c -c LaMiaCommunity 192.168.1.1 SNMPv2-MIB::sysDescr.0
# Lo stesso OID, in forma numerica
snmpget -v2c -c LaMiaCommunity 192.168.1.1 1.3.6.1.2.1.1.1.0
# Un intero ramo: il nome di ogni interfaccia
snmpwalk -v2c -c LaMiaCommunity 192.168.1.1 IF-MIB::ifDescr
# La stessa cosa con GetBulk, 50 valori per scambio
snmpbulkwalk -v2c -c LaMiaCommunity -Cr50 192.168.1.1 IF-MIB::ifTable
In v3
snmpget -v3 -l authPriv \
-u monitoraggio \
-a SHA -A 'PasswordAutenticazione' \
-x AES -X 'PasswordCifratura' \
192.168.1.1 SNMPv2-MIB::sysUpTime.0
-l fissa il livello di sicurezza. -a e -A indicano il protocollo e la password di autenticazione. -x e -X indicano il protocollo e la password di cifratura. Le password v3 devono avere almeno 8 caratteri.
Se nomi come IF-MIB::ifDescr non vengono riconosciuti, mancano i file MIB. Su Debian si trovano nel pacchetto snmp-mibs-downloader. Gli OID numerici funzionano in ogni caso.
Configurare SNMPv3
Nei tre esempi si crea un utente monitoraggio in sola lettura, con autenticazione e cifratura, raggiungibile solo dal server di monitoraggio 192.168.10.5.
Su Linux con Net-SNMP
sudo apt install snmpd libsnmp-dev
# Lo strumento di creazione utenti richiede che il servizio sia fermo
sudo systemctl stop snmpd
sudo net-snmp-create-v3-user -ro \
-a SHA -A 'PasswordAutenticazione' \
-x AES -X 'PasswordCifratura' \
monitoraggio
sudo systemctl start snmpd
-ro dà un accesso in sola lettura. Su Debian e Ubuntu lo strumento si trova nel pacchetto libsnmp-dev.
Per impostazione predefinita, l'agent ascolta solo sulla macchina locale (agentaddress 127.0.0.1,[::1]). Per aprirlo alla rete, sostituisci quella riga in /etc/snmp/snmpd.conf:
# Ascoltare su tutte le interfacce, in UDP
agentaddress udp:161
# Eliminare o commentare le righe rocommunity e rwcommunity:
# nessuna community v1 o v2c deve restare attiva
Poi limita l'accesso alla porta 161 al solo server di monitoraggio con il firewall:
sudo nft add rule inet filter input ip saddr 192.168.10.5 udp dport 161 accept
sudo nft add rule inet filter input udp dport 161 drop
Queste due regole presuppongono una tabella inet filter con una catena input, come nella configurazione predefinita di nftables su Debian. Inserite così, spariscono al riavvio: per mantenerle, aggiungile in /etc/nftables.conf.
Su Cisco IOS
! La vista: ciò che l'utente ha il diritto di leggere
snmp-server view LETTURA iso included
! Solo il server di monitoraggio può interrogare
ip access-list standard SNMP-MONITORAGGIO
permit 192.168.10.5
! Il gruppo v3: autenticazione e cifratura obbligatorie (priv)
snmp-server group MONITORAGGIO v3 priv read LETTURA access SNMP-MONITORAGGIO
! L'utente, collegato al gruppo
snmp-server user monitoraggio MONITORAGGIO v3 auth sha PasswordAutenticazione priv aes 128 PasswordCifratura
Una trappola sorprende tutti la prima volta: gli utenti SNMPv3 non compaiono in show running-config. Le password vengono trasformate in chiavi appena inserite. Per verificare, usa show snmp user.
Su MikroTik RouterOS
/snmp community
add name=monitoraggio addresses=192.168.10.5/32 security=private \
authentication-protocol=SHA1 authentication-password=PasswordAutenticazione \
encryption-protocol=AES encryption-password=PasswordCifratura \
read-access=yes write-access=no
/snmp set enabled=yes
In RouterOS, il nome della community fa da nome utente v3. security=private corrisponde al livello authPriv. Ricorda anche di limitare o disattivare la community public creata per impostazione predefinita.
Sicurezza: le trappole classiche
Le community predefinite. public e private sono le prime parole che prova uno scanner. Un apparato che risponde a public rivela la sua configurazione di rete, le sue interfacce e a volte le tabelle ARP e di routing.
L'accesso in scrittura. Con una community in scrittura si può modificare la configurazione, spegnere un'interfaccia o, su alcuni apparati, scaricare la configurazione completa. Il monitoraggio non ne ha bisogno. Sola lettura ovunque.
L'esposizione su Internet. La porta UDP 161 non deve mai essere aperta su Internet. Oltre alla fuga di informazioni, SNMP viene usato negli attacchi di amplificazione. L'attaccante invia una piccola richiesta GetBulk falsificando l'indirizzo della vittima, e l'agent risponde alla vittima con una risposta molto più grande. Migliaia di agent configurati male diventano così cannoni di traffico.
La v2c su una rete condivisa. Se la v2c è inevitabile (apparato vecchio, strumento limitato), isola il traffico SNMP in una VLAN di gestione e filtra per indirizzo di origine.
Gli algoritmi deboli. MD5 e DES non dovrebbero più essere usati. SHA e AES sono supportati da tutti gli apparati recenti.
Le trap v3. Per una trap v3, le chiavi vengono derivate dall'engineID di chi la invia. Chi la riceve deve quindi conoscere l'engineID di ogni apparato che gli invia trap. Gli inform non hanno questo problema, perché si usa l'engineID di chi riceve. Un motivo in più per preferire gli inform.
Gli strumenti basati su SNMP
- Zabbix: monitoraggio completo, con template pronti per la maggior parte dei produttori
- LibreNMS: scoperta automatica della rete e grafici senza configurazione
- Centreon: soluzione francese, molto diffusa nelle aziende e negli enti pubblici in Francia
- Prometheus con snmp_exporter: per integrare gli apparati di rete in un monitoraggio già basato su Prometheus e Grafana
- GLPI: l'inventario di rete dell'agent GLPI scopre gli apparati e le loro porte tramite SNMP
SNMP ha ancora senso?
Le grandi reti passano gradualmente alla telemetria in streaming (gNMI). Non è più il manager a interrogare: l'apparato invia i suoi dati in continuo, ogni pochi secondi. Per la configurazione, NETCONF e RESTCONF hanno sostituito da tempo le SetRequest.
Eppure SNMP resta l'unica lingua parlata allo stesso tempo da uno switch di dieci anni, da un UPS, da una stampante e da un router nuovo. Per monitorare un parco eterogeneo, non ha un vero concorrente.
La buona pratica sta in tre punti: SNMPv3 in authPriv, sola lettura, e un accesso limitato al solo server di monitoraggio.
Per approfondire
- RFC 3411 (in inglese), l'architettura di SNMPv3
- RFC 3414 (in inglese), il modello di sicurezza USM
- RFC 3415 (in inglese), il controllo degli accessi VACM
- RFC 7860 (in inglese), l'aggiunta di SHA-2
- Net-SNMP (in inglese), gli strumenti e la loro documentazione
- La documentazione di LibreNMS (in inglese), per mettere in piedi un monitoraggio completo in un pomeriggio
Un esercizio per finire. Lancia snmpwalk -v2c -c public su un apparato della tua rete, con l'accordo del responsabile. Se risponde, hai appena trovato il tuo primo cantiere di sicurezza.
Commenti (0)
Lascia un commento
Puoi commentare indicando il tuo nome e la tua email. Il messaggio sarà pubblicato dopo la moderazione. Con un account appare subito e resta modificabile.
Ancora nessun commento
Sii il primo a commentare questo articolo!