SNMPv3 Setup: Security Levels, Engine ID, Verify - 夜莺博客

SNMPv3 Setup: Security Levels, Engine ID, Verify

SNMPv2c is still everywhere because SNMPv3 looks hard: groups, users, views, engine IDs and three security levels, all of which must line up or the poll simply fails with a vague error. In practice, a working SNMPv3 deployment on Cisco IOS and IOS XE comes down to one dependency chain and one habit. This article covers the three security levels, the exact configuration order, the verification commands, and how to read the error messages that SNMPv3 produces when authentication fails.

How SNMPv3 Authentication Actually Works

Every SNMPv3 failure is easier to diagnose once you know what the protocol does on the wire. Three things separate v3 from v2c, and each one is a place where a deployment can break.

The engine ID. Every SNMP engine — every router, switch, firewall and the NMS itself — has an administratively unique engine ID. It is the identity the engine uses in the security model, and it is the secret salt that turns a shared password into a key. An engine ID is not a password and not a username: it is closer to a host key. Two devices with the same engine ID confuse the NMS, and a device whose engine ID changed after a management-plane restore will reject every credential the NMS still holds.

Localised keys. SNMPv3 never sends your password. The password is a passphrase used to derive a key, and the derivation is salted with the engine ID. That is why a credential is valid only against the engine it was derived for. Change the engine ID and the derived key changes with it, so the old password will not authenticate even though you typed it correctly. This single detail explains the overwhelming majority of "the password is definitely right" support calls.

The time window. The authoritative engine (normally the device being polled) maintains an engine boot counter and an engine time counter. Requests that fall outside a sliding window — roughly 150 seconds, plus liveness acknowledgement — are discarded as outside the time window. A device whose clock jumped, that reloaded, or that has been running long enough to roll its boot counter will demand a re-synchronisation. The NMS handles that automatically by default, but a firewall dropping UDP, a stale cached engine ID, or an NMS configured with a fixed engine ID rather than discovery all defeat the mechanism.

The Three Security Levels

Level Authentication Encryption Use
noAuthNoPriv Username only None Avoid - no better than a community string
authNoPriv HMAC-MD5 or HMAC-SHA None Rarely justified
authPriv HMAC-MD5 or HMAC-SHA DES-56 or AES-128 The default choice

Modern code offers SHA-2 and AES-256 families; use the strongest algorithms both the device image and the monitoring tool support, and never leave community strings enabled alongside SNMPv3 unless a legacy tool forces you to.

The Engine ID Explained

On Cisco IOS and IOS XE, show snmp engineID displays the value the device uses. The structure matters because it encodes how the ID was generated and by whom:

Switch# show snmp engineID
Local SNMP engineID: 80000009030000E04C123456
Remote Engine ID    IP-addr / port  User
IPv4-12   80000009...   10.20.30.40/162  nmsuser

The standard format is a vendor prefix, a format byte, and a device-specific suffix. 80 00 00 09 identifies the enterprise as Cisco (1.3.6.1.4.1.9 packed into the enterprise-number encoding), the next byte describes the format, and the trailing bytes identify the chassis — typically a MAC address or a serial number. Because engineering rules forbid two engines sharing an ID, the suffix is what makes your router's engine unique. In the example above 00E04C123456 is a MAC address with its first octet's multicast bit set, which is the usual convention.

You can override the ID, and there are legitimate reasons to do so — a lab with cloned VMs that inherit the same ID, or a replacement chassis you want to keep managed by the same NMS without re-deriving keys:

snmp-server engineID local 00000009020000E0C0FFEE01
! verify
show snmp engineID

Two cautions. Changing the local engine ID invalidates every user's localised keys, so recreate the users and update the NMS in the same change window. And on a stack or virtual-switching system, each member may present its own engine ID — a poller that resolves a different member's address than the one you configured against will report an authentication failure against a working credential. Confirm which engine answered with show snmp engineID on the specific member, and check show snmp user for the remote engine entries the switch maintains for trap destinations.

Configuration Order Matters

snmp-server group MONITOR v3 priv read MONITORVIEW
snmp-server view MONITORVIEW 1.3.6.1.2.1 included
snmp-server view MONITORVIEW 1.3.6.1.4.1 included

! users must reference the group that already exists
snmp-server user netmon MONITOR v3 auth sha STRONG_AUTH_PASS priv aes 256 STRONG_PRIV_PASS
snmp-server engineID local 00000009020000E04C123456

! traps
snmp-server host 10.20.30.40 version 3 priv netmon
snmp-server enable traps snmp linkdown linkup

Two rules account for most failures: the group must exist before the user is created, and adding a user with a different auth/priv protocol than configured earlier can require recreating the user rather than editing it. A view that includes only 1.3.6.1.2.1 will silently return no data for vendor-specific OIDs under 1.3.6.1.4.1 - a very common "SNMP works but my CPU graphs are empty" cause.

Configuring SNMPv3 on IOS XE: A Complete Walkthrough

Work outside-in in this order and you will not need to debug the protocol: create the view, create the group that references the view, create the user inside the group, then decide what the device may send.

! 1. Access control - what OIDs may be read at all
snmp-server view MONITORVIEW iso included
snmp-server view MONITORVIEW 1.3.6.1.6.3.1.1.4 excluded   ! silence warmStart faking
snmp-server view MONITORVIEW mib-2 included
snmp-server view MONITORVIEW cisco included

! 2. Group - binds a security level to a view
snmp-server group MONITOR v3 auth read MONITORVIEW
snmp-server group MONITOR v3 priv read MONITORVIEW write MONITORWRITE
snmp-server group MONITOR v3 priv access SNMP-ACL

! 3. ACL - restrict which source addresses may query at all
ip access-list standard SNMP-ACL
 permit 10.20.30.0 0.0.0.255
 deny   any log

! 4. User - must reference an existing group
snmp-server user netmon MONITOR v3 auth sha2 256 STRONG_AUTH_PASS priv aes 256 STRONG_PRIV_PASS

! 5. Notifications
snmp-server host 10.20.30.40 version 3 priv netmon
snmp-server enable traps snmp linkdown linkup
snmp-server enable traps cpu threshold

Note the ACL on the group. SNMP has no concept of a bind address, so an ACL at the device is the only access control you get — it is not optional hardening, it is the access control layer. Without it the only protection between the internet and your device's OID tree is udp/161 being firewalled upstream, which is an assumption you do not want to rely on.

Verification

show snmp
show snmp user
show snmp group
show snmp engineID
show snmp view

# from the NMS host
snmpwalk -v3 -l authPriv -u netmon -a SHA -A 'AUTHPASS' -x AES -X 'PRIVPASS' 10.20.30.1 sysDescr

Check localised versus remote users: a user defined for a remote engine ID (a user in a trap receiver) is normal for notification targets, but a monitoring user must exist locally.

Verifying with net-snmp

The device side answers questions about configuration; only a real poll answers questions about reachability and credentials. On any Linux host, install the net-snmp client tools and build the command line deliberately — every option matters, and the ordering of -l, -u, -a, -A, -x, -X is fixed.

sudo apt install snmp              # net-snmp-utils on RHEL

# minimal reachability test
snmpget -v3 -l authPriv -u netmon -a SHA-256 -A 'AUTHPASS' -x AES -X 'PRIVPASS'   10.20.30.1 1.3.6.1.2.1.1.1.0

# walk a subtree
snmpwalk -v3 -l authPriv -u netmon -a SHA-256 -A 'AUTHPASS' -x AES -X 'PRIVPASS'   10.20.30.1 sysDescr

# faster bulk walk for large tables
snmpbulkwalk -v3 -l authPriv -u netmon -a SHA-256 -A 'AUTHPASS' -x AES -X 'PRIVPASS'   -Cn0 -Cr10 10.20.30.1 ifTable

# translate OIDs to names using the default MIB search path
snmpwalk -v3 -l authPriv -On -u netmon -a SHA-256 -A 'AUTHPASS' -x AES -X 'PRIVPASS'   10.20.30.1 1.3.6.1.2.1.2.2.1.10

Test in ascending order of security. If -l noAuthNoPriv works and -l authNoPriv does not, your authentication protocol or passphrase is wrong — the transport, ACL and engine discovery are all proven by the first test. If authNoPriv works and authPriv does not, the problem is the privacy protocol or the privacy passphrase alone, and you have not touched anything else. Skipping straight to authPriv collapses three independent failure modes into one unhelpful timeout.

Ask net-snmp to show you the exchange when it fails:

snmpwalk -v3 -l authPriv -u netmon -a SHA-256 -A 'AUTHPASS' -x AES -X 'PRIVPASS'   -d -e 0x8000000903000112233445 10.20.30.1 sysDescr 2>&1 | head -40

The -d flag dumps the ASN.1 message as it is built and parsed, which shows the engine ID the NMS discovered, the security level it requested, and whether the device answered with an authentication or authorisation error rather than silence. Pair it with -On for numeric OIDs when you suspect a MIB-resolution problem and -Cb when a device mishandles bulk requests.

Reading the Errors

  • unknownUserName: the user does not exist on the device, or the NMS is polling a different engine (stack member or VRF).
  • wrongDigests: authentication password mismatch - check for stray whitespace or a changed password that was not updated on the NMS.
  • unsupportedSecurityLevel: the NMS asked for authPriv but the user or group is configured without privacy.
  • No response at all: ACL, VRF, or the source address of your poller is not in the allowed list.

Trap and Inform Targets

Polling proves the device is readable; notifications prove events arrive. They use different ports (UDP 162 rather than 161), travel in the opposite direction, and — importantly — the device becomes the authoritative engine, so the credential is localised against the receiver's engine ID. The device stores a remote-engine entry for each target, which is exactly what show snmp user shows.

! target with explicit security level and credential
snmp-server host 10.20.30.40 version 3 priv netmon udp-port 162

! inform-style retries for reliability - requires an acknowledgement from the NMS
snmp-server host 10.20.30.40 informs version 3 priv netmon

! prove it works
snmp-server enable traps snmp
interface GigabitEthernet0/0/1
 shutdown
 no shutdown

Traps are fire-and-forget UDP: if the packet is lost or the collector is down, the event is gone with no record on the device. Informs are acknowledged and retried, which is why they are the right choice for events you are contractually obliged to catch. The cost is device-side state and retry buffering, so use informs where they matter rather than for every trap category.

The most common notification failure is a credential that works for polling and not for traps, which is almost always a remote-engine mismatch: the device derives keys against the receiver's engine ID, and if the receiver is a cluster or an appliance behind a load balancer, the engine ID it advertises during discovery may not be the one that later terminates the trap. Configure the target host explicitly and verify receipt at the collector — a fault that generates a syslog line on the device but never appears in the NMS is a receiving-side credential problem, not a device problem.

SNMPv3 on the Server Side: net-snmp and snmpd

If you also run agents on Linux servers, the same dependency chain applies with different syntax. The createUser directive in /etc/snmp/snmpd.conf performs both the key-derivation step and the authorisation step, which is why the passphrase in it must match the NMS exactly and why deleting and re-adding the user is often cleaner than editing it.

# stop, create the user, then remove this line
createUser netmon SHA-256 "STRONG_AUTH_PASS" AES "STRONG_PRIV_PASS"

# access control after the user exists
rouser netmon priv
rouser netmon auth    # weaker fallback, avoid if you can

# restrict who may query
agentaddress udp:161
com2sec notConfigUser  default  public   # remove entirely if you can

Integrating with Monitoring Platforms

Once the credentials work from the command line, hand them to the platform. Zabbix wants the security level, context, auth protocol and priv protocol as separate item fields; Prometheus's snmp_exporter wants them in a module in snmp.yml; LibreNMS discovers them from its own credential table. The recurring problem in all three is the same pairing mistake: the security level, the algorithm names and the passphrases must be the same in the template as they were on the device, and SHA in one tool is SHA-1 or sha in another.

# Prometheus snmp_exporter module excerpt
auths:
  cisco_v3:
    version: 3
    security_level: authPriv
    username: netmon
    password: STRONG_AUTH_PASS
    auth_protocol: SHA256
    priv_protocol: AES
    priv_password: STRONG_PRIV_PASS

Keep the credential in one place and reference it, rather than copying it into every device template. A password rotation that has to be applied to four hundred templates will be deferred; one that touches a single secret will be done. If you are building new dashboards on top of these polls, Zabbix SNMP monitoring for network devices and Prometheus snmp_exporter monitoring go into the item-level detail, while gNMI streaming telemetry is the model-based alternative worth knowing about when polling intervals start to hurt.

Operational Hygiene

  1. One SNMPv3 user per monitoring platform per role - read-only for polling, plus a separate user only if traps must carry different credentials.
  2. Store credentials in the monitoring system's secret store, not in a plain-text config or a shared spreadsheet.
  3. Enable linkUp/linkDown and warm-start traps, then prove they arrive by bouncing a test port.
  4. After any device software upgrade, re-run the verification block: authentication protocol support can change with the image.

Security Hardening Checklist

  1. Disable v1 and v2c outright. no snmp-server community public and no snmp-server community private. A v3 deployment is worth little with a working v2c community beside it.
  2. Use authPriv everywhere. If an algorithm choice is available, take SHA-256 and AES-256; MD5 and DES exist for compatibility, not for new deployments.
  3. Apply an ACL to every group. Bind a named ACL and log denials so that a sweep of your address space is visible rather than silent.
  4. Separate read and write credentials, and do not grant write where you do not need it.
  5. Scope views. Grant iso only where it is required; an unnecessarily wide view turns a read-only credential into a full device inventory.
  6. Rotate passphrases on a schedule and change the device credential first across the fleet in a maintenance window — there is no sequence that avoids a gap, so pick the one with the shorter outage.
  7. Turn off what you do not poll. no snmp-server enable traps for unwanted categories reduces noise and reduces the attack surface of the agent.
  8. Monitor the agent itself. snmp-server ifindex persist keeps interface indices stable across reloads, which prevents a dashboard from silently re-mapping traffic to the wrong port after a reboot.

Worth reading alongside this: the platform-specific procedures in SNMPv3 configuration on Cisco IOS and Junos and the Dell switch equivalent in Dell OS10 SNMPv3 configuration. If your estate is moving toward model-driven interfaces, ArubaOS-CX NAE scripts and agents shows the on-box scripting approach that replaces some polling entirely.

Related reading: SNMPv3 configuration on Cisco IOS and Junos, Zabbix SNMP monitoring for network devices and Prometheus SNMP exporter monitoring.

Troubleshooting Flow

  1. Is the device answering at all? snmpget -v3 -l noAuthNoPriv -u ANYNAME from the NMS host. A reply with an error means the path and agent are fine; total silence points to an ACL, VRF, firewall or a wrong source address.
  2. Is the engine ID what you think? show snmp engineID on the device, and compare with what your NMS recorded. A mismatch means the credential was derived for another engine.
  3. Is the user local or remote? show snmp user — a monitoring user must exist locally, and a remote-engine entry exists only to send notifications to that target.
  4. Is the security level supported? The group's level is a ceiling; a user in an auth group cannot use priv no matter how the request is framed.
  5. Is the OID inside the view? Walk 1.3.6.1.4.1 explicitly. Empty results from a specific subtree while sysDescr works is a view problem every time.
  6. Only then re-enter the passphrase, and re-enter it on both sides.

Keep a written record of the credential set for each platform — engine ID, username, group, security level, auth protocol, priv protocol — in the monitoring system's secret store. Six months from now the question will not be "how does SNMPv3 work" but "which of these four values did we change at the last audit", and a record answers that in seconds.

原文链接:Cisco: SNMP Version 3 configuration guide