Thursday, 20 March 2014

LS_4_Securing Linux with SE Linux

Securing Linux with SE Linux

SELinux (Security Enhanced Linux) implements a flexible Mandatory Access Control (MAC) system built into the Linux kernel protecting the system from malicious or exploitable applications that can become a security risk on the system. It defines the access and transition rights of every application, process, user and file on the system managing the interactions of these entities using a security policy that specifies how strict the system should be. By default SElinux is installed on RHEL installations.

SElinux dynamics

When a subject (application), attempts to access an object (file), the policy enforcement server in the kernel checks an access vector cache AVC, where subject and object permissions are related on the application security context. Based on this information access can be :

-->Granted.
-->Denied, with an avc: denied message detailed in /var/log/messages.

SElinux status

Three are the possible statuses for SELinux: enforcing, permissive, and disabled.

Enforcing
System actions that are not allowed by SElinux context are not executed on the system.

Disabled
SElinux is not activated on the system.

Permissive
SELinux rules that are violated are logged; however SELinux doesn't stop anything.

The command 'setenforce' can be used to change SElinux status at real time on a running system :

# setenforce 1
Puts SELinux in enforcing mode.

# setenforce 0
Puts SELinux in permissive mode.

In order to disable SElinux on the system, the parameter 'SELINUX=disabled' must be configured on file /etc/sysconfig/selinux and the system must be rebooted. Another valid method is pass the kernel parameter 'selinux=0' at kernel boot or write it on /etc/grub.conf.

The command 'getenforce' can be used to display the system SELinux status current value :

# getenforce
Enforcing

SElinux mode

On a RHEL system if SELinux is active it protects the system in two modes: targeted or strict mode. The default is targeted where some daemons are protected. In strict mode all daemons are protected.

Targered mode

Is the default mode on RHEL systems. Under the targeted policy, every subject and object runs in the unconfined_t domain except for the specific targeted daemons. Objects that are in the unconfined_t domain have no restrictions and fall back to using standard Linux security. The daemons that are part of the targeted policy run in their own domains and are restricted in every operation they perform on the system. This way daemons that are exploited or compromised in any way are contained and can only cause limited damage.

This is the list of daemons are protected in the targeted policy: dhcpd, httpd, named, nscd, ntpd, portmap, snmpd, squid, and syslogd. It is possible to disable SElinux protection for each targered daemon using 'chcon' command. For example imagine that you have a server running SElinux in targered mode and you want to disable SElinux protection for Apache web server :

# chcon -t unconfined_exec_t /usr/sbin/httpd
# /etc/init.d/httpd restart


This procedure will exclude httpd daemon for targered daemon list and the rest of daemons will remain protected. Of course you can put httpd on the targered daemon once again using 'restorecon' :

# restorecon -F /usr/sbin/httpd
# /etc/init.d/httpd restart

Strict mode

In the strict policy, every subject and object exists in a specific security domain, and all interactions and transitions are individually considered within the policy rules. All daemons are protected in the strict mode.

SElinux file context

Selinux uses different context to each file/directory, implementing subjects, objects and actions attributes separately from standard file attributes (user, group and permissions). Using these attributes in conjunction with the security policy SElinux will allow/deny a process on the system.

In order to display these attributes the flag '-Z' can be used on most of the standard linux commands.

# ls -lrtZ /bin/bash

-rwxr-xr-x. root root system_u:object_r:shell_exec_t:s0 /bin/bash


As can be seen in this case system_u is the system user, object_r is the system object and shell_exec_t is the system action. All this means that with SElinux in targered mode only process that are allowed to execute shell_exec_t object type will be able to execute /bin/bash.

File relabeling

Sometimes a file relabeling is needed, for example when moving or copying into special directories related to the targeted daemons, such as /var/www/html directory. In this case the command 'chcon' can be used :

chcon -t httpd_sys_content_t /var/www/html/newfile.html

-->With SElinux enabled in targered mode if the file /var/www/html/newfile.html is not labelled as httpd_sys_content_t type the httpd daemon will not be able to show this file through the Web server and a SElinux alert will be generated. For mode info try 'man chcon.'

Restoring default file labeling

When running SElinux in targered mode the file /etc/selinux/targeted/contexts/files/file_contexts contains the default file labeling for most of the system files. This file is very useful when you want to restore the original file labeling of a file a you do not remember the values, you can use 'restorecon' command :

# ls -lrtZ /etc/hosts.allow
-rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/hosts.allow

# chcon -t httpd_sys_content_t /etc/hosts.allow

# ls -lrtZ /etc/hosts.allow
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 /etc/hosts.allow

# restorecon -F /etc/hosts.allow

# ls -lrtZ /etc/hosts.allow
-rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/hosts.allow


For more info 'man restorecon'.

FileSystem relabeling

Entire filesystem relabeling usually occurs only when labeling a file system for SELinux for the first time, or when switching between different types of policy, such as changing from the strict to the targered policy.

Red Hat recommends reboot the machine for relabeling a file system. Then init process performs the relabeling, ensuring that applications have the correct labels when they are started and that they are started in the right order :

# touch /.autorelabel
# reboot


At boot time init.rc checks for the existence of /.autorelabel. If this file exists, SELinux performs a complete file system relabel (using the '/sbin/fixfiles -f -F relabel' command), and then deletes /.autorelabel . Of course it will take some time ...

SElinux file operations

In SElinux enabled systems when filesystem operations are performed (for example copying, moving a file) the security context of the resulting operation must be considered, if not an unexpected behaviour on the running system can be obtained.

As said before file utilities commands such as ls and ps do not display SELinux security context by default. The '-Z' option must be used for most commands to view the SElinux context : 'ls -Z' and 'ps -Z'. Special considerations must be taken in the following commands:

# cp file1 file2
Used to copy files/directories, file2 is created with the SElinux security context related with the target directory where file2 is created.

# cp -p file1 file2
Used to copy files/directories, file2 is created with file1 SElinux security context. It preserves file1 SElinux context on file2.

# cp -Z 'se_user:se_role:se_type' file1 file2
Used to copy files/directories, file2 is created with se_user:se_role:se_type SElinux security context specified in -Z option.

# mv file1 file2
Used to move/rename files/directories, file2 is created with file1 SElinux security context. It preserves file1 SElinux context on file2.

SElinux Booleans

SElinux booleans are used to configure/change parts of the security policy at runtime without changing the security policy. This is used to fine tune the configuration of the daemons that are confined by SElinux. For example it can be used to disable SElinux protection to the httpd daemon when SElinux is enabled in targered mode or allow service access to NFS filesystems that are forbidden by default in targered mode.

Booleans administration can be done using the SElinux commands and 'getsebool' and 'semanage'.

Listing Booleans

In order to list all the booleans that can be used in order to configure confined daemons the command 'getsebool' can be used :

# getsebool -a

abrt_anon_write --> off
allow_console_login --> on
allow_corosync_rw_tmpfs --> off
allow_cvs_read_shadow --> off
allow_daemons_dump_core --> on
allow_daemons_use_tty --> on
allow_domain_fd_use --> on
allow_execheap --> off
allow_execmem --> on
allow_execmod --> on
allow_execstack --> on
allow_ftpd_anon_write --> on
allow_ftpd_full_access --> on
allow_ftpd_use_cifs --> on
allow_ftpd_use_nfs --> on
allow_gssd_read_tmp --> on
allow_guest_exec_content --> off
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
allow_java_execstack --> off
allow_kerberos --> on
allow_mount_anyfile --> on
allow_mplayer_execstack --> off
allow_nfsd_anon_write --> off
allow_nsplugin_execmem --> on
allow_polyinstantiation --> off
allow_postfix_local_write_mail_spool --> on
allow_ptrace --> off
allow_rsync_anon_write --> off
allow_saslauthd_read_shadow --> off
allow_smbd_anon_write --> off
allow_ssh_keysign --> off
allow_staff_exec_content --> on
allow_sysadm_exec_content --> on
allow_unconfined_nsplugin_transition --> off
allow_unconfined_qemu_transition --> off
allow_user_exec_content --> on
allow_user_mysql_connect --> off
allow_user_postgresql_connect --> off
allow_write_xshm --> off
allow_xguest_exec_content --> off
allow_xserver_execmem --> off
allow_ypbind --> off
allow_zebra_write_config --> on
cdrecord_read_content --> off
clamd_use_jit --> off
cobbler_anon_write --> off
cobbler_can_network_connect --> off
cron_can_relabel --> off
dhcpc_exec_iptables --> off
domain_kernel_load_modules --> off
exim_can_connect_db --> off
exim_manage_user_files --> off
exim_read_user_files --> off
fcron_crond --> off
fenced_can_network_connect --> off
ftp_home_dir --> on
ftpd_connect_db --> off
git_session_bind_all_unreserved_ports --> off
git_system_enable_homedirs --> off
git_system_use_cifs --> off
git_system_use_nfs --> off
global_ssp --> off
gpg_agent_env_file --> off
gpg_web_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_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> on
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> on
httpd_execmem --> off
httpd_read_user_content --> 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_gpg --> off
httpd_use_nfs --> off
init_upstart --> on
irssi_use_full_network --> off
mmap_low_allowed --> off
mozilla_read_content --> off
mysql_connect_any --> off
nagios_plugin_dontaudit_bind_port --> off
named_write_master_zones --> off
ncftool_read_user_content --> off
nfs_export_all_ro --> on
nfs_export_all_rw --> on
nscd_use_shm --> on
nsplugin_can_network --> on
openvpn_enable_homedirs --> on
piranha_lvs_can_network_connect --> off
pppd_can_insmod --> off
pppd_for_user --> off
privoxy_connect_any --> on
puppet_manage_all_files --> off
qemu_full_network --> on
qemu_use_cifs --> on
qemu_use_comm --> off
qemu_use_nfs --> on
qemu_use_usb --> on
racoon_read_shadow --> off
rgmanager_can_network_connect --> off
rsync_client --> off
rsync_export_all_ro --> off
samba_create_home_dirs --> off
samba_domain_controller --> off
samba_enable_home_dirs --> on
samba_export_all_ro --> off
samba_export_all_rw --> off
samba_run_unconfined --> off
samba_share_fusefs --> off
samba_share_nfs --> off
secure_mode --> off
secure_mode_insmod --> off
secure_mode_policyload --> off
sepgsql_enable_users_ddl --> on
sepgsql_unconfined_dbadm --> on
sftpd_anon_write --> off
sftpd_enable_homedirs --> off
sftpd_full_access --> off
sftpd_write_ssh_home --> off
smartmon_3ware --> off
spamassassin_can_network --> off
spamd_enable_home_dirs --> on
squid_connect_any --> on
squid_use_tproxy --> off
ssh_sysadm_login --> off
telepathy_tcp_connect_generic_network_ports --> off
tftp_anon_write --> off
tor_bind_all_unreserved_ports --> off
unconfined_login --> on
use_lpd_server --> off
use_nfs_home_dirs --> off
use_samba_home_dirs --> off
user_direct_dri --> on
user_direct_mouse --> off
user_ping --> on
user_rw_noexattrfile --> on
user_setrlimit --> on
user_tcp_server --> off
user_ttyfile_stat --> off
varnishd_connect_any --> off
virt_use_comm --> off
virt_use_fusefs --> off
virt_use_nfs --> off
virt_use_samba --> off
virt_use_sysfs --> off
virt_use_usb --> on
webadm_manage_user_files --> off
webadm_read_user_files --> off
wine_mmap_zero_ignore --> off
xdm_sysadm_login --> off
xen_use_nfs --> off
xguest_connect_network --> on
xguest_mount_media --> on
xguest_use_bluetooth --> on
xserver_object_manager --> off


If you are interested on what booleans can be used in order to manage SElinux settings for confined samba service :

# getsebool -a | grep samba

samba_create_home_dirs --> off
samba_domain_controller --> off
samba_enable_home_dirs --> on
samba_export_all_ro --> off
samba_export_all_rw --> off
samba_run_unconfined --> off
samba_share_fusefs --> off
samba_share_nfs --> off
use_samba_home_dirs --> off
virt_use_samba --> off


In order to get more detailed info about the booleans use the command 'semanage' :

# semanage boolean -l | grep samba

samba_domain_controller -> off Allow samba to act as the domain controller, add users, groups and change passwords.
samba_enable_home_dirs -> on Allow samba to share users home directories.
samba_export_all_ro -> off Allow samba to share any file/directory read only.
samba_export_all_rw -> off Allow samba to share any file/directory read/write.
use_samba_home_dirs -> off Support SAMBA home directories
samba_create_home_dirs -> off Allow samba to create new home directories (e.g. via PAM)
allow_smbd_anon_write -> off Allow samba to modify public files used for public file transfer services. Files/Directories must be labeled public_content_rw_t.
samba_share_fusefs -> off Allow samba to export ntfs/fusefs volumes.
samba_share_nfs -> off Allow samba to export NFS volumes.
samba_run_unconfined -> off Allow samba to run unconfined scripts
virt_use_samba -> off Allow virt to manage cifs files


In both case the booleans name and state (on/off) is displayed. Only in the case of using 'semanage boolean -l' a short description of what configures the boolean is printed.

Configuring Booleans

Once decided which boolean we need change, the command 'setsebool' can be used to change the boolean value.

As example imagine that our system in running with SElinux enabled in targered mode a we need to export through a web server an NFS directory. By default in a system with SElinux in targered mode httpd daemon can not use NFS directories as DocumentRoot :

# getsebool httpd_use_nfs
httpd_use_nfs --> off


But using setsebool command we can allow it :

# setsebool httpd_use_nfs on

Verify the result :

# getsebool httpd_use_nfs
httpd_use_nfs --> on


With this configuration httpd can use NFS directories in SElinux in targered mode without changing the security policy.

Other SElinux utilities

To make sure that following tools are going to be available on the system, install all SElinux RPM related :

# yum install *selinux* setool* policycoreutils* setroubleshoot*

--> system-config-selinux
It is a GUI tool can be used to configure almost anything related with SElinux. It is installed by the policycoreutils* RPMS.

--> sestatus
Displays detailed status of a system running SELinux :

# sestatus -v

SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: enforcing
Mode from config file: enforcing
Policy version: 24
Policy from config file: targeted

Process contexts:
Current context: unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Init context: system_u:system_r:init_t:s0
/sbin/mingetty system_u:system_r:getty_t:s0
/usr/sbin/sshd system_u:system_r:sshd_t:s0-s0:c0.c1023

File contexts:
Controlling term: unconfined_u:object_r:user_devpts_t:s0
/etc/passwd system_u:object_r:etc_t:s0
/etc/shadow system_u:object_r:shadow_t:s0
/bin/bash system_u:object_r:shell_exec_t:s0
/bin/login system_u:object_r:login_exec_t:s0
/bin/sh system_u:object_r:bin_t:s0 -> system_u:object_r:shell_exec_t:s0
/sbin/agetty system_u:object_r:getty_exec_t:s0
/sbin/init system_u:object_r:init_exec_t:s0
/sbin/mingetty system_u:object_r:getty_exec_t:s0
/usr/sbin/sshd system_u:object_r:sshd_exec_t:s0
/lib/libc.so.6 system_u:object_r:lib_t:s0 -> system_u:object_r:lib_t:s0
/lib/ld-linux.so.2 system_u:object_r:lib_t:s0 -> system_u:object_r:ld_so_t:s0


--> sealert
It is used to the setroubleshoot SElinux related incidents on the system. It is used to diagnose SELinux denials and attempts to provide user friendly explanations for a SELinux denial (AVC) and recommendations for how one might adjust the system to prevent the denial in the future.

It can run in text mode :

# sealert -a /var/log/audit/audit.log

or in graphical mode

# sealert -b

Practical Example

All this explanation about SElinux can be complex without using a practical example. Lets see how it works in real life

* Configure enable SElinux on targered mode on your rhel6 TEST machine. For this propose edit the file /etc/sysconfig/selinux and set the following parameters : SELINUX=enforcing and SELINUXTYPE=targeted. Reboot the system.

* Install apache httpd web server. Create the directory /web and the file /web/index.html, make /web the DocumentRoot of this web server.

# yum install httpd
# mkdir /web
# echo "SElinux example" >> /web/index.html
# chown -R root:apache /web
Edit file /etc/httpd/conf/httpd.conf and configure the DocumentRoot parameter to /web directory : 'DocumentRoot "/web"'. Then restart httpd service :

# /etc/init.d/httpd restart

... the it fails with a strange message that /web must be a directory ... lets have a look if it is a SElinux problem

# sealert -a /var/log/audit/audit.log

Summary:

SELinux is preventing /usr/sbin/httpd from using potentially mislabeled files
/web.

Detailed Description:

SELinux has denied the httpd access to potentially mislabeled files /web. This
means that SELinux will not allow httpd to use these files. If httpd should be
allowed this access to these files you should change the file context to one of
the following types, etc_t, lib_t, fonts_t, mnt_t, root_t, proc_t, sysfs_t,
tmpfs_t, tmp_t, usr_t, var_t, httpd_awstats_content_t, krb5_conf_t,
httpd_user_rw_content_t, httpd_nutups_cgi_content_t, sysctl_net_t,
httpd_config_t, httpd_cobbler_rw_content_t, calamaris_www_t,
httpd_prewikka_script_exec_t, var_spool_t, httpd_cache_t, httpd_tmpfs_t,
httpd_sys_script_exec_t, iso9660_t, device_t, httpd_munin_rw_content_t,
...
httpd_bugzilla_script_exec_t, device_t, devpts_t, devpts_t. Many third party
apps install html files in directories that SELinux policy cannot predict. These
directories have to be labeled with a file context which httpd can access.

Allowing Access:

If you want to change the file context of /web so that the httpd daemon can
access it, you need to execute it using semanage fcontext -a -t FILE_TYPE
'/web'.
where FILE_TYPE is one of the following: etc_t, lib_t, fonts_t, mnt_t, root_t,
proc_t, sysfs_t, tmpfs_t, tmp_t, usr_t, var_t, httpd_awstats_content_t,
krb5_conf_t, httpd_user_rw_content_t, httpd_nutups_cgi_content_t, sysctl_net_t,
httpd_config_t, httpd_cobbler_rw_content_t, calamaris_www_t,
httpd_prewikka_script_exec_t, var_spool_t, httpd_cache_t, httpd_tmpfs_t,
httpd_sys_script_exec_t, iso9660_t, device_t, httpd_munin_rw_content_t,
...
httpd_bugzilla_script_exec_t, device_t, devpts_t, devpts_t. You can look at the
httpd_selinux man page for additional information.

Additional Information:

Source Context unconfined_u:system_r:httpd_t:s0
Target Context unconfined_u:object_r:default_t:s0
Target Objects /web [ dir ]
Source httpd
Source Path /usr/sbin/httpd
Port
Host
Source RPM Packages httpd-2.2.15-5.el6
Target RPM Packages
Policy RPM selinux-policy-3.7.19-54.el6
Selinux Enabled True
Policy Type targeted
Enforcing Mode Enforcing
Plugin Name httpd_bad_labels
Host Name rhel6
Platform Linux rhel6 2.6.32-71.el6.i686 #1 SMP Wed Sep 1
01:26:34 EDT 2010 i686 i686
Alert Count 3
First Seen Mon Aug 22 18:37:48 2011
Last Seen Mon Aug 22 18:45:58 2011
Local ID 517a47e5-4a01-4415-ab7a-d7fae5be78d2
Line Numbers 78, 79, 93, 94, 101, 102

Raw Audit Messages

type=AVC msg=audit(1314031558.583:16039): avc: denied { getattr } for pid=22435 comm="httpd" path="/web" dev=dm-0 ino=9533 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=dir

type=SYSCALL msg=audit(1314031558.583:16039): arch=40000003 syscall=195 success=no exit=-13 a0=c38e80 a1=bf9bace0 a2=7abff4 a3=8000 items=0 ppid=22434 pid=22435 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=11 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)


* It seems that is an SElinux restrictions because of the 'avc: denied' tag. This trace is telling you that in order to configure /web as DocumentRoot for an apache web server it must have a file context of 'system_u:object_r:httpd_sys_content_t:s0' as /var/www/html directory. Solution : change SElinux context for /web to 'system_u:object_r:httpd_sys_content_t:s0' :

# chcon -R --reference=/var/www/html /web

* Restart httpd service and verify that is working correctly.

# /etc/init.d/httpd restart
# elinks http://127.0.0.1
SElinux example

Conclusion
: httpd daemon is confined to work only on the httpd SElinux domain. Any attempt to use files/directories outside this domain will be denied. In this particular case the httpd daemon does not started correctly because of the DocumentRoot directory /web is accessed by httpd when the daemon is started. .

No comments :

Post a Comment