Linux by Trial and Error

A repository of the things I learn about Linux

The Joys of SELinux

For the past couple of months now, I’ve been trying to learn more about SELinux. On about half of the servers that I have inherited through my current position, SELinux is set up and set to Enforcing. On the other half, it is set to Permissive. There are only a couple that have it disabled entirely (I did say “about” half.)

Because so many of my servers are in Permissive mode, much of my time is spent scouring through the audit.log file and looking at AVC denial messages. To do this, I’ve been doing the following:

# ausearch -m avc -ts yesterday

This gives me a list of every AVC denial message since 12:00:01am the previous day. The reason I’m doing ‘yesterday’ rather than ‘today’ is because ‘today’ only gets me the denials from 12:00:01am on the day it’s run. If I run that command at 9:00am, I’m never going to see any denial messages between 9:00am and midnight. That’s a pretty good chunk of time to ignore.

As you might imagine, I’ve been spending a lot of time with Google lately. Unfortunately, what I have found has not been supremely helpful. I see a lot of hits about SELinux and how to create custom policies and how to use tools like ausearch, audit2why, audit2allow, semanage, sesearch, restorecon and all that. But there is something that is very much lacking in what I am finding.

When facing a particular AVC denial message, the question I have not found the answer to is, “Should I allow this to happen?” In other words, I know that I can do something like this:

# ausearch -m avc -ts yesterday | grep ifconfig_t | audit2allow -a -M local

# semodule -i local.pp

These commands will help me eliminate the AVC denial messages so that they don’t get denied any more. That’s great, and all. But the problem is, I want to know whether or not ifconfig_t should be trying to do whatever is being denied.

Now, it seems to me that we are, to a degree, stepping outside the realm of SELinux strictly speaking. SELinux doesn’t really “care” what sorts of custom policies you add to your system. If you add them, it will be enforced as you have specified. So, how do you answer the question of whether or not you should add a particular custom policy?

Currently, the servers we are running are RHEL5, so the policies for distros such as RHEL6 and the latest Fedora are going to contain more up-to-date information. Since I don’t actually have a RHEL6 box, I’ve done what I hope is the next best thing. I now have a Fedora 17 VM on my desktop (which runs Centos 6.2….so that might not be far off, either).

Now, what I can do is take certain AVC denial messages and run them through audit2allow (like I showed above) and get what the policy would be. In the case of one of the messages I was looking at, it was:

allow ifconfig_t initrc_t:tcp_socket { read write };

Next, I ran the following command to find out if there are any policies that reference this. So, I would run:

# sesearch –auditallow -s ifconfig_t -t initrc_t -c tcp_socket

# sesearch –dontaudit -s ifconfig_t -t initrc_t -c tcp_socket

The first didn’t return anything, but the second showed me a dontaudit rule. Since there is an existing dontaudit rule for these contexts in the standard policy, I figured it was safe to assume that ifconfig_t should have read/write access to tcp_sockets with a context of initrc_t.

The next problem was how to make the custom policy to implement the dontaudit rule since that obviously was not part of the latest policy settings on my RHEL5 servers.

Once again, it was back to Google. Once again, I found a whole lot of information that didn’t seem to help. I found lots of stuff on turning dontaudit on and off (an option that, thanks to Murphy, was not available in my RHEL5 implementation) and lots of information showing examples of dontaudit entries. But I was not finding anything about how to create a custom dontaudit rule. (There’s actually more to it, but I don’t want this post getting too long).

There was also some hits on how to compile a .te file using the ‘make’ command and such, but that just wasn’t working for me. I finally found something that might help, so I decided to give it a try and, sure enough, it looks like it worked.

So, here is what I did. First, I let audit2allow build both my .te and .pp files:

# ausearch -m avc -ts yesterday | grep ifconfig_t | grep initrc_t | audit2allow -a -M local

Next, I deleted the .pp file:

# rm local.pp

Then I edited the local.te file with vim and changed the “allow” to “dontaudit” and saved the file. Now, I had a .te file with the rule that I wanted to implement, but I need the .pp file to actually get it in place. Thanks to an entry on the Fedora Wiki, I found the following:

# checkmodule -M -m -o local.mod local.te

# semodule_package -o local.pp -m local.mod

# semodule -i local.pp

So, let’s go through these…

The checkmodule takes the .te file and creates a module file (.mod). The ‘-M’ enables the module for MLS/MCS support. This may not be needed if you’re not using MLS/MCS. The ‘-m’ indicates that you are creating a non-base policy module. I take that to mean that this is a sub-module that we’ll be adding to the existing base. The ‘-o’ simply specifies the output file and the last entry ‘local.te’ is the input file.

Next, the semodule_package program, as one might infer, takes the module file and creates a .pp file. The ‘-o’ is still the output file and the ‘-m’ is essentially the input module file you are going to use.

Finally, the semodule command is what installs the package (‘-i’).

There may be a better, faster, more efficient, easier to implement way to get all this done. If there is, please do not hesitate to share as I always prefer to do things the easiest way possible. But, whether this is the easiest or best way to do this or not, it seems to have worked. And hopefully, it may be of some use to you as it was to me.

Until next time…

September 21, 2012 Posted by | selinux | | Leave a comment