Skip to content

SNMP & Protocols

SNMP v1, v2c and v3: what changed and which one to run

Every network I have inherited spoke at least two versions of SNMP, and usually all three. The printers answered v1, the core switches answered v2c with a community string nobody remembered choosing, and one firewall had been set up for v3 by someone who had since moved on. The versions coexist without complaint, which is exactly why they linger. Below are the questions I get asked most about the differences, answered in the order you will hit them when you plan a cleanup.

Which versions exist, and what did each one change?

Three are in real use. There was also a party-based SNMPv2 in the early 1990s whose security model nobody could agree on. What survived from it is SNMPv2c: the new protocol operations with the old community strings bolted back on (the "c" stands for community). It was only ever published as an experimental RFC, and every vendor shipped it anyway.

SNMPv1 SNMPv2c SNMPv3
Defining documents RFC 1157 (1990) RFC 1901 plus the SMIv2 and protocol operation RFCs RFC 3411 to 3418 (2002)
Who are you? Community string, cleartext Community string, cleartext Named user (USM), HMAC on every message
Encryption None None Optional: DES, or AES-128 per RFC 3826
Access control Per community: read-only or read-write Same VACM: groups, views and a minimum security level
Bulk retrieval GetNext only GetBulk GetBulk
64-bit counters No Counter64 Counter64
Notifications v1 Trap format SNMPv2-Trap and Inform SNMPv2-Trap and Inform, authenticated
Error detail Coarse (noSuchName) Exceptions such as noSuchObject and endOfMibView As v2c

The protocol operations in v3 are the same ones v2c uses. Version 3 changed the message wrapper and the security around it, not the questions you can ask an agent. That is good news for migration: your MIBs, OIDs and graphs do not change.

What exactly is wrong with a community string?

Three things, in rising order of how much they should worry you.

It travels in cleartext in every request. Anyone who can capture traffic between the poller and the agent can read it in the first few bytes of the packet, no cracking needed.

It proves nothing about the sender. SNMP runs over UDP 161, and UDP source addresses are easy to forge. An agent that accepts a community from anywhere will answer anyone who knows or guesses it, and public is the first guess every scanner makes.

It is shared. The poller, three scripts, a contractor's laptop and the old backup tool all use the same string, so you cannot revoke one of them without touching all of them.

Read-only access already leaks plenty: sysDescr gives away the exact software version, and the ARP, routing and interface tables draw a map of your network. A read-write community is worse. A single SET on ifAdminStatus (1.3.6.1.2.1.2.2.1.7) shuts a port, and that is one of the polite things a stranger can do with it.

What does USM give you instead?

The User-based Security Model in RFC 3414 replaces the shared string with named users. Each user can have two secrets, one for authentication and one for privacy (encryption), and every request runs at one of three security levels:

  • noAuthNoPriv: a username and nothing else. No better than a community string.
  • authNoPriv: every message carries an HMAC, so the agent knows who sent it and that nobody changed it in transit. The payload is still readable on the wire.
  • authPriv: authenticated and encrypted. This is the level to run.

A few details make USM sturdier than it first looks. Passphrases are turned into keys by hashing about a megabyte of the repeated passphrase, and that key is then localized with the agent's engine ID, so the stored key from one switch is useless on the next. Each agent keeps a boot counter and an engine time, and a message that falls outside a 150-second window is rejected, which kills simple replays. The manager learns the agent's clock during discovery, so you do not need NTP for this to work (you want NTP anyway, for your logs).

The original algorithms were HMAC-MD5 and HMAC-SHA-1 for authentication and 56-bit DES for privacy. RFC 3826 added AES-128, and later work added SHA-2 variants. AES-192 and AES-256 exist on some platforms as vendor extensions, and they do not always interoperate. On mixed fleets, SHA with AES-128 is still the setting that works everywhere.

Access control moves to VACM: you put users in groups, give groups views of the OID tree, and set the minimum security level each group must use. A group that requires priv will refuse the same user's authNoPriv requests.

Why does v2c poll faster than v1?

GetBulk. With GetNext, every row of a table costs one round trip. Walking ifHCInOctets on a switch with 52 interfaces takes 53 requests (the last one steps off the end of the column). With GetBulk and max-repetitions set to 25, the same column takes 3. Across a WAN link with 20 ms of round-trip time, that is about 1.06 seconds against 60 ms, for one column on one device. Multiply by the columns you collect and the devices behind that link. The net-snmp tools default to 10 repetitions per request, and -Cr raises it for a single walk:

snmpbulkwalk -v2c -c n0c-r34d -Cr25 10.20.0.2 IF-MIB::ifHCInOctets

Do not go wild with the number. Large responses get fragmented over UDP, fragments are the first thing a firewall or a lossy link drops, and some small agents slow to a crawl building a huge reply. Somewhere between 10 and 30 suits most switches.

Why do 64-bit counters need v2c or v3?

Counter64 is an SMIv2 type and there is no way to encode it in a v1 message. An agent answering a v1 GetNext skips over Counter64 objects, so a v1 walk of ifXTable quietly returns everything except the high-capacity counters you came for.

That matters because a 32-bit octet counter wraps at 4,294,967,296 bytes. At 1 Gbit/s line rate that takes 34.4 seconds; at 10 Gbit/s, 3.4 seconds. No sensible polling interval keeps up with that, while ifHCInOctets (1.3.6.1.2.1.31.1.1.1.6) will not wrap for centuries at those speeds. The counter rate calculator shows the wrap time for any link speed if you want to check your own ports.

How do I create a v3 user on net-snmp?

On a Linux host running net-snmp's snmpd, the helper script does the work. It ships with net-snmp, though some distributions put it in the development package. Stop the daemon first, because the script edits a file that snmpd rewrites on exit.

sudo systemctl stop snmpd
sudo net-snmp-create-v3-user -ro -a SHA -A 'long-auth-passphrase' -x AES -X 'different-priv-passphrase' monitor
sudo systemctl start snmpd

The script prints the two lines it added and where. If you would rather do it by hand, stop snmpd and put the first line in the persistent snmpd.conf under /var/lib (the exact directory varies by distribution):

createUser monitor SHA "long-auth-passphrase" AES "different-priv-passphrase"

The second line goes in the main config, /etc/snmp/snmpd.conf, and grants the user read-only access at the authPriv level:

rouser monitor priv

On start, snmpd reads the createUser line, stores localized keys in its place and deletes the line, so the passphrases do not sit on disk. That is why it belongs in the persistent file and not in the main config, where it would stay in cleartext forever. Passphrases must be at least eight characters, and the auth and privacy ones should differ. Test from the poller:

snmpget -v3 -l authPriv -u monitor -a SHA -A 'long-auth-passphrase' \
  -x AES -X 'different-priv-passphrase' 10.20.0.5 1.3.6.1.2.1.1.3.0

A timeticks value for sysUpTime means it works. Passphrases on the command line end up in shell history and in ps output, so for daily use put them in ~/.snmp/snmp.conf with mode 600:

defVersion        3
defSecurityName   monitor
defSecurityLevel  authPriv
defAuthType       SHA
defAuthPassphrase long-auth-passphrase
defPrivType       AES
defPrivPassphrase different-priv-passphrase

How do I migrate a whole network without losing graphs?

The agent's counters do not care which version you ask with, so graphs carry straight across. The work is in doing it device by device without a gap.

  1. Inventory what each model supports. Note the auth and privacy algorithms, and find the devices that cannot do v3 at all.

  2. Pick one read-only user name and a passphrase pair per security zone, and store them in your password vault, not in a wiki page.

  3. Add v3 next to the existing v2c on each device. Both answer at the same time. On Cisco IOS the shape is:

    access-list 99 permit 10.99.0.5
    snmp-server view MONVIEW iso included
    snmp-server group MONGROUP v3 priv read MONVIEW access 99
    snmp-server user monitor MONGROUP v3 auth sha AUTH-PASSPHRASE priv aes 128 PRIV-PASSPHRASE
    

    The user line does not appear in the running config. Check it with show snmp user.

  4. Check engine IDs. Cloned VMs and devices restored from one image can share an engine ID, which confuses managers that cache them. snmpEngineID.0 (1.3.6.1.6.3.10.2.1.1.0) should be unique per agent.

  5. Switch the poller to v3 one site at a time (the polling guide covers the poller side) and look at the graphs after two cycles. A flat line means a credential or ACL problem, not lost data.

  6. Move traps. For v3 traps the sending agent is authoritative, so the trap receiver needs each sender's engine ID in its user entry. Informs avoid that because the receiver is authoritative. The trap guide covers the receiver side.

  7. Remove the read-write community first, then the read-only one, and keep the ACL.

During the switch, the counters usmStatsUnknownUserNames, usmStatsWrongDigests and usmStatsNotInTimeWindows on the agent tell you which of the three usual mistakes you made.

When is v2c still acceptable?

When all of these hold:

  • SNMP traffic stays on a management VLAN or out-of-band network that users, guests and servers cannot reach.
  • The agent itself has an ACL that only admits your poller addresses.
  • The community is read-only, long and random. Not public, not the company name.
  • No read-write community exists anywhere on the device.
  • UDP 161 and 162 are blocked at every edge.

In that setup, the cleartext string is only visible to people who are already inside your management network, and you have bigger problems if they are hostile. It is also the honest answer for the devices that cannot do v3: older UPS network cards, printers, some PDUs and budget smart switches. On net-snmp, the ACL is part of the directive:

rocommunity n0c-r34d 10.99.0.5

What v2c is never fine for is anything crossing a network you do not control, including the internet and a shared hosting VLAN.

Is there any reason left to run v1?

Only for a device that speaks nothing else. Without Counter64, any port faster than 100 Mbit/s gives you numbers you cannot trust: even at 100 Mbit/s a 32-bit octet counter wraps in about 5.7 minutes at line rate, close enough to a 5-minute poll to bite. Poll it from one host, give it the same ACL treatment as v2c, and put its replacement in next year's budget.

Where should I start on Monday?

  1. Search every config for read-write communities and delete them. Nothing in a read-only monitoring setup needs one.
  2. Put an ACL on every agent that still answers v2c.
  3. Create one v3 authPriv user and test it on a single device end to end, traps included.
  4. Roll it out by site, then retire the communities.

More on the protocol side lives under SNMP and protocols.