Illustrazione dell'articolo SNMP: capire il protocollo e scegliere tra v1, v2c e v3

SNMP: capire il protocollo e scegliere tra v1, v2c e v3

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

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

Non hai effettuato l'accesso

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.

La tua email non sarà pubblicata.

Ancora nessun commento

Sii il primo a commentare questo articolo!