pam_apparmorIn this chapter, you will learn how to set up and manage SELinux on SUSE Linux Enterprise Server. The following topics are covered:
Why Use SELinux?
Understanding SELinux
Setting up SELinux
Managing SELinux
SELinux was developed as an additional Linux security solution that uses the security framework in the Linux kernel. The purpose was to allow for a more granular security policy that goes beyond what is offered by the default existing permissions of Read, Write, and Execute, and also beyond assigning permissions to the different capabilities that are available on Linux. SELinux does this by trapping all system calls that reach the kernel, and denying them by default. This means that on a system that has SELinux enabled and nothing else configured, nothing will work. To allow your system to do anything, as an administrator you will need to write rules and put them in a policy.
An example explains why a solution such as SELinux (or its counterpart AppArmor) is needed:
“One morning, I found out that my server was hacked. The server was
running a fully patched SLES installation. A firewall was configured on
it and no unnecessary services were offered by this server. Further
analysis learned that the hacker had come in through a flaky PHP script
that was a part of one of the Apache virtual hosts that were running on
this server. The intruder had managed to get access to a shell, using the
wwwrun account that was used by
the Apache Web server. As this
wwwrun user, the intruder had
created several scripts in the /var/tmp and the
/tmp directories, which were a part of a botnet that
was launching a Distributed Denial of Service attack against a number of
servers.”
The interesting thing about this hack is that it occurred on a server where nothing was really wrong. All permissions where set OK, but the intruder had managed to get into the system. What becomes clearly evident from this example is that in some cases additional security is needed—a security that goes beyond what is offered by using SELinux. As a less complete and less complex alternative, AppArmor can be used.
AppArmor confines specific processes in their abilities to read/write and execute files (and other things). Its view is mostly that things that happen inside a process cannot escape.
SELinux instead uses labels attached to objects (e.g. files, binaries, network sockets) and uses them to determine privilege boundaries, thereby building up a level of confinement that can span more than a process or even the whole system.
SELinux was developed by the US National Security Agency (NSA), and since the beginning Red Hat has been heavily involved in its development. The first version of SELinux was offered in the era of Red Hat Enterprise Linux 4™, around the year 2006. In the beginning it offered support for essential services only, but over the years it has developed into a system that offers many rules that are collected in policies to offer protection to a broad range of services.
SELinux was developed in accordance with some certification standards like Common Criteria and FIPS 140. Because some customers specifically requested solutions that met these standards, SELinux rapidly became relatively popular.
As an alternative to SELinux, Immunix, a company that was purchased by Novell in 2005, had developed AppArmor. AppArmor was built on top of the same security principles as SELinux, but took a completely different approach, where it was possible to restrict services to exactly what they needed to do by using an easy to use wizard-driven procedure. Nevertheless, AppArmor has never reached the same status as SELinux, even if there are some good arguments to secure a server with AppArmor rather than with SELinux.
Because many organizations are requesting SELinux to be present in the Linux distributions they are using, SUSE is offering support for the SELinux framework in SUSE Linux Enterprise Server. This does not mean that the default installation of SUSE Linux Enterprise Server will switch from AppArmor to SELinux in the near future.
The SELinux framework is supported on SUSE Linux Enterprise Server. This means that SLES offers all binaries and libraries you need to be able to use SELinux on your server. However, a policy is not included and you will also miss some software that you might be familiar with from other Linux distributions. Unsupported packages of such software might be available at http://software.opensuse.org. However, these have not been tested and therefore might cause problems.
SELinux support is at a fairly early stage in SUSE Linux Enterprise Server, which means that unexpected behavior may occur. To limit this risk as much as possible, it is best to use only the binaries that have been provided by default on SUSE Linux Enterprise Server.
Before starting the configuration of SELinux, you should know a bit about how SELinux is organized. Three components play a role:
The security framework in the Linux kernel
The SELinux libraries and binaries
The SELinux policy
The default kernel of SUSE Linux Enterprise Server supports SELinux and the tools that are needed to manage it. The most important part of the work of the administrator with regard to SELinux is managing the policy.
In the SELinux policy, security labels are applied to different objects on a Linux server. These objects typically are users, ports, processes and files. Using these security labels, rules are created that define what is and what is not allowed on a server. Remember, by default SELinux denies all system calls and by creating the appropriate rules you can allow the system calls that you trust again. Rules should therefore exist for all programs that you want to use on a system. Alternatively, you might want to configure parts of a system to run in unconfined mode, which means that specific ports, programs, users, files and directories are not protected at all by SELinux. This mode is useful if you only want to use SELinux to protect some essential services, while you are not specifically worried about other services. To get a really secure system, you should try to avoid this.
To ensure the appropriate protection of your system, you need an SELinux policy. This must be a tailor-made policy in which all files are provided with a label, and all services and users have a security label as well to express which files and directories can be accessed by which user and processed on the server. Developing such a policy is a tremendous amount of work. In SUSE Linux Enterprise Server, no policy is available yet. If you want to use SELinux, you need to create your own policy.
The complexity of SELinux is also one of the main arguments against using it. Because a typical Linux system is so very complex, it is easy to overlook something and leave an opening that intruders can abuse to get into your system. And even if it is set up completely the way it should be, it still is very hard for an administrator to overlook all aspects with SELinux. With regard to the complexity, AppArmor takes a completely different approach and works with automated procedures that allow the administrator to set up AppArmor protection and understand exactly what is happening.
In SUSE Linux Enterprise Server, the SELinux framework is supported and provided. The SELinux policy is not. Therefore, you will need to either create your own policy or use a freely available policy, for example, from a Web site.
Note that a freely available SELinux policy might work on your server, but is unlikely to offer the same protection as a custom policy. SUSE also does not support third-party policies.
As mentioned, the policy is the key component in SELinux. It defines
rules that specify which objects can access which files, directories,
ports and processes on a system. To do this, a security context is
defined for all of these. On an SELinux system where the policy has been
applied to label the file system, you can use the ls
-Z command on any directory to find the security context for
the files in that directory.
Example 30.1: “Security Context Settings Using ls -Z”
shows the security context settings for the directories in the
/ directory of a SUSE Linux Enterprise Server system with an
SELinux-labeled file system.
ls -Z #root #ls -Zsystem_u:object_r:default_t .autorelabel system_u:object_r:file_t .viminfo system_u:object_r:bin_t bin system_u:object_r:boot_t boot system_u:object_r:device_t dev system_u:object_r:etc_t etc system_u:object_r:home_root_t home system_u:object_r:lib_t lib system_u:object_r:lib_t lib64 system_u:object_r:lost_found_t lost+found system_u:object_r:mnt_t media system_u:object_r:mnt_t mnt system_u:object_r:usr_t opt system_u:object_r:proc_t proc system_u:object_r:default_t root system_u:object_r:bin_t sbin system_u:object_r:security_t selinux system_u:object_r:var_t srv system_u:object_r:sysfs_t sys system_u:object_r:tmp_t tmp system_u:object_r:usr_t usr system_u:object_r:var_t var system_u:object_r:httpd_sys_content_t www
The most important line in the security context is the context type. This is the part of the security context that ends in _t. It tells SELinux which kind of access the object is allowed. In the policy, rules are specified to define which type of user or which type of role has access to which type of context. For example, this can happen by using a rule like the following:
allow user_t bin_t:file {read execute gettattr};
This example rule states that the user who has the context type
user_t (this user is referred
to as the source object) is allowed to access the file with the context
type bin_t (the target), using the permissions read,
execute and getattr.
The standard policy that you are going to use contains a huge amount of rules. To make it more manageable, policies are often split into modules. This allows administrator to switch protection on or off for different parts of the system.
When compiling the policy for your system, you will have a choice to either work with a modular policy, or a monolithic policy, where one huge policy is used to protect everything on your system. It is strongly recommended to use a modular policy and not a monolithic policy. Modular policies are much easier to manage.
The easiest way to make sure that all SELinux components are installed is by using YaST. The procedure described below shows what to do on an installed SUSE Linux Enterprise Server:
Log in to your server as root
and start YaST.
Select ›
› and select the entire C/C++ Compiler and Tools software category for installation.
› and make sure that Search in Name, Keywords and Summary
are selected. Now enter the keyword selinux and
click . You now see a list of packages.
Make sure that all the packages you have found are selected and click to install them.
After installing the SELinux packages, you need to modify the GRUB 2 boot
loader. To do this, from YaST select › › . Now add the following parameters
to the :
security=selinux selinux=1
enforcing=0
These options are used for the following purposes:
security=selinux
This option tells the kernel to use SELinux and not AppArmor
selinux=1
This option switches on SELinux
enforcing=0
This option puts SELinux in permissive mode. In this mode, SELinux is
fully functional, but does not enforce any of the security settings in
the policy. Use this mode for configuring your system. To switch on
SELinux protection, when the system is fully operational, change the
option to enforcing=1.
After installing the SELinux packages and enabling the SELinux GRUB 2 boot options, reboot your server to activate the configuration. You may notice that while rebooting, an error is displayed mentioning that the policy file could not be loaded. At this point in the configuration the error is normal and you can safely ignore it. It will disappear when you have compiled the policy.
As mentioned, the policy is an essential component of SELinux but no
default policy is available for SUSE Linux Enterprise Server. This means that you will
need to get a policy from somewhere else. The best choice is to get a
policy from the openSUSE download site at
http://software.opensuse.org. In the Package Search bar
presented at this site, type selinux-policy to get
access to a list of all open source policy packages presented at
http://openSUSE.org.
Select . The current policy
packages provided for SUSE Linux Enterprise Server are in an unstable state, but still
they are the best available option because they match the layout of the
file system on SUSE Linux Enterprise Server better than a policy for another system.
Click the link. Then
click , and
. Finally, click the
link in the row of the chosen policy source file and save it. This gives
you a file with the name
selinux-policy-2.20081210-12.2.src.rpm (the exact
name of the file might be different).
After downloading the source RPM, you can apply the following steps to install it to your server:
Extract the archive from the source RPM, using
rpm2cpio selinux-policy- >version>.src.rpm | cpio -idmv
This gives you a TAR archive in the current directory, with the name
refpolicy-version.tar.bz2.
Extract the contents of the TAR archive to the directory
/etc/selinux/refpolicy. Use
tar xvf refpolicy-version.tar.bz2 -C /etc/selinux
to do this.
Make sure that in the directory /etc/selinux there
is a file with the name config that has the
following contents:
SELINUX=permissive SELINUXTYPE=refpolicy
Edit the configuration file
/etc/selinux/refpolicy/build.conf and make sure it
includes the following parameters:
DISTRO = suse UNK_PERMS = allow DIRECT_INITRC = y MONOLITHIC = n
Make sure that you are in the directory
/etc/selinux/refpolicy and from that directory,
run the make load command. This command will take a
while to complete.
Use the dracut command to
re-create the -finitrd file. This is needed to
guarantee proper booting of the server with the policy.
When make load has completed, reboot your server.
Before doing anything else, at this point you should use the command
semanage fcontext -a -e /dev /lib/udev/devices. This
is to set a context for a critical directory that is not taken care of by
the policy by default.
At this point, all prerequisites have been met and you are ready to start
file system labeling. To do this, use the command restorecon -Rv
/. This command starts the /sbin/setfiles
command to label all files on your system. To do this, the input file
/etc/selinux/refpolicy/contexts/files/file_contexts
is used.
Because there currently is no default SELinux policy for SUSE Linux Enterprise Server,
this is a delicate part of the configuration. The
file_contexts file needs to match your actual file
system as much as possible. Otherwise, it can lead to a completely
unbootable system.
If that happens, tune the contents of the
file_contexts file to match the structure of the
file system your server is using. Before doing this, make sure to read
the rest of this chapter, so you fully understand how context type is
applied to files and directories (and do not forget to make a backup of
the file_contexts file before starting).
nobody
If, while using semanage you get a message that
complains about the home directory of
nobody, change the login shell
of user nobody to
/sbin/nologin. This makes sure that the settings of
nobody match the current
policy settings.
After another reboot SELinux should be operational. To verify this, use
the command sestatus -v. It should give you an output
that looks like the output in
Example 30.2: “Verifying that SELinux is functional”.
root #sestatus -vSELinux status: enabled SELinuxfs mount: /selinux Current mode: permissive Mode from config file: permissive Policy version: 26 Policy from config file: refpolicy Process contexts: Current context: root:staff_r:staff_t Init context: system_u:system_r:init_t /sbin/mingetty system_u:system_r:sysadm_t /usr/sbin/sshd system_u:system_r:sshd_t File contexts: Controlling term: root:object_r:user_devpts_t /etc/passwd system_u:object_r:etc_t /etc/shadow system_u:object_r:shadow_t /bin/bash system_u:object_r:shell_exec_t /bin/login system_u:object_r:login_exec_t /bin/sh system_u:object_r:bin_t -> system_u:object_r:shell_exec_t /sbin/agetty system_u:object_r:getty_exec_t /sbin/init system_u:object_r:init_exec_t /sbin/mingetty system_u:object_r:getty_exec_t /usr/sbin/sshd system_u:object_r:sshd_exec_t /lib/libc.so.6 system_u:object_r:lib_t -> system_u:object_r:lib_t /lib/ld-linux.so.2 system_u:object_r:lib_t -> system_u:object_r:ld_so_t
At this point you have a completely functional SELinux system and it is
time to further configure the system. In the current status, SELinux is
operational but not in enforcing mode. This means that it does not limit
you in doing anything, it logs everything that it should be doing if it
were in enforcing mode. This is good, because based on the log files you
can find what it is that it would prevent you from doing. As a first
test, it is a good idea to put SELinux in enforcing mode and find out if
you can still use your server after doing so. To do this, open the
/etc/selinux/config file and make sure that the
option enforcing=1 is set. Reboot your server and see if
it still comes up the way you expect it to. If it does, leave it like
that and start modifying the server in a way that everything works as
expected. Chances are though that you will not even be able to boot the
server properly. If that is the case, switch back to the mode where
SELinux is not enforcing and start tuning your server.
Before you start tuning your server, it is a good idea to verify the
SELinux installation. You have already used the command
sestatus -v to view the current mode, process, and
file contexts. Next, use semanage boolean -l, which
shows a list of all Boolean switches that are available, and at the same
time verifies that you can access the policy.
Example 30.3, “Getting a List of Booleans and Verifying Policy Access” shows part of the output of this
command.
root #semanage boolean -lSELinux boolean Description ftp_home_dir -> off ftp_home_dir mozilla_read_content -> off mozilla_read_content spamassassin_can_network -> off spamassassin_can_network httpd_can_network_relay -> off httpd_can_network_relay openvpn_enable_homedirs -> off openvpn_enable_homedirs gpg_agent_env_file -> off gpg_agent_env_file allow_httpd_awstats_script_anon_write -> off allow_httpd_awstats_script_anon_write httpd_can_network_connect_db -> off httpd_can_network_connect_db allow_ftpd_full_access -> off allow_ftpd_full_access samba_domain_controller -> off samba_domain_controller httpd_enable_cgi -> off httpd_enable_cgi virt_use_nfs -> off virt_use_nfs
Another command that should produce output at this stage is
semanage fcontext -l. This command shows the default
file context settings as provided by the policy (see
Example 30.4: “Getting File Context Information”
for partial output of this command).
root #semanage fcontext -l/var/run/usb(/.*)? all files system_u:object_r:hotplug_var_run_t /var/run/utmp regular file system_u:object_r:initrc_var_run_t /var/run/vbe.* regular file system_u:object_r:hald_var_run_t /var/run/vmnat.* socket system_u:object_r:vmware_var_run_t /var/run/vmware.* all files system_u:object_r:vmware_var_run_t /var/run/vpnc(/.*)? all files system_u:object_r:vpnc_var_run_t /var/run/watchdog\.pid regular file system_u:object_r:watchdog_var_run_t /var/run/winbindd(/.*)? all files system_u:object_r:winbind_var_run_t /var/run/wnn-unix(/.*) all files system_u:object_r:canna_var_run_t /var/run/wpa_supplicant(/.*)? all files system_u:object_r:NetworkManager_var_run_t /var/run/wpa_supplicant-global socket system_u:object_r:NetworkManager_var_run_t /var/run/xdmctl(/.*)? all files system_u:object_r:xdm_var_run_t /var/run/yiff-[0-9]+\.pid regular file system_u:object_r:soundd_var_run_t
The base SELinux configuration is now operational and it can now be configured to secure your server. In SELinux, an additional set of rules is used to define exactly which process or user can access which files, directories, or ports. To do this, SELinux applies a context to every file, directory, process, and port. This context is a security label that defines how this file, directory, process, or port should be treated. These context labels are used by the SELinux policy, which defines exactly what should be done with the context labels. By default, the policy blocks all non-default access, which means that, as an administrator, you need to enable all features that are non-default on your server.
As mentioned, files, directories, and ports can be labeled. Within each
label, different contexts are used. To be able to perform your daily
administration work, the type context is what you are most interested
in. As an administrator, you will mostly work with the type context.
Many commands allow you to use the -Z option to show a
list of current context settings. In
Example 30.5: “The default context for directories in the root directory”
you can see what the context settings are for the directories in the
root directory.
root #ls -Zdr-xr-xr-x. root root system_u:object_r:bin_t:s0 bin dr-xr-xr-x. root root system_u:object_r:boot_t:s0 boot drwxr-xr-x. root root system_u:object_r:cgroup_t:s0 cgroup drwxr-xr-x+ root root unconfined_u:object_r:default_t:s0 data drwxr-xr-x. root root system_u:object_r:device_t:s0 dev drwxr-xr-x. root root system_u:object_r:etc_t:s0 etc drwxr-xr-x. root root system_u:object_r:home_root_t:s0 home dr-xr-xr-x. root root system_u:object_r:lib_t:s0 lib dr-xr-xr-x. root root system_u:object_r:lib_t:s0 lib64 drwx------. root root system_u:object_r:lost_found_t:s0 lost+found drwxr-xr-x. root root system_u:object_r:mnt_t:s0 media drwxr-xr-x. root root system_u:object_r:autofs_t:s0 misc drwxr-xr-x. root root system_u:object_r:mnt_t:s0 mnt drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 mnt2 drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 mounts drwxr-xr-x. root root system_u:object_r:autofs_t:s0 net drwxr-xr-x. root root system_u:object_r:usr_t:s0 opt dr-xr-xr-x. root root system_u:object_r:proc_t:s0 proc drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 repo dr-xr-x---. root root system_u:object_r:admin_home_t:s0 root dr-xr-xr-x. root root system_u:object_r:bin_t:s0 sbin drwxr-xr-x. root root system_u:object_r:security_t:s0 selinux drwxr-xr-x. root root system_u:object_r:var_t:s0 srv -rw-r--r--. root root unconfined_u:object_r:swapfile_t:s0 swapfile drwxr-xr-x. root root system_u:object_r:sysfs_t:s0 sys drwxrwxrwt. root root system_u:object_r:tmp_t:s0 tmp -rw-r--r--. root root unconfined_u:object_r:etc_runtime_t:s0 tmp2.tar -rw-r--r--. root root unconfined_u:object_r:etc_runtime_t:s0 tmp.tar drwxr-xr-x. root root system_u:object_r:usr_t:s0 usr drwxr-xr-x. root root system_u:object_r:var_t:s0 var
In the listing above, you can see the complete context for all
directories. It consists of a user, a role, and a type. The s0 setting
indicates the security level in Multi Level Security environments. These
environments are not discussed here. In such an environment, make sure
that s0 is set. The Context Type defines what kind of activity is
permitted in the directory. Compare, for example, the
/root directory, which has the
admin_home_t context type, and the
/home directory, which has the
home_root_t context type. In the SELinux policy,
different kinds of access are defined for these context types.
Security labels are not only associated with files, but also with other items, such as ports and processes. In Example 30.6: “Showing SELinux settings for processes” for example you can see the context settings for processes on your server.
root #ps ZauxLABEL USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND system_u:system_r:init_t root 1 0.0 0.0 10640 808 ? Ss 05:31 0:00 init [5] system_u:system_r:kernel_t root 2 0.0 0.0 0 0 ? S 05:31 0:00 [kthreadd] system_u:system_r:kernel_t root 3 0.0 0.0 0 0 ? S 05:31 0:00 [ksoftirqd/0] system_u:system_r:kernel_t root 6 0.0 0.0 0 0 ? S 05:31 0:00 [migration/0] system_u:system_r:kernel_t root 7 0.0 0.0 0 0 ? S 05:31 0:00 [watchdog/0] system_u:system_r:sysadm_t root 2344 0.0 0.0 27640 852 ? Ss 05:32 0:00 /usr/sbin/mcelog --daemon --config-file /etc/mcelog/mcelog.conf system_u:system_r:sshd_t root 3245 0.0 0.0 69300 1492 ? Ss 05:32 0:00 /usr/sbin/sshd -o PidFile=/var/run/sshd.init.pid system_u:system_r:cupsd_t root 3265 0.0 0.0 68176 2852 ? Ss 05:32 0:00 /usr/sbin/cupsd system_u:system_r:nscd_t root 3267 0.0 0.0 772876 1380 ? Ssl 05:32 0:00 /usr/sbin/nscd system_u:system_r:postfix_master_t root 3334 0.0 0.0 38320 2424 ? Ss 05:32 0:00 /usr/lib/postfix/master system_u:system_r:postfix_qmgr_t postfix 3358 0.0 0.0 40216 2252 ? S 05:32 0:00 qmgr -l -t fifo -u system_u:system_r:crond_t root 3415 0.0 0.0 14900 800 ? Ss 05:32 0:00 /usr/sbin/cron system_u:system_r:fsdaemon_t root 3437 0.0 0.0 16468 1040 ? S 05:32 0:00 /usr/sbin/smartd system_u:system_r:sysadm_t root 3441 0.0 0.0 66916 2152 ? Ss 05:32 0:00 login -- root system_u:system_r:sysadm_t root 3442 0.0 0.0 4596 800 tty2 Ss+ 05:32 0:00 /sbin/mingetty tty2
In SELinux, three different modes can be used:
This is the default mode. SELinux protects your server according to the rules in the policy, and SELinux logs all of its activity to the audit log.
This mode is useful for troubleshooting. If set to Permissive, SELinux does not protect your server, but it still logs everything that happens to the log files. Also, in permissive mode, the Linux kernel still maintains the SELinux labels in the file system. This is good, because this prevents your system from relabeling everything after turning SELinux on again.
This mode is to be deactivated. In disabled mode, SELinux is switched off completely and no logging occurs. The file system labels however are not removed from the file system.
You have already read how you can set the current SELinux mode from GRUB 2 while booting using the enforcing boot parameter.
An important part of the work of an administrator is setting context types on files to ensure appropriate working of SELinux.
If a file is created within a specific directory, it inherits the context type of the parent directory by default. If, however, a file is moved from one location to another location, it retains the context type that it had in the old location.
To set the context type for files, you can use the semanage
fcontext command. With this command, you write the new context
type to the policy, but it does not change the actual context type
immediately! To apply the context types that are in the policy, you need
to run the restorecon command afterwards.
The challenge when working with semanage fcontext is
to find out which context you actually need. You can use
semanage fcontext -l to show a list of all contexts
in the policy, but it might be a bit hard to find out the actual context
you need from that list as it is rather long (see
Example 30.7: “Viewing Default File Contexts”).
root #semanage fcontext -l | lessSELinux fcontext type Context / directory system_u:object_r:root_t:s0 /.* all files system_u:object_r:default_t:s0 /[^/]+ regular file system_u:object_r:etc_runtime_t:s0 /\.autofsck regular file system_u:object_r:etc_runtime_t:s0 /\.autorelabel regular file system_u:object_r:etc_runtime_t:s0 /\.journal all files X:>>None>> /\.suspended regular file system_u:object_r:etc_runtime_t:s0 /a?quota\.(user|group) regular file system_u:object_r:quota_db_t:s0 /afs directory system_u:object_r:mnt_t:s0 /bin directory system_u:object_r:bin_t:s0 /bin/.* all files system_u:object_r:bin_t:s0
There are three ways to find out which context settings are available for your services:
Install the service and look at the default context settings that are used. This is the easiest and recommended option.
Consult the man page for the specific service. Some services have a
man page that ends in _selinux, which contains all
the information you need to find the correct context settings.
When you have found the right context setting, apply it using
semanage fcontext. This command takes
-t context type as its first argument, followed by
the name of the directory or file to which you want to apply the
context settings. To apply the context to everything that already
exists in the directory where you want to apply the context, you add
the regular expression (/.*)? to the name of the
directory. This means: optionally, match a slash followed by any
character. The examples section of the semanage man
page has some useful usage examples for semanage.
Use seinfo -t to display a list of all context
types that are available on your system. Since the command by itself
outputs an overwhelming amount of information, it should be used in
combination with grep or a similar command for
filtering.
To help you apply the SELinux context properly, the following procedure
shows how to set a context using semanage fcontext
and restorecon. You will notice that at first
attempt, the Web server with a non-default document root does not work.
After changing the SELinux context, it will.
Use mkdir /web and then go to that directory using
cd /web.
Use a text editor to create the file
/web/index.html that contains the text welcome to
my Web site.
Open the file /etc/apache2/default-server.conf
with an editor, and change the DocumentRoot line to
DocumentRoot /web
Start the Apache Web server, using service apache2
start.
Use w3m localhost to open a session to your local
Web server. You will receive a Connection refused message. Press
Enter, and then q to quit w3m.
Use ls -Z /srv/www to find the current context type
for the default Apache DocumentRoot, which is
/srv/www/htdocs. It should be set to
httpd_sys_content_t.
Use semanage fcontext -a -f ""-t httpd_sys_content_t
'/web(/.*) ?' to set the new context in the policy and press
Enter.
Now use restorecon /web to apply the new context
type.
Use ls -Z /web to show the context of the files in
the directory /web. You will see that the new
context type has been set properly to the /web
directory, but not to its contents.
Use restorecon -R /web to apply the new context
recursively to the /web directory. The type
context has now been set correctly.
Restart the Web server, using service apache2
restart. You should now be able to access the contents of
the /web directory.
The easiest way to change the behavior of the policy is by working with
Booleans. These are on-off switches that you can use to change the
settings in the policy. To find out which Booleans are available, you
can use the semanage boolean -l command. It will show
you a long list of Booleans, with a short description of what each of
these Booleans will do for you. When you have found the Boolean you want
to set, you can use setsebool -P, followed by the
name of the Boolean that you want to change. It is important to use the
-P option at all times when using setsebool. This
option writes the setting to the policy file on disk, and this is the
only way to make sure that the Boolean is applied automatically after a
reboot.
The procedure below gives an example of changing Boolean settings
From a root shell, type semanage boolean -l | grep
ftp. This shows a list of Booleans that are related to FTP
servers.
Use setsebool allow_ftpd_anon_write off to switch
off this Boolean. Notice that it does not take much time to write the
change. Use semanage boolean -l|grep ftpd_anon to
verify that the Boolean is indeed turned on.
Reboot your server.
Check again to see if the allow_ftpd_anon_write
Boolean is still turned on. As it has not yet been written to the
policy, you will notice that it is off.
Use setsebool -P allow_ftpd_anon_write on to switch
the Boolean and write the setting to the policy.
You have compiled SELinux as modular. This means that the policy that
implements SELinux features is not just one huge policy, but it consists
of many smaller modules. Each module covers a specific part of the
SELinux configuration. The concept of the SELinux module was introduced
to make it easier for third party vendors to make their services
compatible with SELinux. To get an overview of the SELinux modules, you
can use the semodule -l command. This command shows a
list of all current modules in use by SELinux and their version numbers.
As an administrator, you can switch modules on or off. This can be
useful if you want to disable only a part of SELinux and not everything
to run a specific service without SELinux protection. Especially in the
case of SUSE Linux Enterprise Server, where there is not a completely supported SELinux
policy yet, it can make sense to switch off all modules that you do not
need so that you can focus on the services that really do need SELinux
protection. To switch off an SELinux module, use semodule -d
modulename. If you want to switch it on again, you can use
semodule -e modulename. Using this command will
change the current state of the module in the
/etc/selinux/refpolicy/policy/modules.conf file.
Alternatively, you could also edit this file by hand.
To handle policy modules properly, it helps to understand what you are
dealing with. In the end, a policy module is a compiled policy file that
you can load using the semodule -e command. You can
recognize these files by the extension they use:
*.pp (which stands for Policy Package). In some
cases it can be useful to modify modules to have them do exactly what
you need them to do. Three different kinds of files are used as input
files for policy modules and you can find them in subdirectories of the
/etc/selinux/refpolicy/policy/modules directory:
*.te files contain transition rules. These rules
tell the policy how to deal with specific subprocesses that are
started. You will not often change these as an administrator.
*.if files define what exactly the policy should
be doing. As an administrator you do not typically change the contents
of these files.
*.fc files contain the labeling instructions that
apply to this policy. As an administrator, you might want to change
the contents of the .fc files to modify the
default behavior of policies.
In
Example 30.8: “The First 20 Lines of apache.fc”
below you can see the first 20 lines of the
apache.fc file. This is the file that contains the
default file contexts that are used for the Apache server.
apache.fc #/etc/apache(2)?(/.*)? gen_context(system_u:object_r:httpd_config_t,s0) /etc/apache-ssl(2)?(/.*)? gen_context(system_u:object_r:httpd_config_t,s0) /etc/htdig(/.*)? gen_context(system_u:object_r:httpd_sys_content_t,s0) /etc/httpd -d gen_context(system_u:object_r:httpd_config_t,s0) /etc/httpd/conf.* gen_context(system_u:object_r:httpd_config_t,s0) /etc/httpd/logs gen_context(system_u:object_r:httpd_log_t,s0) /etc/httpd/modules gen_context(system_u:object_r:httpd_modules_t,s0) /etc/vhosts -- gen_context(system_u:object_r:httpd_config_t,s0) /srv/([^/]*/)?www(/.*)? gen_context(system_u:object_r:httpd_sys_content_t,s0) /srv/gallery2(/.*)? gen_context(system_u:object_r:httpd_sys_content_t,s0) /usr/bin/htsslpass -- gen_context(system_u:object_r:httpd_helper_exec_t,s0) /usr/lib/apache-ssl/.+ -- gen_context(system_u:object_r:httpd_exec_t,s0) /usr/lib/cgi-bin(/.*)? gen_context(system_u:object_r:httpd_sys_script_exec_t,s0) /usr/lib(64)?/apache(/.*)? gen_context(system_u:object_r:httpd_modules_t,s0) /usr/lib(64)?/apache2/modules(/.*)? gen_context(system_u:object_r:httpd_modules_t,s0)
In the fc file, you will be able to recognize
different elements. First is the name of the directory or file to which
the file context will apply. As you can see, variables can be used (as
is the case in the first line that starts with
HOME_DIR), and typically, regular expressions will be
used as well. Next, the gen_context command tells the policy to which
context the files related to the policy module should be set. This is
the same context setting that you can see when using ls
-Z on the file or directory.
As an administrator, you do not typically change the contents of the
policy files that come from the SELinux Policy RPM. You would rather use
semanage fcontext to change file contexts. If you are
using audit2allow to generate policies for your
server, you might want to change the policy files after all. If you want
to change the contents of any of the policy module files, you will need
to compile the changes into a new policy module file. To do this, copy
or link the SELinux Makefile from
/etc/selinux/refpolicy to the directory that
contains the policy module input files and run the following command to
compile the module:
root #make&&make install&&make load
When make has completed, you can manually load the
modules into the system, using semodule -e.
By default, if SELinux is the reason why something is not working, a log
message to this effect is sent to the
/var/log/audit/audit.log file. That is, if the
auditd service is running. If you see an empty
/var/log/audit, start the auditd service using
systemctl start auditd.service and enable it in the
targets of your system, using sudo systemctl enable
auditd.service. In
Example 30.9: “Example Lines from /etc/audit/audit.log”
you can see a partial example of the contents of
/var/log/audit/audit.log
/etc/audit/audit.log #type=DAEMON_START msg=audit(1348173810.874:6248): auditd start, ver=1.7.7 format=raw kernel=3.0.13-0.27-default auid=0 pid=4235 subj=system_u:system_r:auditd_t res=success
type=AVC msg=audit(1348173901.081:292): avc: denied { write } for pid=3426 comm="smartd" name="smartmontools" dev=sda6 ino=581743 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir
type=AVC msg=audit(1348173901.081:293): avc: denied { remove_name } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir
type=AVC msg=audit(1348173901.081:294): avc: denied { unlink } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.081:295): avc: denied { rename } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582373 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.081:296): avc: denied { add_name } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir
type=AVC msg=audit(1348173901.081:297): avc: denied { create } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.081:298): avc: denied { write open } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.081:299): avc: denied { getattr } for pid=3426 comm="smartd" path="/var/lib/smartmontools/smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.309:300): avc: denied { append } for pid=1316
comm="rsyslogd" name="acpid" dev=sda6 ino=582296 scontext=system_u:system_r:syslogd_t tcontext=system_u:object_r:apmd_log_t tclass=file
At first look, the lines in audit.log are a bit hard
to read. However, on closer examination they are not that hard to
understand. Every line can be broken down into sections. For example, the
sections in the last line are:
type=AVC:
every SELinux-related audit log line starts with the type
identification type=AVC
msg=audit(1348173901.309:300):
This is the time stamp, which unfortunately is written in epoch time,
the number of seconds that have passed since Jan 1, 1970. You can use
date -d on the part up to the dot in the epoch time
notation to find out when the event has happened:
root #date -d @1348173901Thu Sep 20 16:45:01 EDT 2012
avc: denied { append }:the specific action that was denied. In this case the system has denied the appending of data to a file. While browsing through the audit log file, you can see other system actions, such as write open, getattr and more.
for pid=1316:the process ID of the command or process that initiated the action
comm="rsyslogd":the specific command that was associated with that PID
name="acpid":the name of the subject of the action
dev=sda6 ino=582296:the block device and inode number of the file that was involved
scontext=system_u:system_r:syslogd_t:the source context, which is the context of the initiator of the action
tclass=file:a class identification of the subject
Instead of interpreting the events in audit.log yourself, there is
another approach. You can use the audit2allow command,
which helps analyze the cryptic log messages in
/var/log/audit/audit.log. An audit2allow
troubleshooting session always consists of three different commands.
First, you would use audit2allow -w -a to present the
audit information in a more readable way. The audit2allow -w
-a by default works on the audit.log file. If you want to
analyze a specific message in the audit.log file, copy it to a temporary
file and analyze that, using audit2allow -w -i
filename:
root #audit2allow -w -i testfiletype=AVC msg=audit(1348173901.309:300): avc: denied { append } for pid=1316 comm="rsyslogd" name="acpid" dev=sda6 ino=582296 scontext=system_u:system_r:syslogd_t tcontext=system_u:object_r:apmd_log_t tclass=file
Missing type enforcement (TE) allow rule.
You can use audit2allow to generate a loadable
module to allow this access.
To find out which specific rule has denied access, you can use
audit2allow -a to show the enforcing rules from all
events that were logged to the audit.log file, or
audit2allow -i filename to show it for messages that
you have stored in a specific file:
root #audit2allow -i testfile#============= syslogd_t ============== allow syslogd_t apmd_log_t:file append;
As the last part, use audit2allow -a -M mymodule to
create an SELinux module with the name mymodule that
you can load in order to allow the access that was previously denied. If
you want to do this for all events that have been logged to the
audit.log, use the -a -M command arguments. To do it
only for specific messages that are in a specific file, use -i
-M as in the example below:
root #audit2allow -i testfile -M example******************** IMPORTANT *********************** To make this policy package active, execute: semodule -i example.pp
As indicated by the audit2allow command, you can now
run this module by using the semodule -i command,
followed by the name of the module that audit2allow
has created for you (example.pp in the above
example).
With everything you have done so far, you still cannot switch SELinux to enforcing mode. This is because of a misconfiguration in the context types for some files. If you switch to enforcing mode now, you can see that many AVC denied messages are written that are related to the tmpfs, and following these messages your system hangs with the message “INIT: Id "1" respawning too fast”.
[ 5.595812] type=1400 audit(1361363803.588:3): avc: denied { read write }
for pid=431 comm="sh" name="console" dev=tmpfs ino=2513
scontext=system_u:system_r:sysadm_t tcontext=system_u:object_r:tmpfs_t
tclass=chr_file
[ 5.607734] type=1400 audit(1361363803.604:4): avc: denied { read write } for
pid=431 comm="sh" path="/dev/console" dev=tmpfs ino=2513
scontext=system_u:system_r:sysadm_t tcontext=system_u:object_r:tmpfs_t
tclass=chr_fileAs you will see, this message is repeated several times.
To fix this problem, reboot your computer in permissive mode. Copy the
/var/log/audit/audit.log file to a temporary file
(like /var/log/audit/audit.2allow) and remove all
lines with the exception of the lines that contain the audit log messages
for the errors listed above. Assuming that the name of the log file that
you have created is audit.2allow, you should now run
the following command: audit2allow -i audit.2allow -M
bootme.
This creates a policy module file with the name
bootme.pe. Make sure that this module is included in
your SELinux configuration by using semodule -i
bootme.pp. Now reboot your computer in enforcing mode. You will
be able to boot and log in as root in your SELinux-protected system. If
this is not the case, you will need to repeat this procedure until you
have no more messages in your audit.log that refer
to path="/dev/console" dev=tmpfs. This may involve
several reboots.
From here, the fine tuning begins. You will notice that many items on
your system do not work yet. You will need to fix them one by one. The
approach for fixing all of these errors is by using
audit2allow as described in the above example, and by
setting the appropriate context on files and directories on your system.
Until a supported version of the SELinux policy is provided with
SUSE Linux Enterprise Server, you will need to follow this approach to get it to work.
At least using this procedure does allow you to configure a computer with
the very detailed security settings that are offered with SELinux and
will make your system more secure than when using other solutions.