Deploying LibreNMS With SELinux

During an infrastructure upgrade we decided to migrate from Observium to LibreNMS for our time-series graphs. That system is one of the last vestiges of the Ubuntu standardization and will be one of the biggest wins. Since it was one of the first forays into Linux for the team some of the build decisions were less than enterprise; for instance this system runs Ubuntu 12.04 Desktop. Part of the replacement includes migrating to CentOS and, relevant to this post, enabling SELinux by default in enforcing mode.

The LibreNMS project does a lot of things right, but one thing that's missing is a well developed SELinux policy out of the box. For the purposes of building out this policy we made the following assumptions:

  • The application is installed in /opt/librenms
  • We are using Apache httpd as the web server
  • We are using MariaDB/MySQL as the database engine
  • We use an LDAP/AD back-end for user authentication

Building the policy itself was fairly easy. All we needed to explicitly call out was that the httpd process needed to make SNMP and LDAP connections. The LDAP connection is for authentication, and SNMP for...well...this is a monitoring server....

module librenms 1.0;

require {
    type ldap_port_t;
    type snmp_port_t;
    type httpd_t;
    class tcp_socket name_connect;

#============= httpd_t ==============

#!!!! This avc can be allowed using one of the these booleans:
#     httpd_can_connect_ldap, nis_enabled, authlogin_nsswitch_use_ldap, httpd_can_network_connect
allow httpd_t ldap_port_t:tcp_socket name_connect;

#!!!! This avc can be allowed using one of the these booleans:
#     nis_enabled, httpd_can_network_connect
allow httpd_t snmp_port_t:tcp_socket name_connect;

Next came the more interesting part. By default the LibreNMS application itself logs to /opt/librenms/logs, however this is well outside of the web root and would be blocked. To remove the bock we need to set the proper security contexts on the log directory. In order to make it a permanent change we need to create a file context entry using the command:

semanage fcontext -a -t httpd_sys_rw_content_t '/opt/librenms/logs(/.*)?'

The last step is fixing the cleanup process. Without making any other changes the application can create and update rrd logs for all of the devices, however decommissioning causes an issue. When we try to delete the rrd directory as part of a server decommissioning the deletion fails with an access denied message. We also need to define the file contexts such that the httpd process can delete the files.

semanage fcontext -a -t httpd_sys_rw_content_t '/opt/librenms/rrd(/.*)?'

Finally we can go actually set the contexts on all those files:

restorecon -R -v /opt/librenms/rrd /opt/librenms/logs

At this point we were able to add, delete, and update hosts; poll and report on polling; hell even add some custom MIBs for graphs that aren't shipped out of the box.