I don’t often have posts that show my personality – this will be one of them.
While training for EX415 exam – I have had to come back into contact with SELinux. Every workplace I have worked over the past 10 years have elected to put SELinux into permissive mode.
My first contact with SELinux came with a bodged Fedora release which came with a broken SELinux. Things have moved on considerably since then. But a lot of vendors still maintain that their applications must run within a permissive environment.
In any case, this post will highlight some of the issues I have with SELinux.
So first up, what is SELinux. I’m an advocate of calling a spade a ‘spade’. In which case SELinux is ‘Security Blocking Software’. It’s job is to block access to files/ports/functions that it doesn’t know about. That’s fine and Dandy, but it does so in some really strange ways. Below is a list of my gripes:
1. The man pages are not installed by default
Who made that stupid decision that the man page for something as big and complex isn’t installed by default. Further more, it’s a flipping pain to get the man pages ‘created’. It’s compounded by the utility for creating the SELinux Documentation not being installed by default.
# man user_u No manual entry for user_u
how to set up manpages
yum install -y policycoreutils-devel sepolicy --help # to remember syntax as I always forget sepolicy manpage -a -p /usr/share/man/man8 mandb
2. So many of the key binaries missing by default
It seems there is a different selinux utility for every task. Would be so useful to just have one utility to rule them all. I have listed some of the ones I often find are missing:
3. Key binaries in poorly named packages
This is really point 2b rather than 3.
Red Hat, Why not just create a package called selinux-utils which is just a wrapper around the other packages. In one go it’s then possible to install all the utilities.
Instead I am having to resort to yum to try and sort out the mess
yum whatprovides \*sealert
4. Debugging selinux
No matter how you slice or dice it. Finding out what the selinux failure cause is a pain in the neck. It logs to different places. You might find it in the secure, message or audit logs. Sometimes in all three.
Furthermore it’s plumbed into audit so you need to use audit commands to help debug
ausearch -m avc
5. Sealert makes some really stupid suggestions
First up, I love sealert, it’s a great tool – I love how it comes up with some sensible suggestions; but it also comes up with some awful ones. Some really wide-ranging scatter-gun approach to changes.
6. General lack of information
I mean seriously, what can the sysadm_u user do that the staff_u can not (bar use su)?? hmm? anyone? It’s really hard to find good solid information – maybe a nice table or a pretty picture
And finally, a little tip. How to create exceptions quickly (updated following comments)
This is essentially a method of ‘quick winning against SELinux’. It can be used in my mind, as a fallback method. It sets an individual process into permissive mode. This means that SELinux is tracking everyone that would have been blocked. And these logs are then used to generate an acceptance policy which is loaded.
To make this clear, this is merely a learning exercise. I wouldn’t recommend you do this, this is merely an illustration on how to use audit2allow.
I want to run httpd on port 78 (and not the standard port 80) and I know selinux will complain (in real life I would use semanage port to open a new port)
# set httpd_t to be permissive - without which the systemctl start will fail semanage permissive -a httpd_t systemctl start httpd curl localhost:78 # all the selinux logs have been generated #stop and cleanup stop httpd permissive mode systemctl stop httpd semanage permissive -d httpd_t
Now run sealert to translate the logs and make some suggestions
sealert -a /var/log/audit/audit.log
and it makes suggestions to fix the issue:
# ausearch -c 'httpd' --raw | audit2allow -M my-httpd # semodule -i my-httpd.pp
run those commands:
ausearch -c 'httpd' --raw | audit2allow -M my-httpd semodule -i my-httpd.pp # semodule -l
At this point the rules have been loaded and everything should work. So let’s test it.
systemctl start httpd curl localhost:78
And finally …
I would love to hear your comments. Please let me know what you think.