Chapter 19. Linux Security Modules

Objectives

  • Understand how the linux security module works and how it is deployed
  • List the varios LSM implementations available
  • Understand the main features of SELinux
  • Explain the different modes and policies available
  • Grasp the importance of context and how to grab them and set them
  • Know how to use the important SELinux utility programs

Linux Security Modules

  • SELinux
  • AppArmor
  • Smack
  • Tomoyo

Only one of the can be used at the same time since they could potentially modify the same parts in the linux Kernel.

SELinux Overview

SELinux was developed by NSA (National Security Administration) and has been integral to RHEL for a long time ago.

It is composed of security rules that determine which processes can access which files, directories, ports and other items, it works with these three conceptual quantities :

  • Context
    • Labels to files, processes and ports. Example of SELinux context are
      • User
      • Role
      • Type
  • Rules
    • Describe access control in terms of :
      • Contexts
      • Processes
      • Files
      • Ports
      • Users
  • Policies
    • Are a set of rules that describes what system wide access control decision should be made by SELinux

An SELinux context is a name used by a rule to define how users, processes, files and ports interact with each other. As the default policy is to deny any access, rules are used to describe allowed actions on the system.

SELinux Modes

  • Enforcing
    • All SELinux code is operative and access is denied according to policy. All violations are audited and logged
  • Permissive
    • Enables SELinux code but only audits and warns about operations that would be denied in enforcing
  • Disable
    • Completely disables SELinux kernel and application code leaving the system without any of its protections

SELinux configuration file

Normally can be found at

/etc/selinux/config

or

/etc/sysconfig/selinux

​SELinux sestatus command

This command

sestatus

Display the current mode and policy of SELinux

SELinux getenforce and setenforce

Commands used to manage SELinux mode, sample :

$ getenforce
Disabled
$ sudo setenforce Permissive
$getenforce
Permissive

setenforce can switch between "enforced" and "permissive" modes, but it can not switch to disable mode.

Disable SELinux

  • Edit the SELinux configuration file "/etc/selinux/config" and set SELINUX=disabled
    • Default method used to disabled SELinux permanently
  • Adding selinux=0 parameter to the kernel when the system is rebooting 

Note: It is not recommended to disable SELinux in systems that use it often, since re-enable it will impact the performance of the system while relabeling the entire filesystem.

SELinux Policies

Set of rules that determines how SELinux will behave.

Configuring policies

Can be set within the configuration file

/etc/sysconfig/selinux

​Multiple policies are allowed but only one can be active at a time. Changing the policy may require a reboot of the system and a time consuming re-labelong of filesystem contents.

Each policy has files which must be installed under

/etc/selinux/[SELINUXTYPE]

​The most common policies are

  • Targeted
    • The default policy in which SELinux is more restricted to targeted processes. User processes and init processes are not targeted. SELinux enforces memory restrictions for all processes, which reduces the vulnerability to buffer overflow attacks.
  • Minumun
    • A modification of the targeted policy where only selected processes are protected
  • MLS
    • Multi Level Security policy is much more restrictive, all processes are placed in fine-grained security domains with particular policies.

SELinux Context Utilities

Context are labels applied to directories, files, proccesses and ports. Those labels are used to describe access rules. There are four SELinux context

  • User
  • Role
  • Type
  • Level

We are going to focus on Type context, which is the most commonly utilized context. The label naming convention determines that type context labels should end with _t as in kernel_t

SELinux Standard Command Line Tools

Many standard commands like ls and ps where extended to SELinux. Often the Z parameter is passed to standard command line tools

$ ps axZ
LABEL PID TTY STAT TIME COMMAND
system_u:system_r:init_t:s0 1 ? Ss 0:04 /usr/lib/systemd/systemd --switched-root ...
system_u:system_r:kernel_t:s0 2 ? S 0:00 [kthreadd]

$ ls -Z /home/ /tmp/
/home/:
drwx------. peter peter unconfined_u:object_r:user_home_dir_t:s0 peter
/tmp/:
-rwx------. root root system_u:object_r:initrc_tmp_t:s0 ks-script-c4ENhg
drwx------. root root system_u:object_r:tmp_t:s0 systemd-private-0ofSvO
-rw-------. root root system_u:object_r:initrc_tmp_t:s0 yum.log​

​Other tools extended to SELinux includes

  • cp
  • mv
  • mkdir

SELinux context inheritance and preservation

Newly crated files inherit the context from their parent directory, but when moving or copying files, it is the context of the source directory which may be preserved can often lead to confusion.

Following with later samples the context of tmpfile was not changed by moving the file from /tmp to /home/peter

$ cd /tmp/
$ touch tmpfile
$ ls -Z tmpfile
-rw-rw-r--. peter peter unconfined_u:object_r:user_tmp_t:s0 tmpfile

$ cd
$ touch homefile
$ ls -Z homefile
-rw-rw-r--. peter peter unconfined_u:object_r:user_home_t:s0 homefile

$ mv /tmp/tmpfile .
$ ls -Z
-rw-rw-r--. peter peter unconfined_u:object_r:user_home_t:s0 homefile
-rw-rw-r--. peter peter unconfined_u:object_r:user_tmp_t:s0 tmpfile

Common SELinux Behavior with HTTPD server "APACHE"

On SELinux enabled systems, the web server can only access files with the correct context labels. If some files were created in a directory "A" and the Moved to the DocumentRoot located at directory "B", such files may not be accesible to the web server since they wont have the correct context labels.

restorecon

The command "restorecon" resets file contexts, based on parent directory settings. In the next example all files under the home directory will have their context reseted, based on their parent directory "home" in this case.

$ ls -Z
-rw-rw-r--. peter peter unconfined_u:object_r:user_home_t:s0 homefile
-rw-rw-r--. peter peter unconfined_u:object_r:user_tmp_t:s0 tmpfile
 
$ restorecon -Rv /home/peter
restorecon reset /home/peter/tmpfile context \
unconfined_u:object_r:user_tmp_t:s0->unconfined_u:object_r:user_home_t:s0
 
$ ls -Z
-rw-rw-r--. peter peter unconfined_u:object_r:user_home_t:s0 homefile
-rw-rw-r--. peter peter unconfined_u:object_r:user_home_t:s0 tmpfile

Semanage fcontext

Used to change the context of a given file or directory, this command only changes the default settings it does not apply them to existing objects, thus restorecon command is needed to flush the default context and set the new one.

root@rhel7 /]# mkdir /virtualHosts
[root@rhel7 /]# ls -Z
...
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 virtualHosts
 
[root@rhel7 /]# semanage fcontext -a -t httpd_sys_content_t /virtualHosts
[root@rhel7 /]# ls -Z
...
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 virtualHosts
 
[root@rhel7 /]# restorecon -RFv /virtualHosts
restorecon reset /virtualHosts context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0
[root@rhel7 /]# ls -Z
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 virtualHosts

 
The context change from default_t to httpd_sys_content_t is thus only applied after the call to restorecon.

Using SELinux Booleans

SELinux policy behavior can be configured at runtime without rewriting the policy. This is accomplished by configuring SELinux Booleans which are policy parameters which can be enabled or disabled.

$ sudo semanage boolean -l
SELinux boolean             State   Default   Description
ftp_home_dir                  (off , off)      Allow ftp to home dir
smartmon_3ware                (off , off)      Allow smartmon to 3ware
mpd_enable_homedirs           (off , off)      Allow mpd to enable homedirs
xdm_sysadm_login              (off , off)      Allow xdm to sysadm login
xen_use_nfs                   (off , off)      Allow xen to use nfs
mozilla_read_content          (off , off)      Allow mozilla to read content
...
nfs_export_all_rw              (on , on)       Allow nfs to export all rw
pcp_bind_all_unreserved_ports (off , off)      Allow pcp to bind all unreserved ports
postgresql_selinux_transmit_client_label (off , off) Allow postgresql to selinux transmit client label
collectd_tcp_network_connect  (off , off)      Allow collectd to tcp network connect
cobbler_use_cifs              (off , off)      Allow cobbler to use cifs
mcelog_server                 (off , off)      Allow mcelog to server
httpd_setrlimit               (off , off)      Allow httpd to setrlimit
squid_connect_any              (on , on)       Allow squid to connect any
ssh_sysadm_login              (off , off)      Allow ssh to sysadm login
domain_fd_use                  (on , on)       Allow domain to fd use
virt_use_samba                (off , off)      Allow virt to use samba
cluster_use_execmem           (off , off)      Allow cluster to use execmem
nfs_export_all_ro              (on , on)       Allow nfs to export all ro
cron_can_relabel              (off , off)      Allow cron to can relabel
sftpd_anon_write              (off , off)      Allow sftpd to anon write

​getsebool and setsebool

The command getsebool -a wil also display the SELinux boolean information, and setbool will allow us to set such parameters.
With setsebool the default behavior is non persistent however we can use the -P parameter to make such change persistent

An example of non-persistent change using setsebool

​$ getsebool ssh_chroot_rw_homedirs
ssh_chroot_rw_homedirs --> off

$ sudo setsebool ssh_chroot_rw_homedirs on
$ getsebool ssh_chroot_rw_homedirs
ssh_chroot_rw_homedirs --> on

$ sudo reboot
...

$ getsebool ssh_chroot_rw_homedirs
ssh_chroot_rw_homedirs --> off

An example of persistent change using setsebool  -P

$ getsebool ssh_chroot_rw_homedirs
ssh_chroot_rw_homedirs --> off

$ sudo setsebool -P ssh_chroot_rw_homedirs on
$ getsebool ssh_chroot_rw_homedirs
ssh_chroot_rw_homedirs --> on

$ sudo reboot
...

$ getsebool ssh_chroot_rw_homedirs
ssh_chroot_rw_homedirs --> on 

Troubleshooting Tools

SELinux have a package called setroubleshoot-server used to collect data about security issues and proposal of solutions to prevent those issues from happening again.

$ echo "File created in someplace" > rootfile
$ mv rootfile /var/www/html
$ wget -O - localhost/rootfile
--2016-07-16 20:39:15--  http://localhost/rootfile
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2016-07-16 20:39:15 ERROR 403: Forbidden.

One way to solve this is by typing 

$ grep httpd /var/log/audit/audit.log | audit2allow -M mypol

audit2allow is a tool that generates SELinux policy rules from logs of denied operations. A similar tool is audit2why, which translates SELinux audit messages into a description of why the access was denied.

​$ grep httpd /var/log/audit/audit.log | audit2why

Other way to solve this issue is through restorecon

​$ restorecon -Rv /var/www/html

This command will reset the context of the files under html

AppArmor

Is a Linux Security Module similar to SELinux, some of its features are

  • Mandatory Access Control (MAC)
  • Allows administrators to associate a security profile to a program which restricts its capabilities
  • Is considered easier to use than SELinux
  • Is considered filesystem-neutral.

In addition to manually specifying profiles, this module includes a learning mode, in which violations of the profile are logged, but not prevented. This log can then be turned into a profile, based on the program's typical behavior. 

Lab 19.1: SELinux

Before starting this exercise verify SELinux is enabled and in enforcing mode, by editing /etc/selinux/config and rebooting if necessary. Obviously you can only do this on a system such as RHEL where SELinux is installed.

1. Install the vsftpd and ftp packages.
2. Create a user account user1 with the password password.
3. Change to user1 account and write some text to a file named /home/user1/user1file.
4. Exit the user1 account and make sure the ftp (vsftpd by name) service is running.
5. ftp to localhost, login as user1, and try to get user1file. It should fail.
Note this step can fail either at the login, or at the file transfer. The fix for both problems is the same, so it should
not affect the exercise. This difference in the behavior is a consequence of differences in the SELinux policy.
6. Check /var/log/messages to see why. You should see an error from setroubleshoot. Run the sealert command shown earlier.
7. Fix the error, and now try to ftp, login as user1, and get user1file again. This time it should work.

1. Install the FTP server

$ sudo yum install vsftpd ftp

2. Create the user1

$ sudo useradd user1
$ sudo passwd user1
Changing password for user user1.
New password: password
BAD PASSWORD: The password fails the dictionary check - it is based on a dictionary word
Retype new password: password
passwd: all authentication tokens updated successfully.

3. Become the user1

$ sudo su - user1
[user1@rhel7 ~]$ echo ’file created at /home/user1’ > user1file
[user1@rhel7 ~]$ ls
user1file

4. Exit from user1 and check the FTP server status 

$ exit
$ sudo systemctl status vsftpd.service
vsftpd.service - Vsftpd ftp daemon
Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; disabled)
Active: active (running) since Fri 2014-11-21 14:08:14 CET; 32min ago
...

5. Get into the localhost through FTP

$ ftp localhost
Trying ::1...
Connected to localhost (::1).
220 (vsFTPd 3.0.2)
Name (localhost:peter): user1
331 Please specify the password.
Password: password
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> get user1file
local: user1file remote: user1file
229 Entering Extended Passive Mode (|||35032|).
550 Failed to open file.
ftp> quit
221 Goodbye.

6. Check the audit logs

$ tail /var/log/messages
Nov 21 14:23:26 rhel7 setroubleshoot: SELinux is preventing /usr/sbin/vsftpd from read access on the file .
For complete SELinux messages. run sealert -l 7f8e5e6f-bcee-4c59-9cd1-72b90fb1f462
***** Plugin catchall_boolean (47.5 confidence) suggests ******************
If you want to allow ftp to home dir
Then you must tell SELinux about this by enabling the ’ftp_home_dir’ boolean.
Do
setsebool -P ftp_home_dir 1

Notice that the suggestion to fix the issue can be found at the log file, and it is not even necessary to run sealert.

7. Enable the selinux boolean to access the home dir through FTP, access through FTP and then retrieve the file

$ sudo setsebool -P ftp_home_dir 1
$ ftp localhost
Trying ::1...
Connected to localhost (::1).
220 (vsFTPd 3.0.2)
Name (localhost:peter): user1
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> get user1file
local: user1file remote: user1file
229 Entering Extended Passive Mode (|||18769|).
150 Opening BINARY mode data connection for user1file (28 bytes).
226 Transfer complete.
28 bytes received in 4.2e-05 secs (666.67 Kbytes/sec)
ftp> quit
221 Goodbye.
$ cat user1file
file created at /home/user1