This guide assumes the Zabbix server/proxy from the proxy post, at least one SNMP-capable device (switch, UPS, printer, NAS), and that you know the device's read community / SNMPv3 credentials.

SNMP is the oldest monitoring protocol that's still everywhere. Switches, UPSes, ILO/iDRAC, printers, storage arrays, even modern firewalls if it has a management interface, it speaks SNMP. Zabbix supports it natively, but the defaults assume you already know how to read MIBs and OIDs. This post is the operational layer.

SNMP in 60 Seconds

Three primitives:

  • Get fetch one OID's value.
  • Walk fetch every OID under a subtree.
  • Trap the device pushes an event to a listener.

Three versions:

Version Auth Use case
v1 Plain-text community Legacy only avoid
v2c Plain-text community Most LAN gear, fine on trusted nets
v3 Username + auth + priv Anything reachable from untrusted nets

Use v3 wherever the device supports it. v2c communities are passwords sent in clear text. SNMPv3 with authPriv (SHA + AES) is what every audit will eventually require.

Tools You'll Use Constantly

# Net-SNMP - install on the proxy host
sudo apt install -y snmp snmp-mibs-downloader
sudo download-mibs

# v2c walk
snmpwalk -v2c -c public 10.0.0.10 1.3.6.1.2.1.1

# v3 walk with auth + priv
snmpwalk -v3 -l authPriv -u zbx -a SHA -A 'authpw' -x AES -X 'privpw' 10.0.0.10 system

# Resolve a name to its OID
snmptranslate -On SNMPv2-MIB::sysName.0
# .1.3.6.1.2.1.1.5.0

snmpwalk is the discovery tool. Run it on every new device class to see what's actually exposed before you write a single template.

Configure the Host in Zabbix

In Data Collection -> Hosts -> Create host, add an SNMP interface:

  • Type: SNMP
  • IP address: device IP
  • Port: 161
  • SNMP version: SNMPv3 (or v2c)
  • Macro lookup: tick Use bulk requests
  • For v3, fill in Security name, Auth protocol, Auth passphrase, Privacy protocol, Privacy passphrase

Always tick "Use bulk requests". Without it, Zabbix issues one GET per OID per interval devastating on switches with hundreds of interfaces.

Items: SNMP Get

The simplest item:

  • Type: SNMPv3 agent (matches the interface)
  • Key: anything unique, e.g. system.uptime
  • SNMP OID: 1.3.6.1.2.1.1.3.0 (sysUpTime) or the symbolic form SNMPv2-MIB::sysUpTime.0

Use numeric OIDs in production templates. Symbolic names depend on the proxy's MIB files being installed. Numeric is universal.

MIBs: The Glue Between Numbers and Names

A MIB is a text file that maps human names (ifInOctets) to OIDs (1.3.6.1.2.1.2.2.1.10) and describes their type. Vendors ship their own MIBs.

To install a vendor MIB on the proxy:

sudo cp DLINK-AGENT-MIB.txt /usr/share/snmp/mibs/
snmptranslate -m +DLINK-AGENT-MIB -On DLINK-AGENT-MIB::dEntityExtEnvTempUnit.0

Once the MIB is installed, snmpwalk and snmptranslate resolve names. Zabbix itself doesn't need the MIB if you use numeric OIDs in items which is exactly why production templates always do.

Low-Level Discovery for Per-Interface Items

A switch with 48 ports needs 48 ifInOctets items, 48 ifOutOctets items, etc. Doing that by hand is cruel and unusual. SNMP LLD is the answer same pattern as the LLD post, with SNMP-specific discovery.

In Discovery rules -> Create discovery rule:

  • Type: SNMP agent
  • Key: if.discovery
  • SNMP OID: discovery[{#IFNAME},1.3.6.1.2.1.31.1.1.1.1,{#IFOPERSTATUS},1.3.6.1.2.1.2.2.1.8,{#IFTYPE},1.3.6.1.2.1.2.2.1.3]

This walks three OIDs in parallel and returns one entry per interface index, with {#IFNAME}, {#IFOPERSTATUS}, {#IFTYPE} populated.

Then under that rule, an item prototype:

  • Name: Interface {#IFNAME}: bits in
  • Key: if.in[{#SNMPINDEX}]
  • SNMP OID: 1.3.6.1.2.1.31.1.1.1.6.{#SNMPINDEX}
  • Units: bps
  • Preprocessing: Change per second, then Custom multiplier 8

{#SNMPINDEX} is the row index in the original walk Zabbix populates it automatically per discovered entry.

Filtering at Discovery Time

Most switches expose hundreds of internal-only interfaces (Null0, Vlan1, Loopback0, etc.) you don't care about. Filter at the discovery rule under the Filters tab:

  • {#IFTYPE} matches ^(6|117|161)$ ethernetCsmacd, gigabitEthernet, ieee8023adLag
  • {#IFNAME} does not match ^(Null|Loopback|Vlan)
  • {#IFOPERSTATUS} matches ^1$ only operationally up

The fewer items you create per device, the cheaper each subsequent collection cycle is. Filter aggressively at discovery; promote interfaces back later if you genuinely need them.

SNMP Traps The Push Side

Polling is fine for counters. For events (link up/down, fan failure, PSU loss) you want traps the device pushes the moment something changes.

The flow:

  1. Device sends an SNMP trap to the proxy on UDP/162.
  2. snmptrapd on the proxy receives, formats, and writes to a log file.
  3. Zabbix reads the log file with snmptrap[<filter>] items.

Install and configure snmptrapd:

sudo apt install -y snmptrapd

/etc/snmp/snmptrapd.conf:

authCommunity log,execute,net public
disableAuthorization no
format2 %V\n%B\n%v\n
traphandle default /usr/sbin/zabbix_trap_receiver.pl

The zabbix_trap_receiver.pl script (ships with Zabbix) writes to /var/log/zabbix/snmptraps.log.

In Zabbix, on the host, add an item:

  • Type: SNMP trap
  • Key: snmptrap[".*linkDown.*"]
  • Type of information: Log

Then a trigger on the item to fire when the regex matches.

Forward traps from agent to proxy, not directly to the server. Centralize trap reception on the proxy that already monitors the device. Otherwise traps and polled data show up on different hosts in the UI.

Useful Standard MIBs

Most useful day-one OIDs across vendors:

Symbol OID What it is
sysName 1.3.6.1.2.1.1.5.0 Hostname
sysUpTime 1.3.6.1.2.1.1.3.0 Time since SNMP restart
ifNumber 1.3.6.1.2.1.2.1.0 Interface count
ifInOctets.X 1.3.6.1.2.1.2.2.1.10.X 32-bit byte counter
ifHCInOctets.X 1.3.6.1.2.1.31.1.1.1.6.X 64-bit byte counter (use this)
ifOperStatus.X 1.3.6.1.2.1.2.2.1.8.X up=1, down=2
hrSystemUptime 1.3.6.1.2.1.25.1.1.0 OS uptime (vs SNMP uptime)
hrStorageUsed 1.3.6.1.2.1.25.2.3.1.6.X Memory/disk usage

Always use ifHC* (64-bit) counters for interfaces. The 32-bit if* counters wrap in seconds on 10G+ links, and Zabbix shows nonsensical "deltas" when they do.

Operational Habits

  • One template per device class. Net-Cisco-IOS, Net-Aruba-CX, UPS-APC, Storage-Synology. Templates compose; massive "everything" templates don't.
  • User macros for community/credentials. {$SNMP_COMMUNITY} per host or per group. Templates reference the macro; the credential never lives in the template.
  • Pin polling intervals to what you actually need. A 30s poll on a 48-port switch with 8 items per port is 13 NVPS from one device. Multiply by 200 switches and your proxy is doing nothing else.
  • Test with snmpwalk first, always. If the OID doesn't return what you expect from the proxy host, no Zabbix configuration will fix it. Get the walk right, then build the item.
  • Watch the SNMP error count. Reports -> Audit log and the zabbix[stats,...] internal items both expose how often SNMP collection fails. A spike usually means a device upgraded firmware and renumbered an OID.

What to Do Next

SNMP is wide, ancient, and surprisingly capable once you stop fighting the defaults. Use v3, walk before you write items, filter discovery aggressively, prefer 64-bit counters, push templates per device class, and centralize traps on the proxy that polls the device. Once those reflexes are in place, adding a new switch model to the fleet stops being a project and starts being half a day with snmpwalk and a template editor.

Three concrete moves on the next device class you onboard:

  1. snmpwalk -v3 -l authPriv ... before you open Zabbix. If the walk doesn't return what you expect from the proxy host, no template configuration will fix it. Get the OID right at the shell, then build the item.
  2. Filter the LLD rule on IF-MIB::ifType (or equivalent). A 48-port switch typically has 48 physical ports plus 100+ virtual interfaces (loopbacks, tunnels, sub-interfaces) you didn't ask to monitor. Filter to ethernetCsmacd and you cut the item count by 70% before any of it lands in the DB.
  3. Bind traps to the same proxy that polls the device. Cross-proxy correlation is a debugging nightmare; a trap arriving at proxy-A while the polled state lives on proxy-B will look like two separate events even when they're the same incident.

Pairs naturally with the Low-Level Discovery post (the LLD rules you're filtering above) and the proxy load-balancing post (so SNMP polling load gets sharded the same way agent traffic does).