1 goals
This document explains how to configure OpenBSD'ssnmpd
to receive SNMP traps. We'll also cover the implementation of a generic trap handler, aswell as a specialized one.
2 snmpd
OpenBSD has its own SNMP daemon (snmpd
), the only downside is the missing SNMPv3 trap support. First of all, we'll need a configuration file /etc/snmpd.conf
:
listen on udp 192.168.0.100 notify snmpv1 snmpv2c trap community "TEST" trap handle 1.3.6.1.4.1.11.2.14.11.5.1.12.1.5.0.1 "/home/_snmpd/loop.sh" trap handle default "/home/_snmpd/traphandler.sh"SNMP traps are received on the UDP port 162, here
snmpd
only listens on the address 192.168.0.100
. The daemon will handle version 1 and 2c messages. As a "security" feature the community is set to TEST
.
There are two trap handlers:
- A special trap handler
loop.sh
for the OID 1.3.6.1.4.1.11.2.14.11.5.1.12.1.5.0.1, which translates to hpicfBridgeLoopProtectLoopDetectedNotification for an old HP switch. It will be descriped in chapter 3.2. - A default trap handler
traphandler.sh
for all other SNMP traps, which we'll cover in 3.1.
snmpd
:
# snmpd -n -v # rcctl enable snmpd # rcctl start snmpdYou may need to add a filter rule to
/etc/pf.conf
:
pass in quick on $ext_if proto udp to port 162where
$ext_if
is your network interface. Now load the current ruleset:
# pfctl -f /etc/pf.conf
3 trap handler
For our generic trap handler we first need a directory:# mkdir /home/_snmpd # chown _snmpd:_snmpd /home/_snmpd # chmod 700 /home/_snmpdTo write a trap handler, it's a good idea to have a look at the snmpd.conf(5) manpage, quote:
"The invoked command will receive the following information about the trap on standard input, one per line, in this order: the resolved hostname of the host sending the trap, the IP address of the host sending the trap, and any variable bindings contained in the trap (the OID followed by the value, separated by a single space)."The important thing to understand is that
snmpd
calls the handler and the information is passed via standard input.
3.1 default trap handler
Here is a primitive generic trap handler, which handles all traps without a specialized handler (/home/_snmpd/traphandler.sh
):
#!/bin/sh read -r var1 read -r var2 read -r var3 read -r var4 read -r var5 read -r var6 read -r var7 read -r var8 read -r var9 read -r var10 echo "TRAP:" >> /home/_snmpd/trap.log echo "1: $var1" >> /home/_snmpd/trap.log echo "2: $var2" >> /home/_snmpd/trap.log echo "3: $var3" >> /home/_snmpd/trap.log echo "4: $var4" >> /home/_snmpd/trap.log echo "5: $var5" >> /home/_snmpd/trap.log echo "6: $var6" >> /home/_snmpd/trap.log echo "7: $var7" >> /home/_snmpd/trap.log echo "8: $var8" >> /home/_snmpd/trap.log echo "9: $var9" >> /home/_snmpd/trap.log echo "10: $var10" >> /home/_snmpd/trap.log echo >> /home/_snmpd/trap.logDon't forget to make your handler executable:
# chmod 700 traphandler.shYou'll see traps like this in
/home/_snmpd/trap.log
:
TRAP: 1: 192.168.0.10 2: 192.168.0.10 3: iso.org.dod.internet.mgmt.mib_2.system.sysUpTime.0 70034 4: iso.org.dod.internet.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTrap.snmpTrapOID.0 iso.org.dod.internet.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTraps.linkDown 5: iso.org.dod.internet.mgmt.mib_2.interfaces.ifTable.ifEntry.ifIndex.4 4 6: iso.org.dod.internet.mgmt.mib_2.interfaces.ifTable.ifEntry.ifAdminStatus.4 2 7: iso.org.dod.internet.mgmt.mib_2.interfaces.ifTable.ifEntry.ifOperStatus.4 2 8: iso.org.dod.internet.mgmt.mib_2.interfaces.ifTable.ifEntry.ifDescr.4 "4" 9: iso.org.dod.internet.mgmt.mib_2.ifMIB.ifMIBObjects.ifXTable.ifXEntry.ifAlias.4 "" 10:If you don't want
snmpd
to convert the OIDs, use the -N
flag:
# rcctl set snmpd flags -N # rcctl restart snmpd
3.2 loop trap
Now for the special trap handler. The test device is an old HP 2915 switch, which can be configured to send out SNMP traps if a loop is detected. The idea is the once a loop is detected, the loop handler does a SNMP request to the switch to get its location and mails all the information to user@localhost
.
> enable # configure terminal (config)# loop-protection 1-8 (config)# loop-protection trap loop-detected (config)# loop-protection disable-timer 300 (config)# snmp-server community "TEST" restricted (config)# snmp-server location "Room 123" (config)# snmp-server host 192.168.0.5 community TEST trap-level not-info (config)# snmp-server enable (config)# write memoryNow lets have a look at the loop information, which you can get from the generic trap handler of the last chapter:
1: 192.168.0.10 2: 192.168.0.10 3: iso.org.dod.internet.mgmt.mib_2.system.sysUpTime.0 71458 4: iso.org.dod.internet.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTrap.snmpTrapOID.0 iso.org.dod.internet.private.enterprises.hp.2.14.11.5.1.12.1.5.0.1 5: iso.org.dod.internet.mgmt.mib_2.interfaces.ifTable.ifEntry.ifIndex.7 7 6: iso.org.dod.internet.private.enterprises.hp.2.14.11.5.1.12.1.5.2.1.1.4.7 10 7: iso.org.dod.internet.private.enterprises.hp.2.14.11.5.1.12.1.5.2.1.1.5.4 8
Most important are the arguments 1 or 2 and 4, which is the IP address of the switch on which the loop has happend and the switch port on which it was detected.
Here is the loop trap handler/home/_snmpd/loop.sh
:
#!/bin/sh read -r src read -r read -r read -r read -r iface iface=`echo $iface | cut -d ' ' -f 2` location=`snmp get -v 1 -c TEST $src 'sysLocation.0' | cut -d ' ' -f 4` echo "Loop detected!\n\nHost: $src\nInterface: $iface\nLocation: $location" \ | mail -r "snmpd@localhost" -s "Loop detected!" user@localhostFirst we get the switch port, on which the loop was detected. Then there is an SNMP request to the switch for the
sysLocation.0
variable, using the community "TEST
". The last line is for the E-Mail delivery, which of cause only works if smtpd
is running. And don't forget to make the script executable:
# chmod 700 loop.shYou can read your mails using the
mail
command:
From snmpd@localhost Fri Jul 29 13:33:18 2022 Delivered-To: user@localhost From: snmpd@localhost To: user@localhost Subject: Loop detected! Loop detected! Host: 192.168.0.10 Interface: 7 Location: Room 123