Thursday, October 1, 2009

Arch Linux with TOMOYO Linux MAC

I had mentioned in my mini review of Arch Linux about no official support for Mandatory Access Control solution such as SELinux or AppArmor and also outlined the importance of MAC when writing
about AppArmor a few months ago.  I'm very happy with my Arch Linux installation, but one thing that bothered me was no ability to protect crucial applications and system against unknown vulnerabilites. So I decided to put some effort and install a MAC implementation on my system. This blog entry is about how it went.

The problem with software bugs is you cannot avoid them. Developers make bugs and even if you keep your system updated, you are still endangered by zero-day bugs and hidden, undisclosed bugs.  If you think you're on the sunny side because your're not a server administrator, just a workstation user, then you're mistaken. You may get hacked by just visiting a malicious web site that exploits a yet-unknown vulnerability in your web browser or by opening a crafted PDF file that exploits a bug in your PDF viewer software.

With Mandatory Access Control you can "enclose" selected applications in secured domains with precisely defined resources and privileges for that application. If bug in secured application is exploited, an attacker cannot perform any operations not defined in that application's policy rules.

OK, now onto choosing the right MAC implementation. This depends on your needs, determination, time, knowledge and willingness to learn. When looking for a solution for Arch Linux I initially considered two implementations: AppArmor and SELinux.
AppArmor is something I'd preferr over SELinux for my needs, but the status of AppArmor development is not clear to me. The latest kernel patch available on the official web site is for kernel 2.6.26, so it's a bit outdated.  On the other hand AppArmor will be shipped with new Ubuntu 9.10 (kernel 2.6.31), so obviously there are people who maintain it, but I could not find any new patches.... Strange.
SELinux would be an overkill for a workstation. I'm just not willing to tackle with file labelling and complex policies just to protect a few applications. Besides that, it's seems to be hard to protect Mozilla Firefox with SELinux labelling. The nice thing about installing SELinux is it can be easily installed using Community packages.

I kept looking and found two other solutions that recently emerged in Linux world:
SMACK - Simplified Mandatory Access Control - available in stock kernels starting from kernel 2.6.24.
TOMOYO Linux - available with limited functionality in stock kernels starting from kernel 2.6.30 (but not enabled in Arch Linux kernel). Also available as a separate kernel patch with full functionality.

SMACK is a "SELinux for dummies"; it uses lables and extended attributes, but is much more easy to use than SELinux. Tomoyo is similiar in concept to AppArmor - it uses path names as security labels. It can be easily installed on Arch using PKGBUILD from AUR. Keeping all the above in mind (complexity of administration, availability) I decided to give Tomoyo a try.

Installation is easy. Just build and install kernel26 and ccs-tools from AUR (note: this is TOMOYO 1.6.8 with full MAC functionality) , update grub config file, reboot the system, initialize policy files and it's ready to use (basic setup is well described in TOMOYO's HOWTO). The majority of work is with creating application policies. Fortunately, TOMOYO has a really powerful learning mode. Here is how to use it:
  1. Start application just once so that TOMOYO knows about it, then quit it.
  2. Run ccs-editpolicy and find that application on the domains list (see screenshot) and highlight it.
  3. Press 'S' and then '1' to enable learning mode for it.
  4. Excercise your application a bit - perform as many actions as possible. Policy rules for this application will be generated automatically and kept in kernel memory.
  5. When you're done, press 'S' again and then '3' to enable enforcing mode for your application. Alternatively, you can use '2' for permissive mode (all actions are permitted but potential denials will be written to log file - useful for testing purposes).
  6. Save the policy with 'ccs-savepolicy'. This stores current policy from kernel memory to /etc/ccs/* files.
  7. Adjust the /etc/ccs/domain_policy.conf and /etc/ccs/exception_policy.conf with a text editor. You'll most likely need to change any specific file paths occuring in the policy (like /home/john/.mozilla/firefox/6y78dadq.default/Cache/yiaud) with file patterns (e.g. /home/\*/.mozilla/firefox/\*/Cache/\*).
  8. Reload the policy with 'ccs-loadpolicy de'; this loads current policy from files to kernel memory.
You can repeat above steps as many times as needed.

There is hovewer one catch to be aware of.  Policy rules are defined per execution domain. In TOMOYO domains are defined by process invocation history (PIH), that is, a concatenated list of executables that lead to the execution of specific application. This means that "/sbin/init /usr/bin/gdm /usr/sbin/gdm-binary /etc/gdm/Xsession /usr/bin/ssh-agent /usr/bin/gnome-session /usr/bin/gnome-panel /usr/bin/transmission /usr/lib/firefox-3.5/firefox" domain is different from " /sbin/init /usr/bin/gdm /usr/sbin/gdm-binary /etc/gdm/Xsession /usr/bin/ssh-agent /usr/bin/gnome-session /usr/bin/gnome-panel /usr/lib/firefox-3.5/firefox", even though in both cases Mozilla Firefox was executed. In the first case Firefox was started by Transmission, in the second case it was started by Firefox shortcut on the panel. The number of domains Firefox could be started in is potentially infinite, because you can start it via ALT+F2 in GNOME, xterm, gnome-terminal etc. You may think you'll end up with duplicating policy rules for all possible domains Firefox can be started in (not a good idea...), but fortunately Tomoyo has solution for this:  you've to add 'initialize_domain /usr/lib/firefox-3.5/firefox' definition to /etc/ccs/exception_policy.conf and define policy rules for " /usr/lib/firefox-3.5/firefox" domain.  It's so simple.  From now on, whichever way you choose to start Firefox, Tomoyo will use just one domain definition and same rule set. Don't underestimate PIH though, as PIH is a a powerful tool to define various polices for same application, depending on its invocation history (well... that was obvious, hmm...). You can, for example, define different rules for /bin/cat executable, depending on whether it was used in /usr/bin/ script or /usr/bin/ script.

Ok, this is enough. It's time to summarize best features of TOMOYO Linux:
• Easy to set up. No existing userland tools need to be modified.
• Easy policy language.
• Great learning mode.
• Ability to modify policies on-the-fly.
• No impact on performance (according to Tomoyo Linux authors, performace hit is within measurements error).

If you need a MAC solution which is easy to setup and use and you understand the differences between path-based (TOMOYO, AppArmor) and label-based (SELinux, SMACK) solutions, then you should definately give Tomoyo Linux a try. I think it's superiror to AppArmor and now as it made it's way into Linux Kernel, it seems it has a bright future. Congratulations, TOMOYO team!

UPDATE: I've been contacted by Tetsuo Handa (one of the Tomoyo developers) with a rectification about performance: there is some impact on performance, and performance impact of TOMOYO is larger than SELinux (as it entails string comparison with pattern patching), but users
 won't notice unless CPU is too slow. Some people tried to measure the performance hit, but they got bizzare results.

No comments: