Contributed by jason on from the .22.214.171.124.4.1.2021.11.9.0 dept.
Reyk Floeter writes in to tell us about his work on a new SNMP implementation...
I just imported snmpd(8) and snmpctl(8), an initial attempt to implement a new SNMP daemon for OpenBSD. SNMP is the "Simple Network Management Protocol" and it is still very commonly used in corporate networks, by network vendors, and in network management systems (NMS).
SNMP is very essential for me since I'm using it at work; our security appliances based on OpenBSD need to integrate into various SNMP scenarios. We had to use net-snmp for this; the BSD license is good but the code is very bad and full of ancient cruft and portability glue. Then there were many problems with the net-snmp port in OpenBSD, people reported 90% CPU usage on -misc, crashes, bugs, ...it was just a pain.
So I decided to have a look at SNMP to implement something new. When we don't like the existing alternatives or ports, we tend to re-implement it in OpenBSD, right? Having a new snmpd(8) using privilege separation, the imsg framework from ospfd/bgpd, knf, "security in mind", and a nice control program like snmpctl(8) would be really nice and solve some of our problems. And I knew that claudio@ already started working on a little ASN.1 BER implementation for another project; this was the perfect base for handling the annoying BER-encoding of SNMP messages.
I talked to some people during OpenCON about my idea and the initial code that I was working on. The expected reaction was always like "This is nice, but I don't like SNMP". SNMP is a necessary evil. People are upset and happy at the same time; will it be possible to implement a sane SNMP? Will it be possible to make it secure?
The code is still in a very early stage, snmpctl(8) is mostly a stub without any functionality, and the implemented MIBs are limited to (most of) the MIB-2, SNMPv3-MIB, and the IF-MIB. I plan to implement the IP-MIB, TCP-MIB, UDP-MIB, and BRIDGE-MIB next and continue with working on the daemon's infrastructure. There needs to be a way to talk to other daemons in OpenBSD without using SNMP BER messages: IMSG. snmpd(8) may connect to the daemons, query some IMSG information, and provide the SNMP MIBs for the outside world. I also plan to export some useful information like sensor status in an OpenBSD-specific MIB.
I DON'T want to provide a plug-in or module API, people can use net-snmp if they need a hyper-extensible codebase.
The daemon is currently based on the SNMPv2/3 RFCs, supporting SNMPv1/2 messages and a very simple community-based security model (SNMPv2c). The User-based Security Model (USM) will be added later, but the complexity of the new SNMPv3 standards is a little bit scary; they turned a simple protocol into a mess of layers, modules, and abstractions. There is also a very interesting draft about a SSH-based security model for SNMP (draft-ietf-isms-secshell), but it is defined by Cizzco and Huawai...
Sure, I'm looking for volunteers to test and to contribute to snmpd(8), have a look at the src/usr.sbin/snmpd/README file and the code in the OpenBSD source tree. It is not enabled in the builds yet and it will take some time before we are satisfied enough to enable it. Again, please don't propose any useless features XYZ, it is good to have net-snmp for all the additional foo.
For example, I get the following output when I query the new snmpd(8) with the snmpwalk tool from net-snmp:# client: snmpwalk from net-snmp, server: new OpenBSD snmpd(8) sysDescr = STRING: OpenBSD john.hq.vantronix.net 4.2 GENERIC.MP#6 amd64 sysObjectID = OID: enterprises.267126.96.36.199.42 sysUpTime = Timeticks: (2472) 0:00:24.72 sysContact = STRING: firstname.lastname@example.org sysName = STRING: john.hq.vantronix.net sysLocation = STRING: sysServices = INTEGER: 74 sysORLastChange = Timeticks: (0) 0:00:00.00 sysORIndex.1 = INTEGER: 1 sysORIndex.2 = INTEGER: 2 sysORIndex.3 = INTEGER: 3 sysORID.1 = OID: mib-2 sysORID.2 = OID: snmp sysORID.3 = OID: ifMIB sysORDescr.1 = STRING: iso.org.dod.internet.mgmt.mib-2 sysORDescr.2 = STRING: iso.org.dod.internet.mgmt.mib-2.snmp sysORDescr.3 = STRING: iso.org.dod.internet.mgmt.mib-2.ifMIB sysORUpTime.1 = Timeticks: (0) 0:00:00.00 sysORUpTime.2 = Timeticks: (0) 0:00:00.00 sysORUpTime.3 = Timeticks: (0) 0:00:00.00 ifNumber = INTEGER: 4 ifIndex.1 = INTEGER: 1 ifIndex.2 = INTEGER: 2 ifIndex.3 = INTEGER: 3 ifIndex.4 = INTEGER: 4 ifDescr.1 = STRING: em0 ifDescr.2 = STRING: ath0 ifDescr.3 = STRING: enc0 ifDescr.4 = STRING: lo0 ifType.1 = INTEGER: ethernetCsmacd(6) ifType.2 = INTEGER: ethernetCsmacd(6) ifType.3 = INTEGER: other(1) ifType.4 = INTEGER: softwareLoopback(24) ifMtu.1 = INTEGER: 1500 ifMtu.2 = INTEGER: 1500 ifMtu.3 = INTEGER: 1536 ifMtu.4 = INTEGER: 33168 ifSpeed.1 = Gauge32: 1000000000 ifSpeed.2 = Gauge32: 54000000 ifSpeed.3 = Gauge32: 0 ifSpeed.4 = Gauge32: 0 ifPhysAddress.1 = STRING: 0:1a:6b:36:2e:5 ifPhysAddress.2 = STRING: 0:16:cf:ab:4c:97 ifPhysAddress.3 = STRING: ifPhysAddress.4 = STRING: ifAdminStatus.1 = INTEGER: up(1) ifAdminStatus.2 = INTEGER: down(2) ifAdminStatus.3 = INTEGER: down(2) ifAdminStatus.4 = INTEGER: up(1) ifOperStatus.1 = INTEGER: up(1) ifOperStatus.2 = INTEGER: down(2) ifOperStatus.3 = INTEGER: down(2) ifOperStatus.4 = INTEGER: unknown(4) ifLastChange.1 = Timeticks: (2474) 0:00:24.74 ifLastChange.2 = Timeticks: (2474) 0:00:24.74 ifLastChange.3 = Timeticks: (2474) 0:00:24.74 ifLastChange.4 = Timeticks: (2474) 0:00:24.74 ifInOctets.1 = Counter32: 28675019 ifInOctets.2 = Counter32: 0 ifInOctets.3 = Counter32: 0 ifInOctets.4 = Counter32: 395717 ifInUcastPkts.1 = Counter32: 85059 ifInUcastPkts.2 = Counter32: 0 ifInUcastPkts.3 = Counter32: 0 ifInUcastPkts.4 = Counter32: 2473 ifInNUcastPkts.1 = Counter32: 267 ifInNUcastPkts.2 = Counter32: 0 ifInNUcastPkts.3 = Counter32: 0 ifInNUcastPkts.4 = Counter32: 0 ifInDiscards.1 = Counter32: 0 ifInDiscards.2 = Counter32: 0 ifInDiscards.3 = Counter32: 0 ifInDiscards.4 = Counter32: 0 ifInErrors.1 = Counter32: 0 ifInErrors.2 = Counter32: 0 ifInErrors.3 = Counter32: 0 ifInErrors.4 = Counter32: 0 ifInUnknownProtos.1 = Counter32: 0 ifInUnknownProtos.2 = Counter32: 0 ifInUnknownProtos.3 = Counter32: 0 ifInUnknownProtos.4 = Counter32: 0 ifOutOctets.1 = Counter32: 8354604 ifOutOctets.2 = Counter32: 0 ifOutOctets.3 = Counter32: 0 ifOutOctets.4 = Counter32: 400397 ifOutUcastPkts.1 = Counter32: 60000 ifOutUcastPkts.2 = Counter32: 0 ifOutUcastPkts.3 = Counter32: 0 ifOutUcastPkts.4 = Counter32: 2521 ifOutNUcastPkts.1 = Counter32: 0 ifOutNUcastPkts.2 = Counter32: 0 ifOutNUcastPkts.3 = Counter32: 0 ifOutNUcastPkts.4 = Counter32: 0 ifOutDiscards.1 = Counter32: 0 ifOutDiscards.2 = Counter32: 0 ifOutDiscards.3 = Counter32: 0 ifOutDiscards.4 = Counter32: 0 ifOutErrors.1 = Counter32: 0 ifOutErrors.2 = Counter32: 0 ifOutErrors.3 = Counter32: 0 ifOutErrors.4 = Counter32: 0 ifOutQLen.1 = Gauge32: 0 ifOutQLen.2 = Gauge32: 0 ifOutQLen.3 = Gauge32: 0 ifOutQLen.4 = Gauge32: 0 ifSpecific.1 = OID: zeroDotZero ifSpecific.2 = OID: zeroDotZero ifSpecific.3 = OID: zeroDotZero ifSpecific.4 = OID: zeroDotZero snmpInPkts = Counter32: 338 snmpOutPkts = Counter32: 335 snmpInBadVersions = Counter32: 0 snmpInBadCommunityNames = Counter32: 3 snmpInBadCommunityUses = Counter32: 0 snmpInASNParseErrs = Counter32: 0 snmpInTooBigs = Counter32: 0 snmpInNoSuchNames = Counter32: 0 snmpInBadValues = Counter32: 0 snmpInReadOnlys = Counter32: 0 snmpInGenErrs = Counter32: 344 snmpInTotalReqVars = Counter32: 0 snmpInTotalSetVars = Counter32: 0 snmpInGetRequests = Counter32: 0 snmpInGetNexts = Counter32: 352 snmpInSetRequests = Counter32: 0 snmpInGetResponses = Counter32: 0 snmpInTraps = Counter32: 0 snmpOutTooBigs = Counter32: 0 snmpOutNoSuchNames = Counter32: 0 snmpOutBadValues = Counter32: 0 snmpOutGenErrs = Counter32: 0 snmpOutGetRequests = Counter32: 0 snmpOutGetNexts = Counter32: 0 snmpOutSetRequests = Counter32: 0 snmpOutGetResponses = Counter32: 0 snmpOutTraps = Counter32: 0 snmpEnableAuthenTraps = INTEGER: disabled(2) snmpSilentDrops = Count
(Comments are closed)