Chotaire Wiki

Stuff you didn't know

User Tools

Site Tools


linux-selinux

SELinux Howto

Enable/disable SELinux

Find out if (and how) SELinux is enabled:

getenforce

Disable SELinux (set it to permissive):

setenforce 0

Re-enable SELinux with the following command:

setenforce 1

SELinux Booleans

Starting with CentOS 5, many SELinux problems can be fixed by simply changing booleans. If you see error messages flooding your audit logs, google for them. You may find out that booleans may be helpful. There is often no need to build selinux modules.

A list of available SELinux booleans can be generated:

getsebool -a

Search for something specific, e.g. httpd:

getsebool -a | grep httpd

Change a boolean temporarily, then try if you experience the same problem again:

setsebool httpd_can_network_connect on

If you are sure this fixed your problems, set it permanent so it will resist reboots:

setsebool -P httpd_can_network_connect on

Allow additional ports with SELinux

Sometimes, we wanna change default ports, e.g. let's change SSH port 22 to port 222. Let's just write the entire procedure down here because you wanna change this anyway. Let's assume you're running CentOS 6/7 or Fedora 24/25:

See a list of ports allowed by SELinux:

yum -y install policycoreutils-python
semanage port -l 

Firewall

Without firewalld, insert the following line in /etc/sysconfig/iptables where your other INPUT accept lines reside:

-A INPUT -p tcp -m state --state NEW -m tcp --dport 222 -j ACCEPT

Then restart iptables:

service iptables restart

With firewalld installed, you can use commands to do this:

firewall-cmd --permanent --zone=public --add-port=222/tcp
firewall-cmd --reload

Semanage

Now we will install the policycoreutils and manage SELinux accordingly:

yum -y install policycoreutils-python
semanage port -a -t ssh_port_t -p tcp 222

Ssh Config

Last but not least, edit /etc/ssh/sshd.config and find the line that says:

#Port 22

Change it to:

Port 222

then restart SSH by typing:

service sshd restart

Security contexts

All processes and files have a SELinux security context. You can list them with the -Z switch, this works with many utilities. Sometimes you will need specific directories to have a different security context from the defaults because e.g. your webserver needs to write to an uncommon directory. This is best done with semanage fcontext, which is a better approach than creating an selinux module.

List files:

ls -alZ /bin/bash
-rwxr-xr-x. 1 root root system_u:object_r:shell_exec_t:s0 1072008 30. Sep 10:25 /bin/bash

List processes:

ps -auxZ | grep bash
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 root 15278 0.0  0.2 122920 4456 pts/0 Ss 18:19   0:00 -bash

Shit often fucks up because a user moved some modified files instead of copying them. If they would copy, the copy would adapt to the destination's security context. But when moving them, the source security context is used and then everything's fucked. Restore the location's context:

# restorecon -v /var/www/html/index.html 

This also works recursively:

# restorecon -Rv /var/www/html 

List configured security contexts:

semanage fcontext -l

Change the security context of a directory, this example will allow nginx to write to a php session directory:

semanage fcontext -a -t httpd_sys_rw_content_t '/var/lib/php/session(/.*)?'

Delete a changed security context of a directory:

semanage fcontext -d -t httpd_sys_rw_content_t '/var/lib/php/session(/.*)?'

Please remember to restorecon the affected directory after having made changes to security contexts.

Using chcon to temporarily relabel files

The 'chcon' command may be used to change SELinux security context of a file or files/directories in a similar way to how 'chown' or 'chmod' may be used to change the ownership or standard file permissions of a file.

Using Apache as an example, suppose you want to change the DocumentRoot to serve web pages from a location other than the default /var/www/html/ directory. Assume we create a directory (or maybe a mount point) at /html/ and create an index.html file there:

# mkdir /html
# touch /html/index.html
# ls -Z /html/index.html
-rw-r--r--  root root user_u:object_r:default_t        /html/index.html
# ls -Z | grep html
drwxr-xr-x  root root user_u:object_r:default_t        html 

We see that both the directory /html/ and file /html/index.html have the security context type: default_t. If we start our web browser and try to view the page, SELinux will properly deny access and log the error because the directory and file(s) have the wrong security context. We need to set the correct security context type for Apache of: httpd_sys_content_t.

# chcon -v --type=httpd_sys_content_t /html
context of /html changed to user_u:object_r:httpd_sys_content_t
# chcon -v --type=httpd_sys_content_t /html/index.html
context of /html/index.html changed to user_u:object_r:httpd_sys_content_t
# ls -Z /html/index.html
-rw-r--r--  root root user_u:object_r:httpd_sys_content_t    /html/index.html
# ls -Z | grep html
drwxr-xr-x  root root user_u:object_r:httpd_sys_content_t    html 

Equally we could have set both in one go using the -R recursive switch:

# chcon -Rv --type=httpd_sys_content_t /html 

Modifying security contexts in this manner will persist between system reboots but only until the modified portion of the filesystem is relabeled. This is a not uncommon operation and the proper solution, after testing, is to write a local custom rule (a so-called Policy Module) and merge it into the base local rules. This will be an additional rule on top of the 200+ rules already present. To make the security context changes permanent, even through a complete filesystem relabel, we can use the SELinux Management Tool or the 'semanage' command from the command line:

semanage fcontext -a -t httpd_sys_content_t "/html(/.*)?" 

to add a file context of type httpd_sys_content_t for everything under /html.1)

Build custom SELinux modules on Centos/Fedora

If you think that SELinux is blocking your operations, find the cause:

a) You may already be audit logging. If you're not auditlogging already, start fresh:

rm -rf /var/log/audit/* ; semodule -B -D ; setenforce 0 ; service auditd restart

b) Now trigger the same problem again and afterwards filter the relevant AVC deny lines into a text file

cat /var/log/audit/audit.log | grep "AVC" > /tmp/whatever.log

c) check /tmp/whatever.log and remove all shit that doesnt belong to the problem

d) Create a policy module with a module name that you will remember:

cat /tmp/whatever.log | audit2allow -M your-fucking-modulename

e) For major enlightement and also some generated tips and advises, check the text version of your module:

more your-fucking-modulename.te

f) Install the generated module

semodule -i your-fucking-modulename.pp

g) If shit now works, make sure to set selinux back to normal shit:

setenforce 1 ; semodule --build

You are able to view all installed semodules. If you were clever enough to name your own modules with e.g. your preceding nickname, then you will be able to find your custom modules quickly:

semodule -l

To delete a semodule, issue the following command:

semodule -r <modulename>

Relabel the entire filesystem

Sometimes, when you really fucked up (e.g. with SELinux permanently disabled you upgraded security contexts or did a dist-upgrade or wildly moved system files from one system to the other) stuff is really messed up. Solution: Relabel the entire fucking shit. Remember it will take ages so get two coffees.

Relabel on reboot:

touch /.autorelabel
reboot

If this doesn't work because you did a kick-ass dist-upgrade and then re-enabled SELinux, try issueing another command first:

genhomedircon
touch /.autorelabel
reboot

On Fedora 30, this can be easily accomplished like this:

fixfiles onboot



linux-selinux.txt ยท Last modified: 2021/05/13 15:04 by chotaire