Raygen's Basement - Internet Stuff

Securing Ubuntu with AppArmor

Ubuntu is a free and open-source Linux distribution supported by Canonical LTD. Even though Ubuntu Linux is very secure out of the box, there are very easy ways to ensure Ubuntu is even more secure. We can do this by taking advantage of the Mandatory Access Controls that ship with Ubuntu. The Mandatory Access Control System Ubuntu ships with is AppArmor. AppArmor was originally designed by Novel, and released to the open source community under the GPL. AppArmor is a path-based MAC that many experts deemed is easier to use and implement then SELinux.

AppArmor works by reading and loading profiles (Text documents) that outline the permissions for an application, and what areas of the system they are allowed to read and write to. AppArmor is implemented using  Linux Security modules kernel interface. What AppArmor allows you to do is confine system access of Internet facing applications and daemons to a specific set of places the application needs to function and that’s all. This means AppArmor can be used to fend off and/or greatly reduce the damage potential of zero-day exploits in Internet facing applications.

In this article I will show you the basics of how AppArmor works, and write a  profile for Mozilla Firefox.

Disclaimer: by following the steps in this guide you agree that raygen.info and its author will not be held liable or responsible for any damage or loss of data on your computer. you proceed at your own risk. If you are not comfortable performing the steps below, then don’t follow them. You are  solely responsible for any damage or loss of data on your computer.

AppArmor Syntax

The syntax AppArmor uses is pretty simple. Permissions are laid out in a path-based manner with switches denoting permissions. The permissions are as follows:

  1. r = Read Access
  2. w = Write Access
  3. ix = Inherit Execute
  4. m = Allow Executable Mapping
  5. l = Link
  6. ux = Unconstrained Execute (Not reccommended for use)
  7. Ux = Unconstrained Execute – with environment scrubbing (again not recommended for use)
  8. px = Discrete Profile Execute (requires a seperate profile exists for application being called)
  9. Px = Discrete Profile Execute (requires a seperate profile exists for application being called) – scrub the environment
  10. k = lock permissions

Note: The ux and Ux permissions are not recommended because they allow an application or service to execute unconstrained with no restrictions. In worse case scenario write a separate profile for the application or use the ix permission it its place and grant permissions accordingly within the parent profile.

AppArmor Paths and Globbing

So now that the permissions AppArmor uses to work have been explained, I will give an example of the path-based nature of AppArmor. Say you want Firefox to be allowed read only access to the tmp directory, then you would lay out the following rule in your AppArmor profile depending on the access you wish to grant. The * represent globbing:

/tmp/ r, – The tmp directory
/tmp/* r, – all files directly in /tmp
/tmp/*/ r, – all directories directly in /tmp
/tmp/** r, – all files and directories underneath /tmp
/tmp/**/  r,- all directories underneath /tmp

So as you can see, AppArmor is not all that difficult to grasp, it just take a little practice to get used to the syntax of how to create a AppArmor profile.

Abstractions

Abstractions are like include statements that are used in programing laugauges to include a set of files or rules. you can use the prebuilt abstractions that come with AppArmor to reduce the amount of permissions for common things. The abstractions are located in the /etc/apparmor.d/abstractions folder. An example of an abstraction is below:

#include <abstractions/gnome>

That abstraction would allow your profile to have all the permissions granted in the prebuilt gnome abstraction rules. This makes it easy to have generic rules that can apply to many profiles and greatly lessen the work you have to do.

AppArmor Profile modes

There are two types of modes for AppArmor Profiles. The Complain Mode and the Enforce Mode.

Complain ModeIn this mode, AppArmor only logs violations of the profile to the log, it does not restrict access. This is good for troubleshooting a profile or profiling an application you wish to contain.

Enforce Mode - In Enforce Mode AppArmor will enforce the MAC you have laid out in the AppArmor profile you have created. This mode puts the teeth into the AppArmor profile you have created.

AppArmor Commands

Before we get started however, we need to go over a few AppArmor commands.

  1. sudo aa-genprof -  creates a profile for an application and places the application in complain mode. for example, sudo aa-genprof firefox would create a profile for firefox and place it in complain mode.
  2. sudo aa-status – shows the status of AppArmor profiles
  3. sudo aa-complain - puts a profile in complain mode. example: sudo aa-complain firefox would put firefox in complain mode.
  4. sudo aa-enforce - put a profile in enforce mode. example: sudo aa-enforce firefox would put firefox in enforce mode.
  5. sudo aa-logprof – Allows you to log violations to a profile, good for setting permissions on applications. will then give you choices on what to do with permissions. example: sudo aa-logprof firefox would log violations to firefox profile and allow you to make choices.
  6. sudo /etc/init.d/apparmor reload – This allows you to reload your AppArmor profiles. you can also use /etc/init.d/apparmor.d restart  if you wish to restart AppArmor.

Those commands above will allow you to control AppArmor. If for some reason you put a profile in enforce mode and the app quits working, use the commands sudo aa-complain  and then sudo /etc/init.d/apparmor reload to put the profile back in complain mode and reload AppArmor so the app works.

Generating a AppArmor profile for Firefox

As I promised earlier in this post, we will generate an AppArmor profile for Firefox. Its not as daunting as a task as you may think because the tools are there on Ubuntu to help you along the way.  You can’t really make any mistakes here. At worst case scenario you will be too restrictive(the application won’t work) or you will be too permissive(not restrictive enough) there is always a way out. with that being said, lets generate a profile for Firefox.

Step 1: Make sure Firefox is not running, then open a terminal and type the following command: sudo aa-genprof firefox and press enter. Leave this terminal window open and Answer no to the repository question.

Step 2: Now open Firefox and browse around the internet. Play some youtube videos, use firefox as you would in your normal everyday use. when finished close Firefox.

Step 3: Now in the terminal window select Scan for System Events and answer the questions about permissions you wish to grant. Once you go through them all, open a 2nd terminal window and type sudo /etc/init.d/apparmor reload and press enter. This will reload your AppArmor profile.

Now launch Firefox again and continue using it. Stop every once and awhile and scan your system events again and modify your permissions until you are happy.  when you are satisfied with your Firefox profile then its time to test it in enforce mode. To put your AppArmor profile in enforce mode do the following:

Step 1: in a terminal type sudo aa-enforce firefox and press enter.

Step 2: In a terminal type sudo /etc/init.d/apparmor reload and press enter.

Now ty to lauch Firefox. If it fails to load then your profile is too restrictive. Simply use the commands sudo aa-complain firefox followed by sudo /etc/init.d/apparmor reload in a terminal to put the profile back into complain mode and reload AppArmor. in a terminal use sudo aa-logprof firefox and use firefox again to scan your system logs and allow the permissions you need until Firefox works with a set of confined permissions.

Each and every AppArmor Profile looks different because every user uses Firefox differently. Below is the Firefox profile I came up with. Yours may vary, but this should give you a good idea.

#include <tunables/global>

/usr/lib/firefox-3.5.*/firefox {
#include <abstractions/audio>
#include <abstractions/base>
#include <abstractions/cups-client>
#include <abstractions/dbus>
#include <abstractions/fonts>
#include <abstractions/freedesktop.org>
#include <abstractions/gnome>
#include <abstractions/nameservice>
#include <abstractions/user-tmp>
#include <abstractions/X>

network inet stream,
network inet6 stream,
@{PROC}/[0-9]*/net/if_inet6 r,
@{PROC}/[0-9]*/net/ipv6_route r,

/etc/sound/ r,
/etc/sound/** r,
/etc/wildmidi/wildmidi.cfg r,

/etc/ r,
/etc/gnome/defaults.list r,
/etc/mime.types r,
/etc/mailcap r,
/usr/bin/dbus-launch ixr,
/usr/bin/apport-bug ix,

/etc/firefox-3.*/ r,
/etc/firefox-3.*/** r,
/etc/xulrunner-1.9*/ r,
/etc/xulrunner-1.9*/** r,
/etc/gre.d/ r,
/etc/gre.d/* r,

deny /usr/lib/firefox-3.*/** w,
deny /usr/lib/firefox-addons/** w,
deny /usr/lib/xulrunner-addons/** w,

/usr/lib/firefox-3.*/** ixr,
/usr/bin/basename ixr,
/sbin/killall5 ixr,
/bin/which ixr,
@{PROC}/ r,
@{PROC}/[0-9]*/cmdline r,
@{PROC}/[0-9]*/stat r,
@{PROC}/[0-9]*/status r,
@{PROC}/filesystems r,
capability sys_ptrace,

/etc/mtab r,
@{PROC}/[0-9]*/mounts r,
@{PROC}/[0-9]*/maps r,

# allow access to documentation and other files the user may want to look
# at in /usr
/usr/ r,
/usr/** r,

# so browsing directories works
/ r,
/**/ r,

@{HOME}/ r,
@{HOME}/** rw,
@{HOME}/Desktop/** rw,
@{HOME}/Firefox_wallpaper* rw,
owner /media/** rw,
owner /mnt/** rw,
owner /srv/** rw,

#include <abstractions/private-files>
audit deny @{HOME}/.ssh/** mrwkl,
audit deny @{HOME}/.gnome2_private/** mrwkl,

audit deny @{HOME}/.gnupg/** mrwkl,

@{HOME}/.mozilla/ rw,
@{HOME}/.mozilla/** rw,
@{HOME}/.mozilla/**/*.sqlite* k,
@{HOME}/.mozilla/**/.parentlock k,
@{HOME}/.mozilla/plugins/** rm,
@{HOME}/.mozilla/**/plugins/** rm,

@{HOME}/.icedteaplugin/ rw,
@{HOME}/.icedteaplugin/** rw,
@{HOME}/.adobe/ rw,
@{HOME}/.adobe/** rw,
@{HOME}/.macromedia/ rw,
@{HOME}/.macromedia/** rw,
@{HOME}/.java/ rw,
@{HOME}/.java/** rwk,

@{HOME}/.mozilla/**/extensions/** mixr,

deny /usr/lib/firefox-3.*/update.test w,
deny /usr/lib/mozilla/extensions/**/ w,
deny /usr/lib/xulrunner-addons/extensions/**/ w,
deny /usr/share/mozilla/extensions/**/ w,

#
# Plugins/helpers
#
@{PROC}/[0-9]*/fd/ r,
/usr/lib/** rm,
/bin/bash ixr,
/bin/dash ixr,
/bin/grep ixr,
/bin/ps ixr,
/bin/uname ixr,
/usr/bin/m4 ixr,
/usr/lib/nspluginwrapper/i386/linux/npviewer ixr,
/var/lib/ r,
/var/lib/** mr,

/usr/bin/evince ixr,

# miscellaneous
#/usr/bin/eog ixr,
/usr/bin/gedit ixr,
/usr/bin/gimp* ixr,
/usr/bin/file-roller ixr,
/usr/bin/ooffice ixr,
/usr/bin/oocalc ixr,
/usr/bin/oodraw ixr,
/usr/bin/ooimpress ixr,
/usr/bin/oowriter ixr,
/usr/bin/gtk-gnash ixr,
/usr/bin/pulseaudio ixr,

# totem
/usr/lib/totem/** ixr,
/usr/bin/totem-gstreamer ixr,
/usr/bin/totem-xine ixr,
/usr/bin/totem ixr,

# mozplugger
/etc/mozpluggerrc r,
/usr/bin/mozplugger-helper ixr,

# mplayer plugin
/etc/mplayerplug-in.conf r,
/usr/bin/mplayer ixr,

# java
/usr/lib/jvm/java-6-openjdk/jre/bin/java ixr,
/etc/java-*-sun/** r,
/usr/lib/jvm/java-*-sun-1.*/jre/bin/java ixr,
/etc/java-6-openjdk/** ixr,
/etc/java-6-openjdk/* ixr,
/etc/lsb-release ixr,
/etc/.java/deployment/ mrw,
/etc/.java/deployment/* mrw,
/home/ron/.java/deployment/cache/* mr,
/home/ron/.java/deployment/cache/** mr,
/tmp/* mr,
/tmp/** mr,

so there you have it. This is an easy way to lock down Firefox with AppArmor. AppArmor can be used to lock down other programs to from instant messengers to pdf viewers in much the same way you locked down Firefox. You just have to be patient and give yourself a chance to get used to the syntax and how it works, but it becomes pretty easy after a little bit of experience.

further reading

http://en.opensuse.org/AppArmor

http://ubuntuforums.org/showthread.php?t=1008906

Comments Welcome!

i am always willing to help others.

  • Share/Bookmark

Related Articles

Leave a comment

Your comment

Raygen's Basement - is powered by WordPress | Entries (RSS) and Comments (RSS)