Contributed by rueda on from the agentx my PDUs dept.
We are delighted to have received a report on
Martijn van Duren (
Coming to Bad Liebenzell for the 3rd year in a row I knew what to expect, but the scenery still continues to amaze me. Driving through the black forest was a nice little escape before plunging back into the SNMP world.
One of the biggest misconceptions I've seen floating around and one of my biggest irks with
snmpd(8)was its privilege separation situation. While true that
snmpd(8)always had multiple processes it was never used to any meaningful degree. The engine process (
snmpe) handled everything snmp related: Handling packets/connections, de-/encoding the BER, handling authentication, finding the correct object and retrieving the data from the proper source (usually the kernel). Because some metrics fell outside the scope of
pledgeit also ran without the
pledgeseat belt. The engine however does run inside a
chroot, this is where the other (parent) process comes into play. When a trap (notification) is received and covered by "trap handle" it's forwarded to the parent process, which then executes the "command".
During k2k20 I committed
libagentxwhich was the first piece of the puzzle to making privilege separation between the handling of the (network facing) packets and the handling of the metrics possible. The other big piece was (re-)adding
snmpd. Because the original code was build around the idea that all metrics originate from within the engine certain assumptions in the code were made that didn't quite fit into an
- The code assumed objects instead of regions. Since objects can't overlap it's easy to just walk the edge of the tree, which also comes with a great speed benefit.
Agentxhowever requires regions, which can happily overlap.
- The code worked sequential, meaning that every
varbindwould wait for its value as soon as it was processed. This could cause the entire
snmpdto hang if one backend were to hang.
- The code wasn't really set up to handle inserting and removing of new regions/objects.
During h2k21 I wrote support for the new application layer, which now handles the PDUs and is designed to handle the above requirements. This came with an legacy handler, which calls out to the old code so we don't lose any functionality while transitioning.
During r2k22 I polished up the
agentxmaster code which I wrote in tandem with the new application layer. This code mostly translates between the
agentxline format and the
application.cAPI, which does all the heavy lifting. This code got committed a week before the g2k22.
With all the core pieces for
agentxbased communication in place it was only a matter of landing on a design on how to set up the backends, which was my main goal for g2k22. I already had the idea that the new backend(s) should function as a standalone binary, because I don't want to link
snmpd. From here I decided on creating a dedicated
libexec/snmpddirectory, inspired by
libexec/smtpd. For now all binaries inside this directory are being executed and the
snmpdside of the
socketpairis registered inside the
agentxsubsystem with some additional flags, making sure that the regions registered by these backends are exclusively owned and can't be overwritten by rogue dynamic backends.
I talked over the design with
claudio@and got committed only a few days later, allowing
snmpdto finally enter the realm of OpenBSD's privsepped daemons, making the engine process
stdio recvfd inet unix" for now, hoping that it can be locked down even further in the future.
(Comments are closed)