🔐SNMPv3-Sicherheit

SNMPv3 ersetzt die Community durch Benutzer mit Schlüsseln (USM) und regelt mit Views, wer was sehen darf (VACM). Hier wird beides nachgerechnet – mit den Testvektoren aus dem RFC.

🎚️Sicherheitsstufen

Stufe (-l)msgFlagsAuthentisierungVerschlüsselungNet-SNMP
noAuthNoPriv0x00 (+ 0x04 reportable)––rouser … noauth
authNoPriv0x01HMAC über die ganze Nachricht–rouser … auth
authPriv0x03HMACScoped PDU verschlüsseltrouser … priv

Ein gesetztes Priv-Bit ohne Auth-Bit ist ungültig – Verschlüsselung gibt es nur zusammen mit Authentisierung. Das Reportable-Bit (0x04) erlaubt dem Empfänger, mit einer Report-PDU zu antworten.

📎 Quellen: RFC 3414 – User-based Security Model · RFC 3412 – Message Processing (SNMPv3-Nachricht) · snmpd.conf(5)

🧾Aufbau einer SNMPv3-Nachricht

SEQUENCE
├─ msgVersion            3
├─ msgGlobalData  SEQUENCE
│  ├─ msgID              zufällig, ordnet Antworten zu
│  ├─ msgMaxSize         ≥ 484
│  ├─ msgFlags           1 Oktett: reportable|priv|auth
│  └─ msgSecurityModel   3 = USM
├─ msgSecurityParameters OCTET STRING mit SEQUENCE:
│  ├─ msgAuthoritativeEngineID      engineID des Agenten
│  ├─ msgAuthoritativeEngineBoots
│  ├─ msgAuthoritativeEngineTime
│  ├─ msgUserName                   „monitor“
│  ├─ msgAuthenticationParameters   gekürzter HMAC
│  └─ msgPrivacyParameters          Salt (8 Oktette)
└─ msgData
   ├─ plaintext ScopedPDU   {contextEngineID, contextName, PDU}
   └─ encryptedPDU          (bei authPriv)

📎 Quellen: RFC 3412 – Message Processing (SNMPv3-Nachricht) · RFC 3414 – User-based Security Model

🧮Auth- und Priv-Protokolle

-aProtokoll (MIB)Schlüssel Kulübertragener MACNormBewertung
MD5usmHMACMD5AuthProtocol16 Oktette12 OktetteRFC 3414veraltet
SHAusmHMACSHAAuthProtocol20 Oktette12 OktetteRFC 3414veraltet
SHA-224usmHMAC128SHA224AuthProtocol28 Oktette16 OktetteRFC 7860ok
SHA-256usmHMAC192SHA256AuthProtocol32 Oktette24 OktetteRFC 7860empfohlen
SHA-384usmHMAC256SHA384AuthProtocol48 Oktette32 OktetteRFC 7860ok
SHA-512usmHMAC384SHA512AuthProtocol64 Oktette48 OktetteRFC 7860ok
-x DESusmDESPrivProtocol56-Bit-DES im CBC-ModusRFC 3414veraltet
-x AESusmAesCfb128ProtocolAES-128 im CFB-ModusRFC 3826empfohlen
Beide Seiten müssen dasselbe können
SHA-2 und AES setzen bei Net-SNMP eine Übersetzung mit OpenSSL voraus (snmpd.conf(5)). Ältere Geräte kennen oft nur MD5/SHA und DES/AES-128 – passt die Kombination nicht, meldet der Agent usmStatsWrongDigests oder usmStatsDecryptionErrors, der Manager meist nur „Authentication failure“ oder einen Timeout. AES-192/256 sind nicht in RFC 3826 genormt; einige Implementierungen bieten sie als Erweiterung an – dann Interoperabilität testen.

📎 Quellen: RFC 3414 – User-based Security Model · RFC 7860 – HMAC-SHA-2 für USM · RFC 3826 – AES-CFB-128 für USM · snmpcmd(1)

🗝️Password-to-Key und Lokalisierung – live gerechnet

Auth-Protokoll
Schritt 1 · Passwort zyklisch auf 1 048 576 Oktette verlängern
maplesyrupmaplesyrupmaplesyrupmaplesyrupmaplesyr… (insgesamt 1 048 576 Zeichen)
Schritt 3 · Ku ‖ engineID ‖ Ku
… 00 00 00 00 00 00 00 00 00 00 00 02 …
Warum lokalisieren? Ein ausgespähter Kul gilt nur für genau diese engineID. Derselbe Benutzer mit demselben Passwort hat auf jedem Agenten einen anderen Schlüssel (RFC 3414, 2.6) – der Manager rechnet ihn nach der Discovery für jeden Agenten aus. Das Hashen von 1 MiB macht jeden Rateversuch aufwendiger, ein leicht zu erratendes Passwort bleibt trotzdem unsicher (RFC 3414, 11.2).

📎 Quellen: RFC 3414 – User-based Security Model · RFC 7860 – HMAC-SHA-2 für USM · RFC 3826 – AES-CFB-128 für USM

🆔engineID, Discovery und Zeitfenster

engineID zerlegen (RFC 3411)
Erstes Bit
1 → Format nach RFC 3411
Enterprise-Nummer (Oktette 1–4)
8072 – Net-SNMP
Format (Oktett 5)
128 – herstellerspezifisch
Daten · Länge
5a 3c 91 7e 21 4b 0d 66 00 00 00 00 · 17 Oktette
Zeitfenster prüfen (Agent: boots 7, time 85634)
✅ Boots stimmen, Zeitabstand 40 s ≤ 150 s – Nachricht ist „rechtzeitig“

Nach einem Neustart erhöht der Agent snmpEngineBoots. Alte, mitgeschnittene Nachrichten werden dadurch ungültig (Schutz gegen Wiedereinspielen). Der Manager synchronisiert sich über einen Report automatisch neu.

Discovery Schritt für Schritt (RFC 3414, 4)
  1. M→A1 · Anfrage ohne engineID (noAuthNoPriv)

    Der Manager kennt die engineID des Agenten noch nicht. Er schickt eine Anfrage mit leerer msgAuthoritativeEngineID, leerem Benutzernamen und leerer Varbind-Liste; reportable ist gesetzt.

    msgFlags 04 · engineID '' · user '' · Varbinds: keine
  2. A→M2 · Report: usmStatsUnknownEngineIDs.0
  3. M3 · Schlüssel lokalisieren
  4. M→A4 · Authentisierte Anfrage mit Boots = 0, Time = 0
  5. A→M5 · Report: usmStatsNotInTimeWindows.0
  6. M→A6 · Eigentliche Anfrage (authPriv)
  7. A→M7 · Response
Klassiker: geklonte VMs mit gleicher engineID
Die engineID muss je Agent eindeutig sein – sonst passen lokalisierte Schlüssel und Zeitfenster nicht zusammen. Wer ein Server-Image mit fertiger Net-SNMP-Konfiguration klont, übernimmt die gespeicherte engineID aus dem persistenten Verzeichnis (net-snmp-config --persistent-directory) und sollte sie vor dem ersten Start neu erzeugen lassen.

📎 Quellen: RFC 3411 – SNMP-Architektur · RFC 3414 – User-based Security Model

🛂VACM-Auswerter: darf dieser Benutzer das?

Objekt
  1. ✔ 1 · Kontext
    Kontext „“ (Standardkontext) existiert
  2. ✔ 2 · Gruppe
    usm/„monitor“ gehört zur Gruppe „grpMonitoring“
  3. ✔ 3 · Zugriffseintrag
    Gruppe „grpMonitoring“, Modell usm, Mindeststufe authPriv → read „monitoring“, write „–“, notify „–“
  4. ✔ 4 · View wählen
    read-View „monitoring“
  5. ✔ 5 · OID prüfen
    .1.3.6.1.2.1.2.2.1.10.2 liegt unter .1.3.6.1.2.1 → included
✅ accessAllowed
Der Wert wird geliefert (bzw. geschrieben).
.1.3.6.1.2.1.2.2.1.10.2

Die Abbildung der VACM-Ergebnisse auf SNMP-Antworten folgt RFC 3413 (Command Responder): Objekte außerhalb der View gelten für diese Anfrage als nicht vorhanden.

📋 Konfiguration dieses Beispiels (VACM-Tabellen und Net-SNMP-Schreibweise)
GruppeModellStufe ≥readwritenotify
grpNurSystemanynoAuthNoPrivsystemonly––
grpMonitoringusmauthNoPrivsystemonly––
grpMonitoringusmauthPrivmonitoring––
grpAdminusmauthPrivallesschreibenalles
ViewTeilbaumMaskeTyp
systemonly.1.3.6.1.2.1.1–included
systemonly.1.3.6.1.2.1.25.1–included
monitoring.1.3.6.1.2.1–included
monitoring.1.3.6.1.4.1.2021–included
monitoring.1.3.6.1.2.1.2.2.1.6–excluded
alles.1–included
schreiben.1.3.6.1.2.1.1–included
schreiben.1.3.6.1.2.1.2.2.1.0.2ff:a0included
# snmpd.conf – gleiche Regeln mit den VACM-Direktiven
com2sec   pubnet   198.51.100.0/24  public
group     grpNurSystem   v2c   pubnet
group     grpMonitoring  usm   monitor
group     grpAdmin       usm   admin

view  systemonly  included  .1.3.6.1.2.1.1
view  systemonly  included  .1.3.6.1.2.1.25.1
view  monitoring  included  .1.3.6.1.2.1
view  monitoring  included  .1.3.6.1.4.1.2021
view  monitoring  excluded  .1.3.6.1.2.1.2.2.1.6
view  alles       included  .1
view  schreiben   included  .1.3.6.1.2.1.1
view  schreiben   included  .1.3.6.1.2.1.2.2.1.0.2  ff:a0

#       Gruppe         Kontext Modell Stufe  Präfix  read        write     notify
access  grpNurSystem   ""      any    noauth exact   systemonly  none      none
access  grpMonitoring  ""      usm    auth   exact   systemonly  none      none
access  grpMonitoring  ""      usm    priv   exact   monitoring  none      none
access  grpAdmin       ""      usm    priv   exact   alles       schreiben alles

In Net-SNMP bildet com2sec eine Community (plus Quellnetz) auf einen securityName ab; im Auswerter oben wird der Einfachheit halber die Community selbst als securityName verwendet. Die Maske ff:a0 gibt alle Spalten der ifTable-Zeile 2 frei (Beispiel aus snmpd.conf(5)).

📎 Quellen: RFC 3415 – View-based Access Control · RFC 3413 – SNMP-Anwendungen · snmpd.conf(5)