PNP4Nagios is commonly used to add performance graphs to a Nagios installation.
For additional security, SElinux is enabled on the monitoring host. There is no standard SElinux policy for applications like PNP4Nagios, so we need to develop a custom policy. This sounds harder than it actually is:
- Run the software as you normally would (SElinux will interfere, so prepare for errors)
- Extract audit messages and use them to create or update a local SElinux policy for the software
- Repeat until everything works
In this example, I am running Nagios 3.2.3 with PNP4Nagios 0.6.16 on EL6, 64-bit.
After configuring Nagios and PNP4Nagios integration in Synchronous Mode (see documentation), I noticed that PNP4Nagios is not logging any performance data to /var/lib/pnp4nagios/.
Normally, PNP4Nagios should automatically create directories and files under /var/lib/pnp4nagios as performance data is received by Nagios. This smells of an SElinux issue, so check /var/log/audit/audit.log for suspicious messages. Sure enough, several audit messages have been logged. They look like this:
type=AVC msg=audit(1329129875.344:198212): avc: denied { getattr } for pid=26692 comm="process_perfdat" \ path="/var/lib/pnp4nagios/orac/Root_Partition.xml.26692" dev=dm-0 ino=1444378 \ scontext=unconfined_u:system_r:nagios_t:s0 tcontext=unconfined_u:object_r:var_lib_t:s0 tclass=file type=SYSCALL msg=audit(1329129875.344:198212): arch=c000003e syscall=5 success=no exit=-13 a0=3 a1=25440a0 \ a2=25440a0 a3=0 items=0 ppid=26691 pid=26692 auid=0 uid=498 gid=498 euid=498 suid=498 fsuid=498 egid=498 \ sgid=498 fsgid=498 tty=(none) ses=14942 comm="process_perfdat" exe="/usr/bin/perl" subj=unconfined_u:system_r:nagios_t:s0 key=(null)
Create a policy
You can run the “audit2allow” command (part of the policycoreutils-python RPM) to display suggested policy improvements based on the audit log:
audit2allow -a
The output can be saved in a file, for example local_nagios.te:
grep nagios_t /var/log/audit/audit.log | audit2allow -l -v -m local_nagios > local_nagios.te
This generates an output file suitable for compiling into a custom SElinux module.
Note: ALWAYS prefix the policy name with something like local_ to prevent overwriting system policies!
Test and refine the policy
Compile and load the SElinux policy module:
checkmodule -M -m -o local_nagios.mod local_nagios.te semodule_package -o local_nagios.pp -m local_nagios.mod semodule -v -i local_nagios.pp
Note: The above tools can be found in the checkpolicy and policycoreutils RPMs.
Re-run the software and check for SElinux audit messages. New issues can be captured and translated into a new policy:
grep nagios_t /var/log/audit/audit.log | audit2allow -l -v -m local_nagios > local_nagios.te_NEW
Merge the new results (in local_nagios.te_NEW) with your existing policy (in local_nagios.te). Compile and reload the module.
Lather, rinse, repeat ;-)
Results
After some iterations, your local_nagios.te file will look something like this:
module local_nagios 1.0; require { type nagios_t; type var_log_t; type var_lib_t; class dir { write create add_name remove_name }; class file { create getattr ioctl lock open read rename unlink write }; } #============= nagios_t ============== allow nagios_t var_lib_t:dir { add_name create remove_name write }; allow nagios_t var_lib_t:file { create getattr ioctl lock open read rename unlink write }; allow nagios_t var_log_t:file { read rename unlink };
If all is well, the audit.log should not show any new messages for nagios_t:
clear;tail -f /var/log/audit/audit.log |grep nagios_t
Note: The new SElinux policy will survive reboots; it is automatically copied to /etc/selinux/targeted/modules/active/modules/local_nagios.pp.
Enjoy!