Overview
Simple Network Management Protocol (SNMP) is the standard protocol for monitoring and managing network devices such as routers, switches, servers, printers, and IoT devices. SNMP uses a manager-agent architecture where the management station (NMS) queries agents running on managed devices. Agents expose device information through a hierarchical namespace of Object Identifiers (OIDs) organized in Management Information Bases (MIBs). SNMP operates primarily over UDP port 161 (queries) and 162 (traps/notifications).
Three versions of SNMP are widely used: SNMPv1 (community string authentication, no encryption), SNMPv2c (improved performance with bulk operations, still community-based), and SNMPv3 (adds authentication with HMAC-MD5/SHA and encryption with DES/AES for secure management). SNMPv3 is the recommended version for production environments due to its security features. SNMP supports four main operations: GET (retrieve a single value), GETNEXT (walk through the MIB tree), SET (modify a value), and TRAP/INFORM (asynchronous notifications from agent to manager).
Installation
# Ubuntu/Debian
sudo apt install snmp snmp-mibs-downloader snmpd
# RHEL/CentOS/Rocky
sudo dnf install net-snmp net-snmp-utils net-snmp-libs
# macOS
brew install net-snmp
# Download standard MIBs
sudo download-mibs
# Enable MIB resolution (comment out 'mibs :' line)
sudo sed -i 's/^mibs :/#mibs :/' /etc/snmp/snmp.conf
Core Commands
| Command | Description |
|---|
snmpget | Get a single OID value |
snmpwalk | Walk a subtree of OIDs |
snmpbulkwalk | Bulk walk (SNMPv2c/v3, faster) |
snmpgetnext | Get next OID in tree |
snmpset | Set a value on the agent |
snmptable | Display SNMP table |
snmptranslate | Translate OID to/from name |
snmptrap | Send an SNMP trap |
snmpdf | Display disk usage via SNMP |
snmpstatus | Quick device status |
SNMPv2c Queries
# Get system description
snmpget -v2c -c public 192.168.1.1 sysDescr.0
# Get system uptime
snmpget -v2c -c public 192.168.1.1 sysUpTime.0
# Walk system information
snmpwalk -v2c -c public 192.168.1.1 system
# Walk interface table
snmpwalk -v2c -c public 192.168.1.1 ifTable
# Bulk walk (faster for large tables)
snmpbulkwalk -v2c -c public -Cr50 192.168.1.1 ifTable
# Get interface names and status
snmpwalk -v2c -c public 192.168.1.1 ifDescr
snmpwalk -v2c -c public 192.168.1.1 ifOperStatus
# Get interface traffic counters (64-bit)
snmpwalk -v2c -c public 192.168.1.1 ifHCInOctets
snmpwalk -v2c -c public 192.168.1.1 ifHCOutOctets
# Display as table
snmptable -v2c -c public 192.168.1.1 ifTable
SNMPv3 Queries
# SNMPv3 with authentication and encryption (authPriv)
snmpget -v3 -u myuser -l authPriv \
-a SHA -A "authpassword123" \
-x AES -X "privpassword123" \
192.168.1.1 sysDescr.0
# SNMPv3 with authentication only (authNoPriv)
snmpget -v3 -u myuser -l authNoPriv \
-a SHA -A "authpassword123" \
192.168.1.1 sysUpTime.0
# SNMPv3 walk
snmpwalk -v3 -u myuser -l authPriv \
-a SHA -A "authpassword123" \
-x AES -X "privpassword123" \
192.168.1.1 interfaces
# SNMPv3 bulk walk
snmpbulkwalk -v3 -u myuser -l authPriv \
-a SHA256 -A "authpassword123" \
-x AES256 -X "privpassword123" \
192.168.1.1 ifTable
Common OIDs
| OID | Name | Description |
|---|
1.3.6.1.2.1.1.1.0 | sysDescr | System description |
1.3.6.1.2.1.1.3.0 | sysUpTime | Uptime in timeticks |
1.3.6.1.2.1.1.5.0 | sysName | Hostname |
1.3.6.1.2.1.1.6.0 | sysLocation | Physical location |
1.3.6.1.2.1.2.1.0 | ifNumber | Number of interfaces |
1.3.6.1.2.1.2.2.1.2 | ifDescr | Interface descriptions |
1.3.6.1.2.1.2.2.1.8 | ifOperStatus | Interface status (1=up, 2=down) |
1.3.6.1.2.1.25.1.1.0 | hrSystemUptime | Host uptime |
1.3.6.1.2.1.25.2.3 | hrStorageTable | Storage/disk info |
1.3.6.1.2.1.25.3.3.1.2 | hrProcessorLoad | CPU load |
1.3.6.1.4.1 | enterprises | Vendor-specific MIBs |
SNMP Agent Configuration
snmpd.conf (Net-SNMP Agent)
# /etc/snmp/snmpd.conf
# SNMPv2c community strings
rocommunity public 192.168.1.0/24
rwcommunity private 192.168.1.100
# SNMPv3 user
createUser myuser SHA "authpassword123" AES "privpassword123"
rouser myuser authpriv
# System information
syslocation "Data Center, Rack A-12"
syscontact "admin@example.com"
sysname "web-server-01"
# Extend with custom scripts
extend cpu_temp /usr/local/bin/get_cpu_temp.sh
extend disk_usage /bin/df -h /
# Listen addresses
agentaddress udp:161,udp6:161
# Access control
com2sec localnet 192.168.1.0/24 public
group MyROGroup v2c localnet
view all included .1
access MyROGroup "" any noauth exact all none none
# Restart agent
sudo systemctl restart snmpd
sudo systemctl enable snmpd
# Test locally
snmpwalk -v2c -c public localhost system
SNMP Trap Configuration
# /etc/snmp/snmptrapd.conf
authCommunity log,execute,net public
traphandle default /usr/local/bin/trap_handler.sh
# Send a test trap
snmptrap -v2c -c public 192.168.1.100:162 '' \
1.3.6.1.4.1.99999 \
1.3.6.1.4.1.99999.1 s "Test alert: disk full"
# SNMPv3 trap
snmptrap -v3 -u myuser -l authPriv \
-a SHA -A "authpassword123" \
-x AES -X "privpassword123" \
-e 0x0102030405 192.168.1.100:162 '' \
1.3.6.1.4.1.99999 \
1.3.6.1.4.1.99999.1 s "Critical event"
MIB Management
# Translate OID to name
snmptranslate -On sysDescr.0
# Output: .1.3.6.1.2.1.1.1.0
# Translate name to OID
snmptranslate -Of .1.3.6.1.2.1.1.1.0
# Output: .iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0
# Show MIB tree
snmptranslate -Tp .1.3.6.1.2.1.1
# List available MIBs
ls /usr/share/snmp/mibs/
# Add custom MIB
sudo cp CUSTOM-MIB.txt /usr/share/snmp/mibs/
export MIBS=+CUSTOM-MIB
Advanced Usage
SNMP SET Operations
# Change system location (requires rw community)
snmpset -v2c -c private 192.168.1.1 sysLocation.0 s "Building A, Floor 3"
# Change system contact
snmpset -v2c -c private 192.168.1.1 sysContact.0 s "noc@example.com"
# Disable interface (OID for ifAdminStatus)
snmpset -v2c -c private 192.168.1.1 ifAdminStatus.3 i 2 # 2=down
# Enable interface
snmpset -v2c -c private 192.168.1.1 ifAdminStatus.3 i 1 # 1=up
Monitoring Scripts
#!/bin/bash
# Check interface status
HOST=$1
COMMUNITY=${2:-public}
snmpwalk -v2c -c "$COMMUNITY" -OqvU "$HOST" ifDescr | while IFS= read -r iface; do
idx=$(snmpwalk -v2c -c "$COMMUNITY" -OqvU "$HOST" ifDescr | grep -n "$iface" | cut -d: -f1)
status=$(snmpget -v2c -c "$COMMUNITY" -OqvU "$HOST" ifOperStatus.$idx 2>/dev/null)
echo "$iface: $status"
done
Prometheus SNMP Exporter
# snmp.yml (generator config)
modules:
if_mib:
walk:
- ifTable
- ifXTable
lookups:
- source_indexes: [ifIndex]
lookup: ifDescr
overrides:
ifType:
type: EnumAsInfo
# Prometheus scrape config
scrape_configs:
- job_name: 'snmp'
static_configs:
- targets: ['192.168.1.1', '192.168.1.2']
metrics_path: /snmp
params:
module: [if_mib]
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: snmp-exporter:9116
Troubleshooting
| Issue | Solution |
|---|
Timeout: No Response | Verify agent is running; check firewall allows UDP 161; test community string |
No Such Object | OID may not be supported on device; check with snmpwalk on parent OID |
Authentication failure | Wrong community string or SNMPv3 credentials; check snmpd.conf ACLs |
| MIB not resolving | Install MIBs: sudo download-mibs; uncomment mibs : line in snmp.conf |
| 32-bit counter wrap | Use 64-bit counters (ifHCInOctets) instead of ifInOctets for high-speed interfaces |
| Traps not received | Check snmptrapd is running on port 162; verify firewall allows UDP 162 |
| SNMPv3 engine ID mismatch | Specify -e flag with correct engine ID, or let auto-discovery work |