LibreNMS 1.50.1 packer.io CentOS image high CPU usage

LibreNMS offers prebuilt OVA VM images using packer.io based on Ubuntu 18 and CentOS 7. If you’ve deployed the CentOS image though, you may be aware of it using an excessive amount of CPU – not an issue present in the Ubuntu image.

A quick look at the system with top will show us php processes with new PIDs spiking the CPU endlessly. Output of ps axf will show the parent process as syslog-ng, whose config has a PHP script defined as a program which it is trying to launch. Turning on debugging in syslog-ng doesn’t return any information on what is happening so when something on an RHEL based system doesn’t make sense, what do you do? Check if SELinux is enforcing and look at your audit logs!

Lo and behold, SELinux is enforcing, and the audit logs are being hammered with denials. Let’s quickly solve this problem. By setting SELinux to permissive we can figure out all the tweaks needed in a module to allow syslog-ng and the PHP process to do what it needs. Keep in mind this is a blunt force way of dealing with the problem. Generally you should take the time to investigate available booleans that will allow the access needed and if the denials are due to labelling issues. My investigations prior to creating a module suggested that the problem would not be solved by either of those, but I am not an SELinux wizard by a long shot.

# setenforce 0
# getenforce
Permissive

Once this is set, check with top that the CPU has calmed down, and then use the audit2allow tool to take a look at what kind of policies would allow the necessary operations. The output should look something like this:

# audit2allow -a


#============= syslogd_t ==============

allow syslogd_t httpd_sys_rw_content_t:dir { getattr search write };
allow syslogd_t httpd_sys_rw_content_t:file { getattr open read };
allow syslogd_t ping_exec_t:file execute;
allow syslogd_t self:process execmem;

We can see the syslogd_t type context has generated four denials related to accessing httpd_sys_rw_content_t directories and files, attempted to ping, and attempted to map an executable. We can now generate a policy module to install. Before tweaking SELinux with new policies, always understand everything you’re allowing! SELinux’s role is compromised if you don’t do your due diligence.

# grep syslogd_t /var/log/audit/audit.log | audit2allow -a -M syslogng_librenms
...
To make this policy package active, execute:

semodule -i syslogng_librenms.pp

# cat syslogng_librenms.pp

module syslogd_t 1.0;

require {
        type syslogd_t;
        type httpd_sys_rw_content_t;
        type ping_exec_t;
        class process execmem;
        class dir { getattr search write };
        class file { execute getattr open read };
}

#============= syslogd_t ==============
allow syslogd_t httpd_sys_rw_content_t:dir { getattr search write };
allow syslogd_t httpd_sys_rw_content_t:file { getattr open read };
allow syslogd_t ping_exec_t:file execute;
allow syslogd_t self:process execmem;
# semodule -i syslogng_librenms.pp

It is a good idea to review the content of the .te before installing to ensure the content is limited to what you expected. Once a module is installed with semodule it will survive reboots.

From here, you can set SELinux to Enforcing and verify that no new denials are logged in your /var/log/audit/audit.log either with tail or one of the more specific SELinux tools.

This is just my out of the box review of issues with the LibreNMS CentOS image and it shows that not enough attention was paid to SELinux to leave it enforcing, it even signals the image probably wasn’t reviewed. With that in mind, I would not be surprised if further issues come up with SELinux. If you choose to deploy this way (I highly recommend keeping SELinux enforcing, especially on a production system), you will have a bit more know how to track down and fix issues.

Leave a Reply

Your email address will not be published. Required fields are marked *