### Teknikal's_Domain

#<ENT:NTA:NnT:SSrgS:H66-198:W300:CBWg>

# Ah Yes, the SIMPLE Network Management Protocol

If that title isn’t a dead giveaway, I’m not happy. But yet I will somehow manage to vent my frustrations and explain something at the same time. Today: SNMP, or, “How to gather lots of stats on remote machines,” or, “Because you thought CVS was hard to wrap your head around”

On that last point, remember where I talked about CVS revision numbers ? Remember that for later.

Now, officially, SNMP is, per Wikipedia, “an Internet Standard protocol for collecting and organizing information about managed devices on IP networks and for modifying that information to change device behavior. Devices that typically support SNMP include cable modems, routers, switches, servers, workstations, printers, and more.”

Laymans terms: SNMP allows you to manage, but actually more commonly, monitor devices on a network by requesting specific attributes from them, for example “How many bytes have been sent on interface eth0?” Some attributes can be written to, for example, the ability to write to one to administratively disable a certain network interface, but I pretty much set everything I have to read-only since I don’t need remote modification, so we’ll focus on the monitoring point.

Many monitoring systems (like the one I use, Zabbix) support checking devices via SNMP for some statistics.

# SNMP Architecture

SNMP operates on what I will deem a client-server architecture. The client can send GetRequest commands to the server, and it will respond with a particular value (there’s other commands, that’s besides the point.) In this manner, SNMP is a request-only system, nothing is actually pushed out from the SNMP-enabled device (meaning a device running an SNMP agent, such as snmpd). However there is a provision for that, called SNMP traps.

And do note: SNMP used UDP as its transport, not TCP.

## Traps

SNMP traps can be sent from the client (agent) to the server (manager) as an unsolicited notification, for example, alerts if a power supply has failed, or disk S.M.A.R.T. variables indicate a potential failure, whatever. A common trap type is SNMP authentication failure, but… we’ll get to that in a second. And by a second, I mean right now.

## Versions

SNMP has three major versions, SNMPv1, SNMPv2c, and SNMPv3.

Version 1 is… really nothing special, it’s basic, it’s insecure, and there’s little to speak about.

### SNMPv2c

Version 2 (not 2c) added some performance improvements, and the GetBulkRequest for accessing large numbers of attributes in a single request. Version 2 also changed the “counter” type attributes from being 32 bits wide to 64 bits wide. Version 2 also added an “overly complex” security model that wasn’t ever really adopted.

Out of this, 2c was born, the c for “community.” SNMPv1 and SNMPv2c both base their entire security model on what are called community strings. How these work is that a particular device accepts requests from a certain community (the default one is public), and may even accept multiple communities, some being read only, some read-write, but this is at the discresion of the SNMP agent being used.

The community string is transmitted in the packet in plain text, which is compared with the community list on the agent, and a valid community gets a response, an invalid community gets a failure.

Here’s the problem: that’s effectively the password. That’s likely going to be repeated on every SNMP device, and is transmitted clear. Anyone who gets into your network will have no trouble figuring it out.

Note: user-based auth 2u was also a thing that acted as a compromise between 2 and 2c, but it was never really used until v3.

### SNMPv3

Think of this one as a major security update. Each device, client or server, is an SNMP entity. Every entity has an SNMPEngineID, and (with the exception of traps), an entity will not communicate with another entity presenting an unknown SNMPEngineID. SNMPv3 uses a user-based authentication model, and protects against message modification in-flight, entity spoofing, and a few other things like eavesdropping on SNMP traffic. To accomplish this, there are three security levels that SNMPv3 can operate at: NoAuthNoPriv, AuthNoPriv, and AuthPriv. Looking at these tells you the two main services at work here: authentication and privacy. To this end, each of those requires a passkey. Authentication passes are a pre-shared hash between two devices, and privacy passes are symmetric encryption ciphers with a pre-shared initialization. For example, my system uses SHA for authentication and AES for privacy. When sending an AuthPriv level request, both the hash value and cipher value have to match what’s on the other device or it won’t accept it. The actual data that you, the human in the loop, need to give it are a text phrase (the actual pass), and the algorithm in use. This means that the rest is just protocol work, and text passwords can still be brute-forced through generating, hashing/encrypting, and then sending them to a target device, assuming it hasn’t whitelisted known IPs and is allowing all addresses to send requests. Additionally, like stated before, the SNMPEngineID, but those are capable of being auto-discovered… once. If it changes after it’s found the first time, then the device will reject it.

# SNMP Structure

So the rest is really cool, and this is where things suddenly go from smooth sailing to please pass me the bottle of Jack Daniel’s. SNMP uses a hierarchical namespace for its attributes, think of it as a giant tree structure. This is represented textually through an Object Identifier or OID. OIDs are standardized methods of naming any, well, thing with an unambiguous name. OIDs are represented as a dotted-decimal structure, where each number is another level on the OID tree, and the actual number is what branch you pick.

For example, Intel has an OID that everything for them is under, which is IANA enterprise number 343. Their OID is 1.3.6.1.4.1.343. Do… do you see the resemblance (and headache) to CVS yet? If we were to give those names it would look like iso.identified-organization.dod.internet.private.enterprise.intel. Fun fact: the dod there is indeed Department of Defense, a very old hold-over from the early days of the internet which was pretty much developed by the DoD, for the DoD. And yes, the DoD does technically have authority over anything under 1.3.6, in the same sense that IANA has control over 1.3.6.1.4.1, in the same sense that Intel has free reign over their own subtree, 1.3.6.1.4.1.343, to do what they please. Note that OIDs are used in a lot of places, LDAP (part of the internal server schema), X.509 certificates (TLS), and a few others use them since they do have an obvious appeal of uniquely and permanantly naming some entity or “thing”.

With THAT explanation over, if you’re not seeing my main headache with SNMP, just wait, it gets better. SNMP attributes are exported as OIDs. For example, the system hostname is available at 1.3.6.1.2.1.1.5.0, the MAC address of network interface 2 is at 1.3.6.1.2.1.2.2.1.6.2, and the number of bytes received by interface 1 is at .3.6.1.2.1.2.2.1.10.1.

Naturally we decided that this is all too complicated and started assigning names. The hostname is at RFC1213-MIB::sysName.0, NIC 2 MAC is RFC1213-MIB::ifPhysAddress.2, and NIC 1 received bytes is RFC1213-MIB::ifInOctets.1.

Where do we map these names to numbers? MIBs.

# MIBs

A Management Information Base, or MIB, is a text file formatted in Structure of Management Information Version 2 (SMIv2), which looks very much like Brackus-Narr syntax.

Protocol-wise, everything in SNMP is raw OIDs. Anything that interfaces with a human uses its MIBs to translate textual names into OIDs.

If a hardware vendor (say, like, Netgear) wanted to add their own custom statistics into SNMP, the best thing to do is to construct and allow downloading of a MIB that defines all their attributes.

Speaking of, here’s one:

    READYNASOS-MIB DEFINITIONS ::= BEGIN

IMPORTS
OBJECT-TYPE
FROM RFC-1212
TRAP-TYPE
FROM RFC-1215
enterprises
FROM RFC1155-SMI
DisplayString
FROM RFC1213-MIB;

netgear     OBJECT IDENTIFIER ::= { enterprises 4526 }
productID       OBJECT IDENTIFIER ::= { netgear 100 }

ReadyNASOS  OBJECT IDENTIFIER ::= { productID 16 }

ngNasManager    OBJECT IDENTIFIER ::= { netgear 22 }

nasMgrSoftwareVersion OBJECT-TYPE
SYNTAX DisplayString (SIZE (1..32))
STATUS current
DESCRIPTION
ngNasManager software."
::= { ngNasManager 1 }

nasMgrSerialNUM OBJECT-TYPE
SYNTAX DisplayString (SIZE (1..32))
STATUS current
DESCRIPTION
::= { ngNasManager 2 }



And this file tells you, for example, that READYNASOS-MIB::netgear.ngNasManager.nasMgrSoftwareVersion is 1.3.6.1.4.1.4526.22.1, and it is the “Version information for the ReadyNASOS ngNasManager software.

And thus, when I snmpget READYNASOS-MIB::netgear.ngNasManager.nasMgrSoftwareVersion, it will send an SNMP GetRequest for 1.3.6.1.4.1.4526.22.1

Which leads me to one question : Why???

No, seriously. For the “simple” protocol, we’ve taken three distinct versions to get actual good security, security that requires you know two passwords and two algorithms, the actual representation of everything is just an explosion of numbers the likes of which only IPv6 and CVS have matched, and since like IPs, we decided that remembering numbers is dumb, so we invented DNS MIBs written in this weird human-readable and machine-parsable Brackus-Narr markup that defines everything. And which every vendor likely has their own if not for every software product they have, NICE.

I wasn’t even setting up proper SNMP when I got this ranty, I tried doing that a while back, and setting up SNMPv3 gets tiring quick. I was just trying to get it to run on that NAS that kinda died until I made it live again , which… really just set me off. Like just hear me out, if you’re going to present a MIB for all your details, SNMP traps, and the like, well, maybe have the device that presents it actually use them. The model I have pretty much only exports stuff from RFC1213-MIB and that’s it. Not to mention it only supports SNMPv2c.

See and the protocol itself in implementation is simple, I give it that. But in terms of usage and configuring, it’s anything but. For example, for Zabbix to recognize my human-readable names, it needs the MIB. These are kept in /usr/share/snmp/mibs. Except it keeps saying not found… and I know this is an issue with a software library not SNMP but WHY does the most popular implementation, Net-SNMP, have a critical bug in 5.7.x where the MIB compiler (official term) will read MIBs and then spit out a Module not found error for every file that it just read? And why does no package repository actually contain 5.8 where this is fixed? I know this is linux world but I would assume the Debian package repositories which are usually on top of things would have either a backport fix, or upgrade to a version without a crippling bug in it.

I spent an hour and a half dealing with all this, dealing with MIBs, dealing with a stupidly slow NAS CPU, dealing with Net-SNMP’s crap to be told “oh by the way, the thing you just tried putting together isn’t even supported in the slightest.”

Simple. Yes. Totally. Simple.