Share your story
The central voice for Linux and Open Source security news
Home News Topics Advisories HOWTOs Features Newsletters About Register

Sign up!
EnGarde Community
What is the most important Linux security technology?
Linux Events
Linux User Groups
Link to Us
Security Center
Book Reviews
Security Dictionary
Security Tips
White Papers
Featured Blogs
All About Linux
DanWalsh LiveJournal
Latest Newsletters
Linux Security Week: March 30th, 2015
Linux Advisory Watch: March 27th, 2015
LinuxSecurity Newsletters
Choose Lists:
About our Newsletters
RSS Feeds
Get the LinuxSecurity news you want faster with RSS
Powered By

Hacks From Pax: SELinux Policy Development Print E-mail
User Rating:      How can I rate this item?
Posted by Pax Dickinson   
SELinux Hi, and welcome to the final entry in my series of articles on SELinux. My last three articles have provided an overview and history of SELinux, discussed how SELinux makes access decisions, and explained how to administer an SELinux system. Today we'll build on the SELinux knowledge we've gained and learn how to perform basic customization of our system's security policy.

Customizing your system's SELinux policy can be necessary when running an application your policy is unaware of. Particularly, web based applications might need customization of Apache policy in order to run properly.

Setting Up a Policy Development Environment

For the purposes of this article, I'll assume you have a server running EnGarde Secure Community 3.0 (a free downloadable ISO image is available). Engarde Secure Linux is a good base for learning SELinux policy since it is a server system only, which allows for a policy that is easier to understand than distributions such as Fedora which include many policy modules for X11 and other desktop applications.

First, log in as root and transition to the sysadm_r role. Generally policy development is best done with SELinux in permissive mode, so use the setenforce command to set the proper mode. Be sure your system is upgraded to the latest release by issuing the apt-get update command, and then install the necessary policy development packages by entering apt-get install make m4 gcc python engarde-policy-sources. Other packages may be installed due to dependencies.

Compiling Policy

Once this is done, you should change to the policy sources directory which is /etc/selinux/engarde/src/policy/. The main part of the policy sources is the policy/modules directory, which contains directories that contain your actual policy source modules for all services and applications constrained by SELinux.

The first time you compile a policy, you must make the configuration files by typing make conf in the main policy directory. This creates the modules.conf and policy.conf files. Now you can compile the policy by entering make policy. This gathers all the modules and compiles them into a binary policy that is directly used by SELinux.

The next step is to install the newly compiled policy by issuing the make install command. Next, you must reload the policy by typing make reload. If you have changed file specifications, you also need to relabel based on the new policy, this is done by typing make relabel. Finally, return to enforcing mode using the setenforce command.

One way to speed up this process is to issue all of the compilation commands in a single command line, as shown below.

# setenforce 0 && make policy install reload relabel reload && setenforce 1

Auditing An Application

Now that you have a policy development environment and are able to compile SELinux policy, you can make policy changes to correct any audited messages in your system log or enable a permission needed by an application you use.

You must create some source files when adding security policy statements that only apply to the local system, since if you add statements to existing files they will be overwritten during policy updates. Create local files by issuing these commands:

touch /etc/selinux/engarde/src/policy/policy/modules/admin/local.fc
touch /etc/selinux/engarde/src/policy/policy/modules/admin/local.te
touch /etc/selinux/engarde/src/policy/policy/modules/admin/local.if

Next, edit the /etc/selinux/engarde/src/policy/policy/modules.conf file and add a line reading local = base and save the file. Recompile the policy and check the output to ensure your local.* files were included.

Let's say, for example, that you've installed some PHP scripts on your website that function fine in permissive mode, but fail when you enable enforcing mode, since the scripts are attempting an action that SELinux does not allow.

The first step would be to open a terminal to the server, ensure you're logged in to the sysadm_r role, and execute the following commands:

# setenforce 0
# dmesg -c
# watch audit2allow -d

These commands will allow you to view the missing SELinux permissions in real time. The audit2allow command is the single most useful tool when troubleshooting SELinux problems. When run with the -d switch, it monitors the dmesg output for SELinux audit errors, and automatically converts these errors into the correct allow command that could be added to the policy to permit the denied action.

With the above commands running and your system in permissive mode, run through the parts of your application that are causing trouble and you should see your audit2allow terminal start outputting allow statements. Review these statements, since they may be unsafe due to incorrect file labeling and may be far too permissive.

For example, your audit2allow output may recommend giving your application full read/write access to the etc_t type. This would allow writing of many files in the /etc directory that belong to other applications and would be unsafe. The correct way to design your policy would be to change the type of the files your application is actually accessing to something narrower and more restricted so you can allow write access to only that new type.

If you're unsure what file is being accessed, look at your system log and search it for the actual denial message. The denial message will look something like the following:

Oct 19 14:38:54 paxtest kernel: audit(1129747134.276:0): avc: denied { read } for name=messages dev=hda6 ino=2146393 scontext=root:staff_r:staff_t tcontext=system_u:object_r:var_log_t tclass=file

The ino entry in the denial message indicates the inode of the file that the denial refers to. You can locate this file by using a find command thusly:

# find / -inum 2146393

If you need to assign a different file context to a file, edit the $policy/policy/modules/admin/local.fc. The .fc files are lists of regular expressions matching a full file path followed by a security context to assign to that file during a relabel. Look at other existing .fc files in the policy for an idea of how these work. Once you assign a new context to a file, recompile and relabel, then perform your application testing again to generate a new list of allow statements that take the new context into account.

Modifying Policy

Once you have your list of all your allow statements, examine them carefully and try to understand what you are allowing before adding them to policy. One weakness of audit2allow is that it is unaware of macros contained in the policy, so grep through your policy sources for allow statements close to the ones you'd like to add and try to find appropriate macros to use instead. If you're planning on doing a lot of policy customization it's a good idea to familiarize yourself with the existing policy sources so you're aware what macros are available.

The $policy/policy/support/obj_perm_sets.spt is one good place to start, it contains macros that expand out to useful permissions groupings. For example, rather than allowing a domain the ioctl, read, getattr, lock, write, and append permissions to a given type, you can simply assign it the rw_file_perms macro instead. This helps keep policy readable later on.

Once you have generated your needed allow statements, add them to the $policy/policy/modules/admin/local.te file and recompile the policy. If your application still won't work in enforcing mode, just repeat the process until you can run it with no SELinux audit errors.

Always keep your policy changes in the $policy/policy/modules/admin/local.* files. These files are included in the package empty and intended for local policy customization. If you change a file that belongs to a service and contains rules already your changes will be lost when the policy is upgraded, so keep local changes in the local.te and local.fc files where they belong.

If you find a problem in existing policy, add your changes to local.* but provide a patch to the policy maintainers so they can include it in a later build. Most SELinux policies are being constantly developed and revised since the technology is still fairly new, and your upstream maintainers will thank you for your help.

Policy development can be difficult at the beginning, but I think you'll find that as you make progress you'll be learning not only about SELinux but about the details of what your applications are really doing under the hood. You'll not only be making your system more secure, you'll be learning about the low level details of your system and its services. SELinux development has already resulted in upstream patches to many applications that had hidden bugs that were only found because SELinux alerted policy developers to the kernel level actions the applications were attempting.

I hope you enjoyed reading this SELinux series as much as I enjoyed writing it. Until next time, stay secure and keep your policy locked down tight.
Pax Dickinson has over ten years of experience in systems administration and software development on a wide variety of hardware and software platforms. He is currently employed by Guardian Digital as a systems programmer where he develops and implements security solutions using EnGarde Secure Linux. His experience includes UNIX and Windows systems engineering and support at Prudential Insurance, Guardian Life Insurance, Philips Electronics and a wide variety of small business consulting roles.

Engarde Policy SourcesWritten by Jack on 2007-11-05 01:50:09
Unfortunately, the developers of EnGarde do not publish the policy source on the GDSN so by using 'apt-get install make m4 gcc python engarde-policy-sources' does nothing, as the policy sources are NOT available for compilation, I know, I've tried. 
If anyone wants a particular change to the policy, the EnGarde support team should impliment it into the next policy, when that is, heaven knows. 
At the present time the policy is written so tight that, when a php script is required to utilize the mail() funtion, it is blocked by the policy, this function "should" have been an allowed part of the policy, from the get-go.
php mail() functionWritten by Jack on 2007-11-08 14:24:14
After testing and analyzing selinux, I found that the developers did not aloow for php scripts to access sendmail or postfix using the mail() function 
Every distro of Linux I have tried that uses SELinux, does not have the mail() function enebled, and no matter how the loacl.te file is added to and the policy re-compiled, SELinux will always block the use of the mail() function, so my conclusion is,,,,SELinux policies need to be revised and re-written to allow such functions.

Only registered users can write comments.
Please login or register.

Powered by AkoComment!

< Prev   Next >


Latest Features
Peter Smith Releases Linux Network Security Online
Securing a Linux Web Server
Password guessing with Medusa 2.0
Password guessing as an attack vector
Squid and Digest Authentication
Squid and Basic Authentication
Demystifying the Chinese Hacking Industry: Earning 6 Million a Night
Free Online security course (LearnSIA) - A Call for Help
What You Need to Know About Linux Rootkits
Review: A Practical Guide to Fedora and Red Hat Enterprise Linux - Fifth Edition
Yesterday's Edition
Feds Charged With Stealing Money During Silk Road Investigation
EFF questions US government's software flaw disclosure policy
Hotel Router Vulnerability A Reminder Of Untrusted WiFi Risks
Partner Sponsor

Community | HOWTOs | Blogs | Features | Book Reviews | Networking
 Security Projects |  Latest News |  Newsletters |  SELinux |  Privacy |  Home
 Hardening |   About Us |   Advertise |   Legal Notice |   RSS |   Guardian Digital
(c)Copyright 2015 Guardian Digital, Inc. All rights reserved.