Apparmor Profiles Quickly, if not easily.

Posted: October 9, 2011 in Guides
Tags: , , ,


With the release of Ubuntu 11.10 Oneiric Ocelot upon us, I decided I would discuss one of the lesser used security features bundled with Ubuntu, Apparmor. Apparmor is actually a great utility particularly in terms of desktop security where browser exploits can become ridiculous quickly. It is suited for production applications as well, however often times is forgone due to the resources confining an application can require.

This guide is designed for the desktop user who all too often chooses not to use Apparmor for the reason, it’s too complicated, it’s a very advanced task, there are no premade profiles for my software; whatever the reason Apparmor is a great security feature, and while us Ubuntu users don’t have something super convenient like YaST to help us configure it, we can still create our own Apparmor profiles with relative ease.

For those of you who don’t understand what Apparmor does but just know that it’s a good thing to have. A quick explanation is, it limits what an application can and can not do, by utilizing a profile with a pre defined set of controls. If the application tries to exceed that profile it will not be allowed. This is useful for countering the dreaded 0 day exploit. Apparmor will essentially limit the exploit code to exercising the program’s functionality. While this still may be undesirable it is much less devestating than the alternatives.

This guide was created with the aim of showing a Novice user how to create their own Apparmor profile, it was created using the oh so awesome and new Oneiric Ocelot, but should work on Lucid Lynx, Maverick Meerkat and Natty Narwhal, anything older I can’t guarantee, although Apparmor hasn’t really changed that much so most will likely still apply.

Making sure we have all the necessaries

Before we delve into creating our Apparmor profile let’s make sure we have all the necessary tools in this case I’m referring to the Apparmor utilities package. We can get it by doing the following

sudo apt-get install apparmor-utils

For this guide we will be constructing a profile for Chromium Browser you can install it by doing the following

sudo apt-get install chromium-browser

Understanding Apparmor Profile Syntax

I will be walking you through the creation process , as well as some of the syntax options we choose and why, however it is wise that you familiarize yourself with all available parameters here

A brief summary of syntax and parameters :

#include – includes abstractions from another profile to help simplify the profile creation process
capability – adds a capability on a per-thread basis (eg : capability sys_admin , capability dac_override)
network – adds networking capabilities (eg : network inet stream)
Access modes
– r : read
– w : write (don’t use with append)
– a : append (don’t use with write)
– ux : unconfined execute
– Ux : unconfined execute with a steralized environment
– px : discrete profile execution
– Px : discrete profile execution with steralized environment
– m : protected execute utilizing mmap()
– l : link
– k : lock

As I said, if you need more information on the function of these check the link here for a more in depth explanation.

Creating our Apparmor Profile

The first step in generating our Apparmor profile for Chromium is to type the following in a terminal

sudo aa-genprof chromium-browser


this tells Apparmor we to generate a profile for /usr/bin/chromium-browser. Once you’ve entered this command you will be prompted to “Scan for system events” , before we do this we need to start Chromium and exercise it’s functionality. Start it up, visit some websites and generally use the browser as you normally would.

Once we’ve done this we can hit “S” to scan for system events. You will be given some choices on what chromium will have access to, this is where it gets a little complicated, and we need to understand what chromium is doing with them.

The first we will be given is /bin/readlink : we can grant ix (inherit execute) to this by pressing X

The next option is /etc/chromium-browser/default : this is our chromium configuration and we can give this r so we press A for Allow

After this we can allow w in /home/*/.config/chromium/FirstRun by pressing A, now here we are given a choice of /home/username/.config/chromium/FirstRun or /home/*/.config/FirstRun, the * acts just as you would expect a wildcard which means match any name we use our arrow keys to scroll down to this and use this option because it makes our profile more portable, we may not always have the same user running our confined application.

The next choice is to allow read in /proc/meminfo , we want to do this so that chromium can manage shared memory , so we choose A for Allow.

The next option is to allow read in /usr/bin/chromium-browser , we want to be able to run our browser so we choose A for Allow, we may have to come back and tune this.

Next we have the option to allow read in /usr/share/icons/Humanity/devices/16/drive/drive-harddisk.svg or to add an abstraction that gives us access to this path, for this we will scroll up to #include and hit enter

After this we will be prompted to save our file. We will press S to do so.

Debugging our Profile

At this point we have a shell of a profile generated for Chromium in /etc/apparmor.d/usr.bin.chromium-browser , we can view it and edit it by doing the following

sudo nano /etc/apparmor.d/usr.bin.chromium-browser

As you might imagine our profile is far from complete, so we will now edit it with our text editor.

The first thing we will want to add to our profile is

#include <abstractions/audio>
#include <abstractions/nameservice>

This will insure that chromium has access to audio and dns lookups.

Debugging the profile manually

Many people will say to place the profile into complain mode via

sudo aa-complain usr.bin.chromium-browser

Then use the application for awhile and run

sudo aa-logprof

To go through the options of what to allow and disallow. This is a good option, but it takes a really long time, so what we’re going to do is debug the profile manually. In a seperate terminal window (not as root) we are going to run chromium-browser and watch for errors.

The first error we can see is that we don’t have access to /etc/lsb-release. We can grant access to that by adding the following to our apparmor profile

/etc/lsb-release r,

At this point we can reload our profiles by doing the following

sudo /etc/init.d/apparmor reload

and attempt to execute chromium-browser again. This time we are told we don’t have permission to acces /usr/lib/chromium-browser/chromium-browser we can add the following to our profile

/usr/lib/chromium-browser/* r,

we can use the star because it is safe to say that Chromium should at LEAST be able to read everything in it’s directory. As we can see that is not enough, as we are still presented with the same error after reload. We can get around this by adding

/usr/lib/chromium-browser/chromium-browser rix,

To give execute permissions to the chromium-browser file. Our next error shows that chromium-browser-sandbox in the same directory is also needed, in order to insure the least amount of permissions given are, we add the following instead of a wildcard.

/usr/lib/chromium-browser/chromium-browser-sandbox rix,

Our next error is failed to move to PID namespace we will add the following to our profile

capability sys_admin,

/proc/*/fd r,
/prox/*/auxv r,

Our next error is slightly more cryptic but essentially says cannot chroot into /proc so we need to add the following to our profile

capability setgid,
capability setuid,
capability sys_chroot,
capability sys_ptrace,
capability dac_readsearch,

/proc/ r,
/proc/*/status r,
/proc/sys/kernel/shmmax r,

Remember if you stop being able to understand what you need to do at any time you can always run

sudo aa-logprof

And Apparmor will give you suggestions based on syslog events.

Our next set of errors give us this can’t access /sys/bus/pci/devices

so we will add

/sys/bus/pci/devices/* r,
/dev/shm/** rwk,

Now we are still getting some errors, so now is a great time to run aa-logprof and get some suggestions it will add the following

/usr/lib{,32,64}/** rw,
/etc/chromium-browser/policies/** rw,

The next set of errors will all have to do with /sys/bus/pci/devices/0000:00:00.0/* So we’re going to cheat a little bit here, since if you notice the addresses are just incrementing between 4 different files we can do add the following two lines

/sys/bus/pci/devices/0000:00:0[0-9].[0-9]/* r,
/sys/bus/pci/devices/0000:00:0[a-d].[0-93]/* r,

Or you can add them each individually as the errors come, I just thought I would give you the cheater mode [a-d] matches any letter a through d , [0-9] matches any number 0 through 9.

This time we’ll see, when we start it works.

We should now have a profile that looks something like this

/usr/bin/chromium-browser {
#include <abstractions/audio>
#include <abstractions/base>
#include <abstractions/gnome>
#include <abstractions/nameservice>

capability dac_override,
capability dac_read_search,
capability setgid,
capability setuid,
capability sys_admin,
capability sys_chroot,
capability sys_ptrace,

owner @{HOME}/** rw,
/bin/dash ix,
/bin/readlink rix,
/dev/shm/** rwk,
/etc/chromium-browser/default r,
/etc/chromium-browser/policies/** r,
/etc/lsb-release r,
/home/*/.config/chromium/Default/* k,
“/home/*/.config/chromium/First Run” w,
/home/*/.pki/nssdb/cert9.db k,
/home/*/.pki/nssdb/key4.db k,
/proc/ r,
/proc/*/auxv r,
/proc/*/fd/ r,
/proc/*/status r,
/proc/meminfo r,
/proc/sys/kernel/shmmax r,
/run/shm/* rw,
/sys/bus/pci/devices/ r,
/sys/bus/pci/devices/* r,
/sys/devices/pci0000:00/0000:00:0[0-9].[0-9]/* r,
/sys/devices/pci0000:00/0000:00:0[a-f].[0-9]/* r,
/usr/bin/chromium-browser r,
/usr/bin/xdg-settings rix,
/usr/lib/chromium-browser/* r,
/usr/lib/chromium-browser/chromium-browser rix,
/usr/lib/chromium-browser/chromium-browser-sandbox rix,
/usr/lib{,32,64}/** rw,
/var/lib/dbus/machine-id r,



Hopefully this will make it easier for you to create your own apparmor profiles more quickly without having to spend days in “learning mode” for your applications. Also if you end up having any problems, with your profile in the future as your needs grow you can always go back and debug your profile with aa-logprof or manually via a terminal.

Thanks for reading I hope everyone is having a GREAT weekend! 🙂


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s