Table of Contents

PHP RFC: SNMP improvements for encryption protocols, mib reset, and controlling output

Introduction

This RFC proposes to improve the functionality of the SNMP extension in one or more of the following ways:

  1. Increase the number of SNMPv3 security protocols supported
  2. Allow the SNMP MIB to be reset
  3. Implement more MIB parsing and value output controls

Proposal

There are 3 change being proposed:

Increase the number of SNMPv3 security protocols supported

The NET-SNMP library can be compiled with support for AES192, AES192C, AES256, and AES256C as valid options for the SNMPv3 security protocol. I propose that we make these valid options for PHP if the underlying library supports these draft RFC protocols.

Allow the SNMP MIB to be reset

The SNMP MIB tree is a global variable within the net-snmp library. There is currently no way to reset the MIB tree once a MIB has been loaded using snmp_read_mib(), which can cause issues if you need to run 2 queries in the same process where a vendor has re-used the same OID in different MIBs (this should never happen, but it does).

In addition to the above, the NET-SNMP library will auto-load MIBs if it is given a fully qualified OID (using MIB::object), but there is no way to alter the list of directories to search in PHP after the php-snmp module has initialised.

The proposal is to add a new function called snmp_init_mib() that takes a colon separated list of directories to use when trying to auto-load MIB files. This function will re-initialise the MIB tree and also set the directory search to the supplied value (or system default if no value is supplied).

A function has also been added to reset the MIB tree in between FPM requests. This stops the MIB tree from being leaked between requests. A global integer has been added to make sure we only re-initialise if the MIB directories get changed at any point or if a MIB is explicitly loaded. This is to avoid a memory leak in the PHP-SNMP library during re-initialisation for code that does not explicitly use the SNMP library. It may be worth also marking the MIB tree as dirty when a SNMP command is run, because these can auto-load MIBs.

Examples

Reset MIB tree, using a colon separated list of directories to search for the MIB, then reset back to default.

<?php
 
// Clear MIB tree and then issue a GET request which will search for MIB in the supplied directories
snmp_init_mib("/path/to/mibs:/path/to/more_mibs");
$results = snmp2_get("hostname", "community", "MIB::object");
 
// Clear MIB tree and reset MIB search directory to defaults
snmp_init_mib();
 
?>

Implement more MIB parsing and value output controls

While trying to use the php-snmp module to replace getting output from external SNMP commands in the LibreNMS project, I discovered that the required output is not always available.

The proposal is to add the following functions to allow as many output controls as possible that are supported by the net-snmp library:

The output options have also been added as properties of the SNMP object so they can be controlled on a per-request basis. Since the MIB tree is a global in the library, it does not make sense to attach the mib option to the object in any way.

The MIB parsing options allows php-snmp to parse MIBs that may not comply strictly to the standard, but are otherwise able to be parsed.

The string output format option allows the NET-SNMP library to be told how to display strings that it does not get explicit information on how to display.

I believe I have found all the boolean output options supported by the NET-SNMP library.

All 3 functions have ENUMs to control which setting we want to use. I think we should document the mapping between the ENUM and the net-snmp command-line option.

A function has been added to save and restore the output and MIB parsing options between requests because these are stored in global variables in the net-snmp library, and as a result they survive across FPM requests. I have specifically chosen to save and restore because some of these settings may be configured in the global snmp.conf file, and as a result are not necessarily false by default on all systems.

MIB Parsing Example

Allow parsing of MIBs with underscores:

<?php
 
snmp_set_mib_option(SNMP_MIB_ALLOW_UNDERSCORES, true);
snmp_read_mib("/path/to/mib_with_unserscores");
 
?>

String output example

Set the string output format to always use ASCII for unknown strings

<?php
 
// For snmp functions
snmp_set_string_output_format(SNMP_STRING_OUTPUT_ASCII, true);
 
// Using the Object
$snmp = new SNMP(...);
$snmp->string_output_format = SNMP_STRING_OUTPUT_ASCII;
 
?>

Output format example

Set the output format to use the extended index and not to print units

<?php
 
// For snmp functions
snmp_set_output_format(SNMP_OUTPUT_EXTENDED_INDEX, true);
snmp_set_output_format(SNMP_OUTPUT_DONT_PRINT_UNITS, true);
 
// Using the Object
$snmp = new SNMP(...);
$snmp->extended_index = true;
$snmp->dont_print_units = true;
 
?>

Backward Incompatible Changes

None - Only new functions have been added

Proposed PHP Version(s)

Next stable release for all currently supported PHP versions.

RFC Impact

If systems are running SNMP queries from within FPM processes, the FPM process will leak about 5k per requests until their libsnmp has been patched with https://github.com/net-snmp/net-snmp/pull/1073

The code affects the SNMP module, and no expected impact since changes are all new functions or adding more options to existing ones.

Open Issues

To be added here if needed....

Voting Choices

Increase the number of SNMPv3 security protocols supported
Real name Yes No Abstain
Final result: 0 0 0
This poll has been closed.
Allow the SNMP MIB to be reset
Real name Yes No Abstain
Final result: 0 0 0
This poll has been closed.
Implement more MIB parsing and value output controls
Real name Yes No Abstain
Final result: 0 0 0
This poll has been closed.

Patches and Tests

Implementation

References

Rejected Features

Changelog