Nagios and SELinux

From MyWiki

(Difference between revisions)
Jump to: navigation, search
(Edited with more description)
(added few final notes)
 
(2 intermediate revisions not shown)
Line 26: Line 26:
semodule -i NagiosRule.pp
semodule -i NagiosRule.pp
 +
</pre>
-
[root@master tmp]# semodule -i NagiosRule.pp
+
What I had as the result of the command, were two files <tt>NagiosRule.pp</tt> and <tt>NagiosRule.te</tt>. The .te file looked like this:
 +
<pre>
 +
module NagiosRule 1.0;
 +
 
 +
require {
 +
type httpd_sys_content_t;
 +
type httpd_sys_script_t;
 +
class fifo_file getattr;
 +
}
 +
 
 +
#============= httpd_sys_script_t ==============
 +
allow httpd_sys_script_t httpd_sys_content_t:fifo_file getattr;
</pre>
</pre>
 +
 +
I did as it said and loaded the policy file:
 +
 +
[root@master tmp]# semodule -i NagiosRule.pp
Tried web UI again and still the same error, so I repeated the dance once again and saw more in the log:
Tried web UI again and still the same error, so I repeated the dance once again and saw more in the log:
Line 56: Line 72:
semodule -i NagiosRule2.pp
semodule -i NagiosRule2.pp
 +
</pre>
 +
 +
And the .te file this time had:
 +
<pre>
 +
module NagiosRule2 1.0;
 +
 +
require {
 +
type httpd_sys_content_t;
 +
type httpd_sys_script_t;
 +
type ping_t;
 +
class file { read write append };
 +
class fifo_file write;
 +
}
 +
 +
#============= httpd_sys_script_t ==============
 +
allow httpd_sys_script_t httpd_sys_content_t:fifo_file write;
-
[root@master tmp]# semodule -i NagiosRule2.pp
+
#============= ping_t ==============
 +
allow ping_t httpd_sys_content_t:file { read write append };
</pre>
</pre>
 +
 +
Now, if you look at the first .te file above and this one, you see that it make perfect sense why the first policy alone didn't work out the miracle. It merely allowed getaddr through, but not the actual write to the file. So, I loaded this new policy as well:
 +
 +
[root@master tmp]# semodule -i NagiosRule2.pp
And now the UI worked fine. No errors.
And now the UI worked fine. No errors.
Now, I decided to consult "SELinux by example" book, to see if there is more elegant or proper way of doing this and it says that audit2allow is not the great way to fix policies, so I will be working on this more and update the article.
Now, I decided to consult "SELinux by example" book, to see if there is more elegant or proper way of doing this and it says that audit2allow is not the great way to fix policies, so I will be working on this more and update the article.
 +
 +
One thing to watch out for is what exactly <tt>audit2allow</tt> is advising you to allow. Experienced people tell that in some cases you can open more door than you wanted to, if you blindly follow the tool's suggestions.
 +
 +
Some interesting SELinux examples can be found on Jan-Frode Myklebust site [http://tanso.net/selinux/ here].
 +
On RedHat you want to install <tt>selinux-policy-devel</tt> package to be able to develop your own policies. You will find the policy generating tool in <tt>/usr/share/selinux/devel/</tt>.

Current revision as of 14:41, 2 April 2010

Was getting this popular message from Nagios when I was trying to schedule a downtime for systems via web UI:

"Error: Could not stat() command file '/usr/local/nagios/var/rw/nagios.cmd'!"

The problem was (of course) SELinux :-). I hate fixing it by turning off 'Enforcing' mode, so I searched. While searching, came across this blog post that showed a nice way to track down the problem

So, here is what I did based on the above mentioned post.

[root@master ~]# tail -f /var/log/audit/audit.log

Then tried to schedule downtime via web UI and the following popped-up in the log:

type=AVC msg=audit(1270138956.195:1317143): avc:  denied  { getattr } for  pid=27998 comm="cmd.cgi" path="/usr/local/nagios/var/rw/nagios.cmd" dev=dm-0 ino=2755298 scontext=user_u:system_r:httpd_sys_script_t:s0 tcontext=user_u:object_r:httpd_sys_content_t:s0 tclass=fifo_file
type=SYSCALL msg=audit(1270138956.195:1317143): arch=c000003e syscall=4 success=no exit=-13 a0=63a920 a1=7fff110124e0 a2=7fff110124e0 a3=1 items=0 ppid=2405 pid=27998 auid=501 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=37366 comm="cmd.cgi" exe="/usr/local/nagios/sbin/cmd.cgi" subj=user_u:system_r:httpd_sys_script_t:s0 key=(null)

Then I created a file to copy&paste the snippet to:

[root@master ~]# vi /tmp/audit.log
[root@master ~]# cd /tmp
[root@master tmp]# audit2allow -M NagiosRule < audit.log 
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i NagiosRule.pp

What I had as the result of the command, were two files NagiosRule.pp and NagiosRule.te. The .te file looked like this:

module NagiosRule 1.0;

require {
	type httpd_sys_content_t;
	type httpd_sys_script_t;
	class fifo_file getattr;
}

#============= httpd_sys_script_t ==============
allow httpd_sys_script_t httpd_sys_content_t:fifo_file getattr;

I did as it said and loaded the policy file:

[root@master tmp]# semodule -i NagiosRule.pp

Tried web UI again and still the same error, so I repeated the dance once again and saw more in the log:

[root@master tmp]# tail -f /var/log/audit/audit.log

type=AVC msg=audit(1270139184.317:1317165): avc:  denied  { append } for  pid=28190 comm="ping" path="/usr/local/nagios/var/host-perfdata" dev=dm-0 ino=2752540 scontext=user_u:system_r:ping_t:s0 tcontext=user_u:object_r:httpd_sys_content_t:s0 tclass=file
type=AVC msg=audit(1270139184.317:1317165): avc:  denied  { append } for  pid=28190 comm="ping" path="/usr/local/nagios/var/service-perfdata" dev=dm-0 ino=2752541 scontext=user_u:system_r:ping_t:s0 tcontext=user_u:object_r:httpd_sys_content_t:s0 tclass=file
type=AVC msg=audit(1270139184.317:1317165): avc:  denied  { read write } for  pid=28190 comm="ping" path="/usr/local/nagios/var/spool/checkresults/checkZsKj5r" dev=dm-0 ino=2755492 scontext=user_u:system_r:ping_t:s0 tcontext=user_u:object_r:httpd_sys_content_t:s0 tclass=file
type=SYSCALL msg=audit(1270139184.317:1317165): arch=c000003e syscall=59 success=yes exit=0 a0=1320e2a0 a1=1320e320 a2=7fffb89bb6f0 a3=0 items=0 ppid=28189 pid=28190 auid=501 uid=513 gid=513 euid=0 suid=0 fsuid=0 egid=513 sgid=513 fsgid=513 tty=(none) ses=40405 comm="ping" exe="/bin/ping" subj=user_u:system_r:ping_t:s0 key=(null)
type=AVC msg=audit(1270139188.909:1317166): avc:  denied  { write } for  pid=28195 comm="cmd.cgi" name="nagios.cmd" dev=dm-0 ino=2755298 scontext=user_u:system_r:httpd_sys_script_t:s0 tcontext=user_u:object_r:httpd_sys_content_t:s0 tclass=fifo_file
type=SYSCALL msg=audit(1270139188.909:1317166): arch=c000003e syscall=2 success=no exit=-13 a0=63a920 a1=241 a2=1b6 a3=241 items=0 ppid=2400 pid=28195 auid=501 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=37366 comm="cmd.cgi" exe="/usr/local/nagios/sbin/cmd.cgi" subj=user_u:system_r:httpd_sys_script_t:s0 key=(null)
type=AVC msg=audit(1270139204.042:1317167): avc:  denied  { append } for  pid=28209 comm="ping" path="/usr/local/nagios/var/host-perfdata" dev=dm-0 ino=2752540 scontext=user_u:system_r:ping_t:s0 tcontext=user_u:object_r:httpd_sys_content_t:s0 tclass=file
type=AVC msg=audit(1270139204.042:1317167): avc:  denied  { append } for  pid=28209 comm="ping" path="/usr/local/nagios/var/service-perfdata" dev=dm-0 ino=2752541 scontext=user_u:system_r:ping_t:s0 tcontext=user_u:object_r:httpd_sys_content_t:s0 tclass=file
type=AVC msg=audit(1270139204.042:1317167): avc:  denied  { read write } for  pid=28209 comm="ping" path="/usr/local/nagios/var/spool/checkresults/checkFCUK8v" dev=dm-0 ino=2755483 scontext=user_u:system_r:ping_t:s0 tcontext=user_u:object_r:httpd_sys_content_t:s0 tclass=file
type=SYSCALL msg=audit(1270139204.042:1317167): arch=c000003e syscall=59 success=yes exit=0 a0=12882a0 a1=1288330 a2=7fff5bb18830 a3=0 items=0 ppid=28208 pid=28209 auid=501 uid=513 gid=513 euid=0 suid=0 fsuid=0 egid=513 sgid=513 fsgid=513 tty=(none) ses=40405 comm="ping" exe="/bin/ping" subj=user_u:system_r:ping_t:s0 key=(null)

Created new file to copy&paste the new bits into:

[root@master tmp]# vi audit2.log 
[root@master tmp]# audit2allow -M NagiosRule2 < audit2.log 
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i NagiosRule2.pp

And the .te file this time had:

module NagiosRule2 1.0;

require {
	type httpd_sys_content_t;
	type httpd_sys_script_t;
	type ping_t;
	class file { read write append };
	class fifo_file write;
}

#============= httpd_sys_script_t ==============
allow httpd_sys_script_t httpd_sys_content_t:fifo_file write;

#============= ping_t ==============
allow ping_t httpd_sys_content_t:file { read write append };

Now, if you look at the first .te file above and this one, you see that it make perfect sense why the first policy alone didn't work out the miracle. It merely allowed getaddr through, but not the actual write to the file. So, I loaded this new policy as well:

[root@master tmp]# semodule -i NagiosRule2.pp

And now the UI worked fine. No errors.

Now, I decided to consult "SELinux by example" book, to see if there is more elegant or proper way of doing this and it says that audit2allow is not the great way to fix policies, so I will be working on this more and update the article.

One thing to watch out for is what exactly audit2allow is advising you to allow. Experienced people tell that in some cases you can open more door than you wanted to, if you blindly follow the tool's suggestions.

Some interesting SELinux examples can be found on Jan-Frode Myklebust site here. On RedHat you want to install selinux-policy-devel package to be able to develop your own policies. You will find the policy generating tool in /usr/share/selinux/devel/.

Personal tools