SNMP v3 Hardening: Authentication, Encryption, and View-Based Access Control
Problem
SNMP (Simple Network Management Protocol) is how network devices — switches, routers, firewalls, load balancers, and UPS systems — expose operational metrics and accept management commands. It is decades old and widely deployed. SNMPv1 and v2c are fundamentally broken from a security perspective: authentication is a plaintext “community string” (effectively a password sent in clear text), and there is no encryption. Any on-path observer reads the community string and gains full SNMP access.
SNMPv3 was standardised in 1998 and provides proper authentication and encryption. Despite this, SNMPv1/v2c remain common in production because network equipment often ships with legacy defaults, and administrators do not change them.
Even with SNMPv3, misconfiguration is common:
noAuthNoPrivsecurity level. SNMPv3 has three security levels:noAuthNoPriv(no authentication, no encryption),authNoPriv(authentication only), andauthPriv(authentication and encryption). Many deployments useauthNoPriv— authentication without encryption. SNMP responses are unencrypted; sensitive OID values (interface counters, routing tables, device configuration) are readable by on-path observers.- MD5 or DES for authentication and privacy. SNMPv3 supports multiple algorithms. Older configurations use MD5 for authentication and DES for privacy — both are cryptographically weak. SHA-2 and AES should be mandatory.
- Overpermissive MIB view. SNMP views define which OID subtrees a user can access. A default view often includes the entire MIB tree — including OIDs that expose device running configuration, VPN pre-shared keys, and SNMP user credentials. Views should be scoped to monitoring-required OIDs only.
- SNMP write access enabled. SNMPv3 supports write operations (SET requests) to modify device configuration. Monitoring systems need read-only access. Write access granted to the monitoring community is an unnecessary privilege.
- No source IP restriction. The SNMP agent accepts queries from any IP address. Access should be restricted to the monitoring server’s IP.
Target systems: Net-SNMP 5.9+ (Linux agents); Cisco IOS XE, NX-OS; Juniper Junos; Palo Alto PAN-OS; network switches and routers with SNMPv3 support.
Threat Model
- Adversary 1 — Community string capture (SNMPv1/v2c): An attacker on the management network captures SNMP packets and extracts the plaintext community string. They then query all devices using the string, extracting network topology, interface configurations, and routing tables.
- Adversary 2 — SNMPv3
authNoPrivresponse capture: An attacker captures SNMPv3 responses. Authentication protects the request, but responses are unencrypted. The attacker reads sensitive OID values — VPN configuration, interface IP addresses, OSPF neighbour tables. - Adversary 3 — SNMP SET for device reconfiguration: An attacker who has obtained SNMP write credentials sends SET requests to modify routing tables, disable interfaces, or change device configuration. Without write-access restriction, any user with the write community string can reconfigure devices.
- Adversary 4 — SNMP amplification DDoS: An attacker sends SNMP GetBulk requests with a spoofed victim IP to poorly secured SNMP agents, causing large responses directed at the victim. Affects devices with open SNMP accessible from the internet.
- Adversary 5 — SNMPv3 user enumeration: SNMPv3 error responses differ for unknown users vs. authentication failures. An attacker enumerates valid SNMP usernames by probing error responses, then focuses credential attacks on known users.
- Access level: Adversaries 1 and 2 are on the management network. Adversary 3 has obtained write credentials. Adversary 4 operates externally. Adversary 5 can reach SNMP ports.
- Objective: Extract network topology, credentials, and configuration; reconfigure devices; enable DDoS amplification.
- Blast radius: Full network topology exposed via SNMP enables precise targeting of subsequent attacks. SNMP write access enables configuration changes equivalent to console access.
Configuration
Step 1: Disable SNMPv1 and v2c, Enforce SNMPv3
# Linux/Net-SNMP: /etc/snmp/snmpd.conf
# REMOVE or comment out all v1/v2c community strings.
# Never include lines like:
# rocommunity public
# rocommunity private
# rwcommunity anycommunity
# Disable v1 and v2c in the agent.
# Net-SNMP: restrict to SNMPv3 only.
disableAuthorisation yes # Reject all non-v3 requests.
# Or explicitly drop v1/v2c at the transport layer (see firewall rules).
# Cisco IOS XE: disable v1/v2c community strings.
no snmp-server community public RO
no snmp-server community private RW
no snmp-server community monitoring RO
# Enable SNMPv3 only.
snmp-server group MONITORING-GROUP v3 priv
snmp-server view MONITORING-VIEW interfaces included
snmp-server view MONITORING-VIEW system included
snmp-server view MONITORING-VIEW ip.route included
Step 2: Configure SNMPv3 with authPriv and Strong Algorithms
# Net-SNMP: /etc/snmp/snmpd.conf
# Create a read-only monitoring user with SHA-256 auth and AES-256 privacy.
# Format: createUser username SHA-256 auth-password AES-256 priv-password
createUser monitoring-ro SHA-256 "$(openssl rand -hex 32)" AES-256 "$(openssl rand -hex 32)"
# Grant read-only access with full authentication and encryption (authPriv).
rouser monitoring-ro priv
# Restrict access to the monitoring server IP.
rocommunity6 "" ::1 # IPv6 loopback only (for local queries if needed).
# Allow SNMPv3 from monitoring server only.
agentaddress udp:161,udp6:161
# Use host-level firewall to enforce source IP (see Step 4).
# Cisco IOS XE: SNMPv3 user with AES-256.
snmp-server user monitoring-ro MONITORING-GROUP v3 auth sha-256 AUTH-PASSPHRASE priv aes 256 PRIV-PASSPHRASE
# Verify the user.
show snmp user
# Expected output shows auth: sha-256, priv: aes-256.
# Juniper Junos.
set snmp v3 usm local-engine user monitoring-ro authentication-sha authentication-password AUTH-PASSPHRASE
set snmp v3 usm local-engine user monitoring-ro privacy-aes128 privacy-password PRIV-PASSPHRASE
set snmp v3 access group MONITORING-GROUP any-security-model security-level privacy read-view MONITORING-VIEW
Security levels — only authPriv is acceptable:
| Level | Authentication | Privacy | Use |
|---|---|---|---|
noAuthNoPriv |
None | None | Never use |
authNoPriv |
Yes | None | Do not use; responses unencrypted |
authPriv |
Yes | AES-256 | Required |
Step 3: View-Based Access Control — Restrict MIB Scope
Limit the MIB subtrees the monitoring user can access:
# Net-SNMP: /etc/snmp/snmpd.conf
# Define a view containing only necessary OIDs for monitoring.
view MONITORING-VIEW included .1.3.6.1.2.1.1 # System info (sysDescr, sysUpTime, etc.)
view MONITORING-VIEW included .1.3.6.1.2.1.2 # Interfaces (ifInOctets, ifOutOctets, etc.)
view MONITORING-VIEW included .1.3.6.1.2.1.4.20 # IP addresses.
view MONITORING-VIEW included .1.3.6.1.2.1.25.1 # Host resources (hrSystemUptime).
view MONITORING-VIEW included .1.3.6.1.4.1.2021 # UCD-SNMP (CPU, memory, disk).
# Explicitly EXCLUDE sensitive OIDs.
view MONITORING-VIEW excluded .1.3.6.1.2.1.2.2.1.6 # Interface MAC addresses.
view MONITORING-VIEW excluded .1.3.6.1.4.1.9 # Cisco private MIB (contains full config).
# Assign the view to the monitoring user.
# rouser monitoring-ro priv -V MONITORING-VIEW
access MONITORING-GROUP "" any priv exact MONITORING-VIEW none none
# Cisco IOS XE: SNMP view restricting access.
snmp-server view MONITORING-VIEW system included
snmp-server view MONITORING-VIEW interfaces included
snmp-server view MONITORING-VIEW ip.route included
# Exclude: private/enterprise MIBs that expose running config.
snmp-server view MONITORING-VIEW cisco excluded # Cisco private MIB.
# Assign view to group.
snmp-server group MONITORING-GROUP v3 priv read MONITORING-VIEW
Step 4: Source IP Restriction
# Linux: iptables/nftables — accept SNMP only from monitoring server.
nft add rule inet filter input \
udp dport 161 \
ip saddr 10.50.0.10 \ # Monitoring server IP.
accept
nft add rule inet filter input \
udp dport 161 \
drop # Drop all other SNMP.
# Net-SNMP: also enforce at application level.
# /etc/snmp/snmpd.conf
agentaddress udp:161
# The rocommunity/rouser directives accept a source IP filter.
rouser monitoring-ro priv 10.50.0.10 # Allow only from monitoring server.
# Cisco IOS: SNMP access control list.
ip access-list standard SNMP-ALLOWED
permit 10.50.0.10
deny any log
snmp-server group MONITORING-GROUP v3 priv access SNMP-ALLOWED
Step 5: Disable SNMP Write Access
Read-only for all monitoring. No exceptions:
# Net-SNMP: never use rwuser or rwcommunity.
# Only rouser directives in snmpd.conf.
# Verify no write access is configured.
grep -E "^rwuser|^rwcommunity|^rw" /etc/snmp/snmpd.conf
# Output should be empty.
# Cisco: verify no write community or group is configured.
show snmp group
# Confirm no group has write access.
# Remove any RW configuration.
no snmp-server community <any-rw-community> RW
Step 6: Credential Management and Rotation
# Generate strong random passwords for SNMP auth and priv.
SNMP_AUTH=$(openssl rand -base64 24)
SNMP_PRIV=$(openssl rand -base64 24)
# Store in secrets manager (Vault, AWS Secrets Manager).
vault kv put secret/snmp/monitoring-ro \
auth_password="$SNMP_AUTH" \
priv_password="$SNMP_PRIV" \
device_group="network-core"
# Distribute to devices via configuration management.
# Never hardcode in Ansible playbooks or Terraform configs.
# Rotate SNMP credentials annually or after any suspected compromise.
# Net-SNMP: deleteUser and recreate.
net-snmp-create-v3-user \
-ro \
-A "$(vault kv get -field=auth_password secret/snmp/monitoring-ro)" \
-a SHA-256 \
-X "$(vault kv get -field=priv_password secret/snmp/monitoring-ro)" \
-x AES \
monitoring-ro
Step 7: SNMP Trap Security
If using SNMP traps (device-initiated alerts to the management station):
# Net-SNMP: configure trap receiver with authentication.
# /etc/snmp/snmpd.conf
trapsink 10.50.0.10 # v2c trap (avoid if possible).
informsink 10.50.0.10 monitoring-ro # v3 inform (preferred; acknowledged).
# snmptrapd.conf on the management station: require authentication.
authCommunity log,execute,net public # REMOVE this.
createUser -e 0x8000000001020304 monitoring-ro SHA-256 AUTH-PASS AES-256 PRIV-PASS
authUser log,execute,net monitoring-ro priv
Step 8: Telemetry
snmp_agent_queries_total{device, version, security_level} counter
snmp_agent_auth_failures_total{device} counter
snmp_agent_set_requests_total{device} counter # Should be 0.
snmp_agent_unknown_users_total{device} counter
snmp_v1_v2c_queries_total{device} counter # Should be 0.
Alert on:
snmp_agent_auth_failures_totalspike — credential attack or misconfigured monitoring system.snmp_v1_v2c_queries_totalnon-zero — a device is still accepting v1/v2c queries despite policy.snmp_agent_set_requests_totalnon-zero — SET request received; all SNMP should be read-only; investigate immediately.snmp_agent_unknown_users_totalnon-zero — enumeration attempt against SNMPv3 users.- SNMP queries from IPs outside the monitoring server subnet — unauthorised access attempt.
Expected Behaviour
| Signal | SNMPv1/v2c default | Hardened SNMPv3 |
|---|---|---|
| Community string on network | Readable in plaintext | No community strings; v3 credentials only |
| SNMP response content | Unencrypted | AES-256 encrypted |
| Query from arbitrary IP | Accepted | Rejected by ACL and application filter |
| Full MIB access | Default | View restricted to monitoring OIDs |
| SNMP write access | Often enabled | Disabled; SET requests rejected |
Trade-offs
| Aspect | Benefit | Cost | Mitigation |
|---|---|---|---|
authPriv mandatory |
All traffic encrypted | Slightly higher CPU on agent (AES) | Negligible on modern hardware |
| View-restricted MIB | Limits data exposure | Must maintain view definition as monitoring needs evolve | Document required OIDs; version-control view config |
| Source IP restriction | Prevents unauthorised queries | Monitoring server IP changes require ACL update | Use a dedicated management VLAN with stable IP range |
| Disabling v1/v2c | Eliminates plaintext credentials | Some legacy devices or tools may not support v3 | Inventory legacy devices; schedule migration or isolation |
Failure Modes
| Failure | Symptom | Detection | Recovery |
|---|---|---|---|
| Auth password mismatch after rotation | Monitoring graphs go blank; SNMP auth failure | snmp_agent_auth_failures_total spike |
Verify new password deployed to both agent and monitoring system |
| View too restrictive | Monitoring system reports missing metrics | Specific OIDs return noSuchObject |
Add required OID to view definition; reload agent |
| Source IP block too narrow | Monitoring server IP change breaks queries | Monitoring graphs blank; no SNMP errors | Update ACL with new monitoring server IP |
| SNMPv3 engine ID mismatch | Authentication fails; snmpwalk returns errors |
Auth failure in agent log | Verify engine ID consistency between agent and monitoring system |