
SNMP traps and informs: receiving them with snmptrapd
Most SNMP traffic is a conversation the monitoring server starts. It asks a device for a value on a schedule and stores the answer. Traps run the other way: the device decides something happened, builds a small message and sends it to whoever it was told to notify. That makes traps fast, often well under a second after a port drops, and it also makes them unreliable in ways that polling is not.
What a trap is
A trap is a single UDP datagram sent from an agent (the SNMP service on a router, switch, UPS or Linux server) to a manager, normally on UDP port 162. Polling uses UDP 161 on the agent; traps use 162 on the receiver. A firewall rule that only allows 161 lets you poll happily and silently eats every trap.
Because it is UDP and the sender expects no reply, a plain trap is fire and forget. If the packet is lost, or sent to an address where nothing listens, nobody finds out. The agent will not retry.
Every trap carries an identity (which kind of event this is) and a list of variable bindings, or varbinds: pairs of
OID and value with the details. A linkDown trap carries the ifIndex of the port plus its admin and operational
status. The identity says what happened; the varbinds say where.
The generic traps
SNMPv1 defined six generic traps any agent could send, plus a seventh value meaning "read the vendor's specific
number instead". SNMPv2 gave each of them a notification OID under snmpTraps.
| No. | Name | v2 notification OID | What it usually means |
|---|---|---|---|
| 0 | coldStart | 1.3.6.1.6.3.1.1.5.1 | The agent restarted; in practice, a reboot or power loss |
| 1 | warmStart | 1.3.6.1.6.3.1.1.5.2 | The agent reinitialized without a configuration change |
| 2 | linkDown | 1.3.6.1.6.3.1.1.5.3 | An interface's ifOperStatus is leaving the up state |
| 3 | linkUp | 1.3.6.1.6.3.1.1.5.4 | An interface came back |
| 4 | authenticationFailure | 1.3.6.1.6.3.1.1.5.5 | A request arrived with a wrong community or bad v3 credentials |
| 5 | egpNeighborLoss | 1.3.6.1.6.3.1.1.5.6 | An EGP peer went away; EGP predates BGP and is almost never seen |
| 6 | enterpriseSpecific | built from the vendor OID | A vendor-defined trap; the specific-trap number says which |
Authentication failure traps hint that someone is scanning the management network, or that an old monitoring box still uses a retired community. On devices facing an untrusted network they can also become a flood, so many teams enable them on core gear and leave them off at the edge.
Enterprise-specific traps carry the useful detail: fan and power supply failures, temperature alarms, BGP session
changes, a UPS on battery. In v1 a vendor trap is an enterprise OID plus a specific-trap number. In v2 the two become
one OID: the enterprise OID, then .0, then the specific number. That rule lets one handler cover an old device and
a new one reporting the same fault.
Trap, v2 notification and inform
Three message types arrive on port 162, and they are not interchangeable.
| SNMPv1 trap | SNMPv2c or v3 trap | Inform | |
|---|---|---|---|
| PDU | Trap-PDU | SNMPv2-Trap-PDU | InformRequest-PDU |
| Identity | enterprise OID plus generic and specific numbers | snmpTrapOID.0 varbind |
snmpTrapOID.0 varbind |
| Sender uptime | a field in the PDU | sysUpTime.0, the first varbind |
sysUpTime.0, the first varbind |
| Agent address | carried inside the PDU | taken from the packet source | taken from the packet source |
| Acknowledged and retried | no | no | yes |
Because the v2 format dropped the agent address field, the receiver trusts the packet's source address. If devices send traps from a loopback or management interface, make sure that address is the one your inventory knows.
Informs answer the lost-trap problem: the sender waits for a Response and retransmits on timeout. That costs a little memory on the device, and it only helps while some path to the receiver exists. The operations are defined in RFC 3416, and v1 to v2 conversion in RFC 3584.
v1 and v2c traps carry the community string in clear text, exactly like a poll. Outside an isolated management network, use SNMPv3 with authPriv, or at least accept traps only from known source ranges. The trade-offs are in SNMP v1, v2c and v3: what changed.
Running a receiver with snmptrapd
Most open-source monitoring systems do not listen on port 162 themselves. They rely on snmptrapd from
Net-SNMP to receive and decode traps, then pick up the result through a script, a log
file or a database. The setup is the same whether the next stop is Zabbix, LibreNMS, Icinga or your own script.
- Install the daemon:
snmptrapdon Debian and Ubuntu, part ofnet-snmpon RHEL-family systems. Install MIB files too. - Write
/etc/snmp/snmptrapd.conf. Since release 5.3, snmptrapd drops traps it has no access rule for, loggingNo access configuration - dropping trap.A fresh install that "receives nothing" is very often just this. - Allow UDP 162 inbound on the receiver, from management ranges only.
- Run it in the foreground first:
snmptrapd -f -Loprints every trap to standard output. Once it works, run it under systemd and log to a file or syslog.
A small, realistic configuration:
snmpTrapdAddr udp:162
authCommunity log,execute n0c-tr4p 10.20.0.0/16
createUser -e 0x8000000001020304 trapuser SHA "replace-this-auth-phrase" AES "replace-this-priv-phrase"
authUser log,execute trapuser priv
traphandle IF-MIB::linkDown /usr/local/bin/trap-to-nms linkdown
traphandle IF-MIB::linkUp /usr/local/bin/trap-to-nms linkup
traphandle default /usr/local/bin/trap-to-nms other
The first line listens on UDP 162 on all IPv4 addresses, which is the default anyway. authCommunity takes the
processing types log, execute and net (forward to another receiver) plus an optional source network, so the
community is accepted from the management range and ignored elsewhere. For v3, notice the -e on createUser:
with traps the sending device is the authoritative engine, so the receiver needs a user tied to that device's
engine ID. With informs the receiver is authoritative, one reason v3 informs are easier to roll out across a
hundred switches.
What a handler receives
A traphandle program reads the trap on standard input, already converted to the v2 layout even when a v1 device
sent it: hostname, transport address, then one varbind per line, OID first and value after the first space. The
first two varbinds are always the sender's uptime (net-snmp may print it as sysUpTimeInstance) and
snmpTrapOID.0.
core-sw1.example.net
UDP: [10.20.0.11]:50612->[10.20.0.5]:162
DISMAN-EVENT-MIB::sysUpTimeInstance 12:3:41:07.15
SNMPv2-MIB::snmpTrapOID.0 IF-MIB::linkDown
IF-MIB::ifIndex.10114 10114
IF-MIB::ifAdminStatus.10114 up
IF-MIB::ifOperStatus.10114 down
The handler maps the sender to a known host, turns ifIndex 10114 into an interface name, and writes an event.
Keep it quick: snmptrapd waits for each handler to finish, so slow lookups stall every trap behind it. Write to a
queue and return. Script conventions are in feeding your monitor from outside programs.
Making OIDs readable
Without MIBs the receiver prints numbers. With the vendor's MIB files loaded, the same trap reads as a named
notification with values like down instead of 2.
- Put vendor MIBs in a directory such as
/usr/local/share/snmp/mibs, add it withmibdirs +/usr/local/share/snmp/mibsinsnmp.conf, and load them withmibs +ALL. - On Debian and Ubuntu the stock
/etc/snmp/snmp.confdisables MIB loading with a baremibs :line. Comment it out, and installsnmp-mibs-downloaderfor the standard IETF MIBs. - Check that a name resolves before you use it in a
traphandleline.snmptranslate -On IF-MIB::linkDownshould print.1.3.6.1.6.3.1.1.5.3, andsnmptranslate -Td IF-MIB::linkDownshows the full definition.
Loading every MIB from every vendor slows each command and invites name clashes. Load what you have hardware for.
Testing without waiting for a failure
Net-SNMP ships snmptrap and snmpinform, which send any notification from any Linux box. Send tests from inside
the management range so your source rules match. The empty '' is the uptime argument; the tool fills in a default.
snmptrap -v 2c -c n0c-tr4p 10.20.0.5 '' IF-MIB::linkDown \
IF-MIB::ifIndex.2 i 2 IF-MIB::ifAdminStatus.2 i 1 IF-MIB::ifOperStatus.2 i 2
snmpinform -v 2c -c n0c-tr4p 10.20.0.5 '' IF-MIB::linkDown \
IF-MIB::ifIndex.2 i 2 IF-MIB::ifAdminStatus.2 i 1 IF-MIB::ifOperStatus.2 i 2
snmptrap always exits cleanly, because nothing confirms a trap. snmpinform waits for the Response and fails on
timeout, which makes it the honest test: if it times out, your traps were never arriving either.
Watch the receiver while you send, with snmptrapd -f -Lo or tcpdump -n -i any udp port 162. If tcpdump sees
packets and snmptrapd logs nothing, check the access rules and community. If tcpdump sees nothing, check the path:
host firewall, router ACL, or a device sending to an old address. More symptoms are in
common monitoring errors.
Pointing devices at the receiver
Every device needs the receiver's address, the version and credentials, and a list of notifications to send. On a
Linux server running the Net-SNMP agent, that is a few lines in snmpd.conf:
trap2sink 10.20.0.5 n0c-tr4p
informsink 10.20.0.5 n0c-tr4p
authtrapenable 1
Use trap2sink for v2c traps or informsink for informs, not both; authtrapenable 1 adds authenticationFailure.
Network gear has its own syntax for the same settings. On each platform, set the trap source interface to the
management address and check which trap groups are on by default. Environmental, power and routing protocol
notifications often need enabling separately.
Why traps alone are not enough
Treat a trap as a fast hint, not a record of truth. The weaknesses are built in:
- UDP loss. A failing link drops packets, and the trap about that link often has to cross it.
- The broken path. When a branch router's only WAN link dies, its linkDown trap has no way out. You hear nothing from exactly the site in trouble.
- Silent devices. A switch that loses power sends nothing until it comes back.
- Drift. Readdress the receiver or change a community, and traps stop with no error anywhere.
- Storms. A flapping port can produce hundreds of traps a second. Devices rate-limit traps, so the one you needed may be the one dropped.
Traps and polling together
The pattern that works: poll everything on a steady interval, and use traps to react between polls. When a linkDown trap arrives, record an event and, if your NMS can, poll that interface at once to confirm. The poller catches the dead branch and the switch with no power. Traps catch the 20-second flap a 5-minute poll never sees. Both feed the same event stream, where duplicates merge into one alarm.
A checklist for a new trap receiver:
- UDP 162 open on the receiver, from management ranges only.
authCommunityorauthUserlines in place, v3 wherever the network is not trusted.- MIBs loaded for every vendor you run, and
snmptranslateresolves their names. - One
snmpinformtest from each device family, seen end to end in the NMS. - Polling still covers every host and interface the traps describe.
- A monthly look at which devices have never sent a trap. Those usually point at the wrong address.