Building a Basic Policy
Building a Basic Policy
The objective of this section is to show how policy files are constructed, compiled and loaded using the SELinux command line tools and editors such as vi or gedit to produce a usable policy for instructional use only.
A modular (with loadable modules) policy is built without the use of any support macros or make files from the Reference Policy source.
Important Note: While these are simple policies, they are built to support X-Windows therefore an x_contexts file must be installed. This file is required by the X-Windows SELinux object manager.
It is recommended that the [Notebook Source] file is installed in your $HOME as this contains all the configuration files and source code required to produce the required modules. It also contains README and a simple Makefile for each section.
The main objectives of the sections that follow are to:
- Show how to construct and build a simple base policy.
- Show how to construct and build a series of loadable modules for use with the base module. This builds into a very simple message filter using a network client / server application and file moving (filter) application (TODO).
- Demonstrate simple X-Windows select and paste applications using customised x_contexts files to show the different between standard (as used by the Reference Policy) and polyinstantiation selections using the XSELinux object manager / XACE services.
- Build a test application that allows the XSELinux SELinuxGet.. and SELinuxSet.. functions to be tested.
To be able to build the policy files only standard SELinux utilities are required. However to build the test “C” programs development tools will be required, therefore ensure that the following are installed:
- gcc tools to compile and link the test applications (gcc and libgcc packages).
- The libselinux library and libselinux-devel packages.
- For the X-Windows examples the the following will also be required:
- The Xlibpackages libX11, libX11-common and libX11-devel.
- For retrieving Xdevice information libXi and libXi-devel.
If the NetLabel module is being built, the NetLabel tools will need to be installed as they are not part of the standard F-12 installation (netlabel_tools).
If the Tresys utilities are used (apol, sechecker etc.), then it is recommended that the policies are built uncompressed by adding the following entry in the semanage.conf file:
The Test Policies
Normally SELinux policies are built to deny everything by default, and then enable access as required, however the example policies in this section grant access to everything and then run the test applications in their own domains to isolate them.
The policies built in this section have been tested using the follow sequence:
- Will the system load, allow users to logon and run applications in permissive mode - If yes then:
- Set the system to enforcing mode by setenforce 1, if still okay then:
- Log out users and log in again (as now in enforcing mode, the login may fail), if okay then:
- Edit the config file and set SELINUX=enforcing, then reboot the system, if okay then:
- Log in users and run applications, if okay then:
- Test that the policy meets the security requirements.
If at any stage the load fails, then the repair CD/DVD may have to be used to investigate the cause. Setting the config file SELINUX entry to permissive and investigating the messages and audit logs can be helpful (but not always).
Building the Policy Source Files
There are at least three ways to build a monolithic or base policy source file to experiment with:
- Use the samples shown in this section that are valid for F-12. However as SELinux gets updated, the object classes and their associated permissions do change, therefore these samples may not be correct for other versions or distributions.
- Rebuild the source files using the flask security_classes, initial_sids and access_vectors files from the Reference Policy source appropriate to the GNU / Linux distribution being used. The policy statements must then be added as necessary.
The buildpolicy script [buildpolicy ] can be used to produce the complete policy automatically using the Reference Policy flask security_classes, initial_sids and access_vectors files.
- There is an article [SELinux From Scratch] that describes a process using a C program and some scripts for building a test policy from the GNU / Linux kernel source tree. This process has since been enhanced and built into the kernel source tree from version 2.6.28, where the following files can be found that describe and build the “make dummy policy”(mdp):
Documentation/SELinux.txt scripts/Makefile scripts/selinux/Makefile scripts/selinux/README scripts/selinux/install_policy.sh scripts/selinux/mdp/Makefile scripts/selinux/mdp/dbus_contexts scripts/selinux/mdp/mdp.c
Policy Source File
The modular policy base.conf source is as follows [base.conf] with Table 1 describing the core policy components.
|Security Classes (class)|| These are from the Reference Policy (build 20091117) files as they have the correct X-Windows classes:
|Access Vectors (permissions)|
|MLS Sensitivity, category and level Statements||There are no MLS security level information in the sample policy.|
|MLS Constraints||There are no MLS constraints in the sample policy.|
|Policy Capability Statements||There are no policycap statements in the sample policy, however one is added later for a NetLabel exercise using network_peer_controls.|
|Attributes||There are no attributes in the sample policy.|
|Booleans||There are no bool statements in the sample policy.|
|Type / Type Alias||There is only one type: unconfined_t. There are no typealias statements.|
|Roles||There is only one role: unconfined_r.|
|Policy Rules|| There is one allow rule for each object class (taken from the security_classes file) in the policy that allows unrestricted access to all its permissions as follows:
allow unconfined_t self : class_name *;
|Users||There is one user: user_u, for logging on. The system_u user is there to allow objects to be labeled system_u:object_r as in the standard Reference Policy. The system_u user is also required by semanage(8) to add network objects.|
|Constraints||These are no constraints in the sample policy, however one is added later to show role constraints.|
|Default SID labeling||These have been taken from the standard Reference Policy build with the security contexts updated. Note that the kernel is labeled unconfined_r and not object_r.|
|fs_use_xattr Statement||Only the ext3 and ext4 filesystems have been added. If the system being built supports other filesystems then these will need to be added.|
|fs_use_task and fs_use_trans Statements|| These have been taken from the standard Reference Policy build.
|genfscon Statements||Only a selection have been taken from the standard Reference Policy build.|
|portcon, netifcon and nodecon Statements||There are none of these statements in the policy.|
The following may help with resolving issues when building the examples:
- If the files are cut from this document and then pasted into a GNU / Linux editor (such as vi or gedit) as a text file, then there could be a cr at the end of each line. This can cause problems with some compliers such as checkpolicy and checkmodule. To remove the cr use the following command:
cat <file_name> | tr -d \\r >new_file_name
- Once the policies etc. have been built and all goes well, the filesystem will relabeled and the new policy loaded during the reboot process, however any errors encountered will probably result in either:
- GNU / Linux hanging, in which case the repair disk will be required. To allow GNU / Linux to load, the /etc/selinux/config file should be edited to set either SELINUX=disabled or the SELINUXTYPE= to a known working policy. The reason for the hang can then be investigated (such as correcting the policy source files and/or re-running the build commands).
- The policy will be rejected by the kernel and not loaded, GNU / Linux will then load with no policy enabled, giving another chance at fixing the problem (the screen messages will generally give the reason for the rejection).
Building the Base Policy Module
This exercise will build the mandatory base policy module that uses the same policy source file as the monolithic policy discussed above.
The basic steps to produce a simple base test policy are:
- Ensure you are logged on as root and SELinux is running in permissive mode (setenforce 0) to perform the build process. It is assumed that the files are built in the ./notebook-source/modular-base-policy directory.
- Produce a base policy source file with a text editor (such as vi or gedit) containing the following contents: [base.conf].
- Produce a base file contexts file with the following contents: [base.fc]. This will be used to relabel the file system.
- Produce a default_contexts file with the folowing contents [default_contexts]. This will be used to ensure that the correct context is used for the logon process (only really needed when the additional loadable modules are built).
- Produce an seusers file with the following contents: [seusers].
- Produce a dbus_contexts file with the following contents: [dbus_contexts]. This is required for X-Windows to load as it uses the dbus messaging service that has a SELinux user space object manager.
- Produce a x_contexts file with the following contents: [x_contexts]. This is required for the X-Windows object manager.
- Compile the policy with checkmodule to produce an intermediate binary policy file:
checkmodule -o base.mod base.conf
The output from the compilation should be:
checkmodule: loading policy configuration from base.conf checkmodule: policy configuration loaded checkmodule: writing binary representation (version 10) to base.mod
- Package the policy with semodule_package, this will produce a base policy module file (note - if successful there are no output messages):
semodule_package -o base.pp -m base.mod -f base.fc -s seusers
- Make the following directories to store the policy:
mkdir /etc/selinux/modular-test/policy mkdir -p /etc/selinux/modular-test/contexts/files mkdir -p /etc/selinux/modular-test/modules/active/modules
- Copy the following files to SELinux policy area:
cp seusers /etc/selinux/modular-test cp dbus_contexts /etc/selinux/modular-test/contexts cp default_contexts /etc/selinux/modular-test/contexts cp x_contexts /etc/selinux/modular-test/contexts
- Install the base policy with semodule. This will produce a base policy and a number of files, some of which will be empty (note - if successful there are no output messages):
semodule -s modular-test -b base.pp
- The file and directory list in the /etc/selinux/modular-test directory area should now consist of the following:
/etc/selinux/modular-test: drwxr-xr-x. 3 root root 4096 2010-02-28 15:57 contexts drwxr-xr-x. 3 root root 4096 2010-02-28 15:57 modules drwxr-xr-x. 2 root root 4096 2010-02-28 15:57 policy -rw-r--r--. 1 root root 51 2010-02-28 15:57 seusers /etc/selinux/modular-test/contexts: -rw-r--r--. 1 root root 195 2010-02-28 15:57 dbus_contexts -rw-r--r--. 1 root root 53 2010-02-28 15:57 default_contexts drwxr-xr-x. 2 root root 4096 2010-02-28 15:57 files -rw-r--r--. 1 root root 0 2010-02-28 15:57 netfilter_contexts -rw-r--r--. 1 root root 2764 2010-02-28 15:57 x_contexts /etc/selinux/modular-test/contexts/files: -rw-r--r--. 1 root root 68 2010-02-28 15:57 file_contexts -rw-r--r--. 1 root root 0 2010-02-28 15:57 file_contexts.homedirs /etc/selinux/modular-test/modules: drwx------. 3 root root 4096 2010-02-28 15:57 active -rw-------. 1 root root 0 2010-02-28 15:57 semanage.read.LOCK -rw-------. 1 root root 0 2010-02-28 15:57 semanage.trans.LOCK /etc/selinux/modular-test/modules/active: -rw-r--r--. 1 root root 22625 2010-02-28 15:57 base.pp -rw-------. 1 root root 32 2010-02-28 15:57 commit_num -rw-------. 1 root root 68 2010-02-28 15:57 file_contexts -rw-r--r--. 1 root root 0 2010-02-28 15:57 file_contexts.homedirs -rw-------. 1 root root 68 2010-02-28 15:57 file_contexts.template -rw-------. 1 root root 0 2010-02-28 15:57 homedir_template drwx------. 2 root root 4096 2010-02-28 15:57 modules -rw-------. 1 root root 0 2010-02-28 15:57 netfilter_contexts -rw-r--r--. 1 root root 12457 2010-02-28 15:57 policy.kern -rw-------. 1 root root 51 2010-02-28 15:57 seusers.final -rw-------. 1 root root 25 2010-02-28 15:57 users_extra /etc/selinux/modular-test/modules/active/modules: /etc/selinux/modular-test/policy: -rw-r--r--. 1 root root 12457 2010-02-28 15:57 policy.24
- Edit the /etc/selinux/config file and change the entries shown. This will set permissive mode and the policy location that will be loaded on the next re-boot. Note - do not put any spaces after these entries.
This will set permissive mode so if the policy is too restrictive it will still allow a login at least. The SELinux policy name/location is also added (modular-test). Note do not put any spaces after the entries.
- To allow a file system relabeling to be actioned on reboot execute the following command:
- Optionally clear the log files so that they are clear for easier reading:
> /var/log/messages > /var/log/audit/audit.log
- Reboot the system. During the boot process, the file system should be re-labeled.
Checking the Base Policy Build
Once the system has reloaded, SELinux will be running in permissive mode. Logon as root and use either seaudit, troubleshooter or simply tail in a couple of terminal windows to view the logs:
* In one terminal window run: tail -f /var/log/messages * In another terminal window run: tail -f /var/log/audit/audit.log
There should be entries for the boot process in the /var/log/messages file, however the /var/log/audit/audit.log file should only contain entries for the audit daemon, user logon and role change for the logon process.
If the system is working (i.e. it should be stable, load the desktop and allow utilities to be loaded from the menus), then SELinux can be set to enforcing mode by:
The new policy will be enforced and the only entries in the logs should be about setting enforcing mode.
If the system is unstable when rebooted, then see the Problem Resolution section for a possible resolution.