SHIFT

--- Sjoerd Hooft's InFormation Technology ---

User Tools

Site Tools


Sidebar

Recently Changed Pages:

View All Pages


View All Tags


LinkedIn




WIKI Disclaimer: As with most other things on the Internet, the content on this wiki is not supported. It was contributed by me and is published “as is”. It has worked for me, and might work for you.
Also note that any view or statement expressed anywhere on this site are strictly mine and not the opinions or views of my employer.


Pages with comments

View All Comments

redhatselinux

Red Hat SELinux

Security Enhanced Linux is an additional method to protect your system, besides updating and a firewall. It is a set of security rules that determine which process can access which files, directories, ports etc. Every file, process, directory and port has a special label called a SELinux context. There a several contexts, but the most interesting one is the type context, which always ends with “_t”.

This article shows some information and commands to work with SELinux. When you encounter a issue on a SELinux enabled system, you should always ask yourself the question, “Could this be caused by SELinux”. So dealing with that question will be the first part.

After that more information will be given about SELinux modes, configfiles and commands.

Could This Be Caused By SELinux?

Is SELinux Enabled?

First determine the mode SELinux is running in. Simply, as root, issue this command: “getenforce”:

[root@localhost ~]# getenforce
Enforcing

There are three modes:

  • enforcing: SELinux actively denies unallowed requests
  • permissive: SELinux allows all interactions, even if there is no explicit rule
  • disabled: SELinux is completely disabled

How Do I Disable SELinux?

To troubleshoot an issue you can temporarily change SELinux to permissive using the command “setenforce”:

[root@localhost ~]# setenforce permissive
[root@localhost ~]# getenforce
Permissive

Now What?

Now you can check if you're issue is solved. If it is, the SELinux was the cause.

How can I Fix It?

The easiest way to troubleshoot SELinux issues is by installing “setroubleshoot-server”:

yum install setroubleshoot-server

Now restart the auditd service for picking up the new package:

[root@localhost log]# service auditd restart
Stopping auditd:                                           [  OK  ]
Starting auditd:                                           [  OK  ]

Then check for more information and how you could fix it, follow this procedure:

  • check /var/log/audit/audit.log
    • this logfile may show some cryptic scontext errors
  • check /var/log/messages
    • this logfile might show some error like “SELinux is preventing…..” and if it does it will also show a unique string regarding the error, for example:“run sealert -l <unique-string>
  • now run the command shown in the messages logfile: sealert -l <unique-string>
  • Now run the suggestion in the sealert description

Example

This is an example of the messages and commands when adding a file to a webserver which has a diiferent SELinux context:

[root@localhost ~]# service httpd stop
Stopping httpd:                                            [  OK  ]
[root@localhost ~]# touch /root/file3
[root@localhost ~]# mv /root/file3 /var/www/html/
[root@localhost ~]# service httpd start

[root@localhost ~]# curl localhost/file3
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /file3
on this server.</p>
<hr>
<address>Apache/2.2.15 (Red Hat) Server at localhost Port 80</address>
</body></html>

[root@localhost ~]# tail /var/log/audit/audit.log
type=AVC msg=audit(1396895949.472:1430): avc:  denied  { getattr } for  pid=16956 comm="httpd" path="/var/www/html/file3" dev=sda2 ino=917490 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file

[root@localhost log]# tail /var/log/messages
Apr  7 11:39:13 localhost setroubleshoot: SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/file3. For complete SELinux messages. run sealert -l 352f96a6-1102-4afe-8a2e-1ec0aac4ebb0

[root@localhost log]# sealert -l 352f96a6-1102-4afe-8a2e-1ec0aac4ebb0
SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/file3.

*****  Plugin restorecon (99.5 confidence) suggests  *************************

If you want to fix the label.
/var/www/html/file3 default label should be httpd_sys_content_t.
Then you can run restorecon.
Do
# /sbin/restorecon -v /var/www/html/file3
Note: In the example the command for fixing one file is shown, if you need to reset more files you can recursively reset them all at once: restorecon -R /var/www/

SELinux Modes (Disable SELinux)

As mentioned above you can change to a different mode with the setenforce command. You can't use that command to disable SELinux though. To completely disable SELinux edit the config file /etc/sysconfig/selinx:

[root@localhost log]# cat /etc/sysconfig/selinux

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

After editing the file, reboot the machine. Note that after disabling SELinux, the only way to enable it again is to edit this file again and reboot again. This will cause the system to start relabeling everything! Especially on larger systems this might take a long time, so think before you do this. The system will not be available during relabeling!

Note: If you'd make a typo in the configfile SELinux will fall back to “permissive”.

Display SELinux Context

SELinux is used for processes, ports, files etc. As explained before, the context is quite important, and normally defined by the parent directory. As shown above, if a file is created and inherits the context of it's parent, it keeps that context when it's moved (mv) or copied with the -a option (-a).

Most commands have an option to display the SELinux context (usually -Z):

[root@localhost log]# ps -ZC httpd
LABEL                             PID TTY          TIME CMD
unconfined_u:system_r:httpd_t:s0 16948 ?       00:00:00 httpd
unconfined_u:system_r:httpd_t:s0 16951 ?       00:00:00 httpd

[root@localhost log]# ls -Z /var/www
drwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 error
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 icons

[root@localhost log]# netstat -Z
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name    Security Context
tcp        0     64 192.168.25.128:ssh          192.168.25.1:63900          ESTABLISHED 16303/sshd          system_u:system_r:sshd_t:s0-s0:c0.c1023

Modify SELinux Context

There are a few commands you can use to change the context:

semanage fcontext -l
semanage fcontext -a
restorecon
  • semanage fcontext -l is used to display all defined contexts. You can grep the required info you need.
  • semanage fcontext -a is used to modify (add) the defined contexts
  • semanage fcontext -d is used to modify (delete) the defined contexts
  • restorecon is used to restore the SELinux contexts as defined in the ruleset and has a few frequent used arguments:
    • -R : Restore the contexts recursively
    • -F : Force
    • -v : verbose, use -vv for even more information

Example

In the example above I've shown how to restore the context for a file inside a directory. But what if you would like to create a second directory which the web server also has to be able to read? SELinux would prevent that since your created directory would not be listed with the context “httpd_sys_content_t”.

First, let's check which directories are listed with that context:

[root@localhost ~]# semanage fcontext -l | grep httpd_sys_content_t
/etc/htdig(/.*)?                                   all files          system_u:object_r:httpd_sys_content_t:s0
/srv/([^/]*/)?www(/.*)?                            all files          system_u:object_r:httpd_sys_content_t:s0
/srv/gallery2(/.*)?                                all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/drupal.*                                all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/htdig(/.*)?                             all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/icecast(/.*)?                           all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/mythtv/data(/.*)?                       all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/mythweb(/.*)?                           all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/ntop/html(/.*)?                         all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/openca/htdocs(/.*)?                     all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/selinux-policy[^/]*/html(/.*)?          all files          system_u:object_r:httpd_sys_content_t:s0
/var/lib/cacti/rra(/.*)?                           all files          system_u:object_r:httpd_sys_content_t:s0
/var/lib/graphite-web(/.*)                         all files          system_u:object_r:httpd_sys_content_t:s0
/var/lib/htdig(/.*)?                               all files          system_u:object_r:httpd_sys_content_t:s0
/var/lib/trac(/.*)?                                all files          system_u:object_r:httpd_sys_content_t:s0
/var/www(/.*)?                                     all files          system_u:object_r:httpd_sys_content_t:s0
/var/www/icons(/.*)?                               all files          system_u:object_r:httpd_sys_content_t:s0
/var/www/svn/conf(/.*)?                            all files          system_u:object_r:httpd_sys_content_t:s0

Since all these directories have the “httpd_sys_content_t” the web server will be allowed to access the files inside of them. Note the (/.*)? section at the end of each line, it's a regular expression which means “optionally, match a / followed by any number of characters” which will match the directory before it and everything in that directory recursively.

Now, we want to add the /virtual directory in which our index.html is created. This has a different SELinux context:

[root@localhost ~]# mkdir /virtual
[root@localhost ~]# touch /virtual/index.html
[root@localhost ~]# ls -Zd /virtual/
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /virtual/
[root@localhost ~]# ls -Z /virtual/
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 index.html

Now we set the SELinux context of “httpd_sys_content_t” to the /virtual directory in the SELinux ruleset:

[root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t '/virtual(/.*)?'
[root@localhost ~]# semanage fcontext -l | grep httpd_sys_content_t
/etc/htdig(/.*)?                                   all files          system_u:object_r:httpd_sys_content_t:s0
/srv/([^/]*/)?www(/.*)?                            all files          system_u:object_r:httpd_sys_content_t:s0
/srv/gallery2(/.*)?                                all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/drupal.*                                all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/htdig(/.*)?                             all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/icecast(/.*)?                           all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/mythtv/data(/.*)?                       all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/mythweb(/.*)?                           all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/ntop/html(/.*)?                         all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/openca/htdocs(/.*)?                     all files          system_u:object_r:httpd_sys_content_t:s0
/usr/share/selinux-policy[^/]*/html(/.*)?          all files          system_u:object_r:httpd_sys_content_t:s0
/var/lib/cacti/rra(/.*)?                           all files          system_u:object_r:httpd_sys_content_t:s0
/var/lib/graphite-web(/.*)                         all files          system_u:object_r:httpd_sys_content_t:s0
/var/lib/htdig(/.*)?                               all files          system_u:object_r:httpd_sys_content_t:s0
/var/lib/trac(/.*)?                                all files          system_u:object_r:httpd_sys_content_t:s0
/var/www(/.*)?                                     all files          system_u:object_r:httpd_sys_content_t:s0
/var/www/icons(/.*)?                               all files          system_u:object_r:httpd_sys_content_t:s0
/var/www/svn/conf(/.*)?                            all files          system_u:object_r:httpd_sys_content_t:s0
/virtual(/.*)?                                     all files          system_u:object_r:httpd_sys_content_t:s0
[root@localhost ~]# ls -Zd /virtual/
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /virtual/

As you can see, the /virtual now has the correct context in the SELinux ruleset, but not yet on the directory. We need restorecon to do that:

[root@localhost ~]# restorecon -RFvv /virtual/
restorecon reset /virtual context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0
restorecon reset /virtual/index.html context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0
[root@localhost ~]# ls -Zd /virtual/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /virtual/
[root@localhost ~]# ls -Z /virtual/
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html

As you can see, everything is correct now, and since SELinux works directly at the kernel nothing has to be restarted.

Removing and Added Directory

If you added a directory with a specific context and you need to remove it again you can do it like this:

semanage fcontext -d '/virtual(/.*)?'

SELinux Booleans

SELinux are switches that change the behavior of the SELinux policy. They can be disabled or enabled. To manage the SELinux booleand you'll use the following commands:

getsebool <boolean>
getsebool -a
setsebool
setsebool -P
semanage boolean -l
  • getsebool will display a SELinux boolean, while -a will show them all
  • setsebool will change a boolean, while -P will make the change persistent
  • semanage boolean -l will how if the boolean is set persistent
Note that packages with SELinux booleans can be found by looking for a manpage like this: man -k '_selinux'

Example

So another example to show you what this might mean. Say you want your webserver also to manage some files in home directories. Even if you would add your home directory on the way described above this will not work since there is a boolean preventing this.

First, let's take a look at the httpd related booleans:

[root@localhost ~]# getsebool -a | grep httpd
allow_httpd_anon_write --> off
allow_httpd_mod_auth_ntlm_winbind --> off
allow_httpd_mod_auth_pam --> off
allow_httpd_sys_script_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> on
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> off
httpd_execmem --> off
httpd_manage_ipa --> off
httpd_read_user_content --> off
httpd_run_stickshift --> off
httpd_serve_cobbler_files --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_tmp_exec --> off
httpd_tty_comm --> on
httpd_unified --> on
httpd_use_cifs --> off
httpd_use_fusefs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
httpd_use_openstack --> off
httpd_verify_dns --> off

As you can see, there are quite a few and the one we need is disabled. So now, let's enable it:

[root@localhost ~]# setsebool httpd_enable_homedirs on
[root@localhost ~]# getsebool -a | grep http.*homedir
httpd_enable_homedirs --> on

But now, if we look at persistency we see that at the next reboot this will be reset:

[root@localhost ~]# semanage boolean -l | grep http.*homedir
httpd_enable_homedirs          (on   ,  off)  Allow httpd to read home directories

Now, let's make it persistent:

[root@localhost ~]# setsebool -P httpd_enable_homedirs on
[root@localhost ~]# semanage boolean -l | grep http.*homedir
httpd_enable_homedirs          (on   ,   on)  Allow httpd to read home directories

SELinux and Non Default Home Directories

SELinux is also configured for using default options. I ran into a problem when an application user in a non-default home directory. We use X-redirection but that stopped working because of SELinux. When trying to add the xauth magic cookie we ran into this error:

xauth:  timeout in locking authority file /application/acceptance/appuser/.Xauthority

To solve this error a few steps are required. First of all check if the file already exists. This has to be the case, as I've seen the fix below fail when this was not the case. If not, as the application user create the file with this command:

[appuser@selinuxbox ~]$ touch .Xauthority

Then you need to configure SELinux to include home directory checking through the passwd file. To do so, open the semanage config file and set the usepasswd option to true:

[adminsjoerd@selinuxbox ~]$ sudo vi /etc/selinux/semanage.conf
[adminsjoerd@selinuxbox ~]$ cat /etc/selinux/semanage.conf | grep usepasswd
# usepasswd check tells semanage to scan all pass word records for home directories
#usepasswd=False
usepasswd=True

Then configure the home directory root to be considered as a home directory:

[adminsjoerd@selinuxbox ~]$ sudo semanage fcontext -a -e /home /application/acceptance
Note: in the above command, please do not add an ”/“ at the end, this will break it.

Then, because the home dir already exists, relabel it like this:

[adminsjoerd@selinuxbox ~]$ sudo restorecon -R /application

Which sets these settings in the fcontext and home dirs:

[adminsjoerd@selinuxbox ~]$ sudo semanage fcontext -l | grep appl
...
/application/acceptance = /home

[adminsjoerd@selinuxbox ~]$ ls -lZd /application/acceptance
drwxr-xr-x. appuser appuser system_u:object_r:home_root_t:s0 /application/acceptance

Graphical Tool

There is also a graphical tool available, system-config-selinx, but it's not installed by default. You can install and use it like this:

yum install policycoreutils-gui

system-config-selinx

This is especially useful if you need to do some policy editing, like adding an allowed port for a web server:
redhatselinux01.jpg

You could leave a comment if you were logged in.
redhatselinux.txt · Last modified: 2021/09/24 00:25 (external edit)