Showing posts with label tomoyo linux. Show all posts
Showing posts with label tomoyo linux. Show all posts

Wednesday, December 1, 2010

TOMOYO Linux - 5 tips to streamline your experience

I've already blogged about TOMOYO Linux, a nice MAC implementation before. This time I'd like to share a few tips that I worked out using TOMOYO. Most (or all) of them may be apparent for long-time TOMOYO users, but hopefully will be helpful for newcomers.
These tips are based on the tomoyo-tools v2.x (for mainlined version, i.e. included in the vanilla kernel and using LSM).  Use ccs-patternize, ccs-loadpolicy etc. for 1.x series.
  1. Use initialize_domain
    Tomoyo creates separate domains for all execution paths. If you execute, say, Firefox web browser from a bash shell running in gnome-terminal, then from gnome menu and finally from gnome “run” dialog, you’ll end up with three distinct domains (and the number is possibly infinite, since you can start any application in many ways). Since you probably want to use same policy rules for all Firefox domains, no matter how Firefox was started, use initialize_domain rule in the exception policy, e.g.

    initialize_domain /usr/bin/firefox
    This way only one domain, “/usr/bin/firefox” will be created in the system.
  2. Use keep_domain
    Many applications spawn child processes and execute helper programs - for instance, /usr/bin/firefox is just a shell script, that runs /usr/lib/firefox-x.y.z/mozilla-run.sh, which in turn starts firefox-bin; the latter runs plugin-container and so on. Since you’re probably interested in confining an application as a whole, you may consider keeping all child processes in the same domain as the parent. Put

    keep_domain /usr/bin/firefox"

    in the exception policy and all execution paths created by /usr/bin/firefox domain will use same policy rules. Be aware however, that this loosens security and violates the rule of minimum privileges a bit. For example, plugin-container is responsible for running macromedia flash content plugin (among other plugins) and running it in the same domain as /usr/bin/firefox means it gets all the privileges granted to Firefox itself.

  3. Use tomoyo-patternize combo
    You probably already know and use tomoyo-patternize, but the trick is to pipe it with tomoyo-savepolicy and tomoyo-loadpolicy combo for fast and efficient policy updates and tweaking. The “-” parameter of tomoyo-savepolicy / tomoyo-loadpolicy dumps policy rules to  standard output or reads rules from standard input respectively. Chain it with tomoyo-patternize like this:

    tomoyo-savepolicy -d | tomoyo-patternize ‘pattern1’ ‘pattern2’ … | tomoyo-loadpolicy -df

    And you can apply patterns immediately. This combo is so useful, that you may consider putting it in a wrapper script, e.g:

    #!/bin/sh
    tomoyo-savepolicy -d | tomoyo-patternize $@ | tomoyo-loadpolicy -df

    Don’t forget that changes are made to the policy rules currently loaded in the kernel (no changes are made to the /etc/tomoyo/domain_policy.conf file), so don’t forget to execute tomoyo-savepolicy before shutdown....

  4. Use recursive dir matching
    The recursive directory matching operator /\{dir\}/ matches one or more repetitions of 'dir/'. Use it with “\*” as a directory argument to match all subdirectories (and their subdirectories etc.) of given directory, regardless of depth. This is useful if you don’t know directory structure in advance or don’t need to grant specific permissions for subdirectories. For instance, Firefox extensions tend to mess a lot with their files in ~/.mozilla/firefox/\*/extensions directory and it subdirectories, so you may want to grant read, write, create, truncate, link, unlink rights to ~/.mozilla/firefox/\*/extensions/\* (for files/dirs in extensions directory) and ~/.mozilla/firefox/\*/extensions/\{\*\}/\* (for files in subdirectories of extensions directory, arbitrary depth).

  5. Use path_group for common paths
    There is a lot of common paths that applications are accessing, for instance all GUI apps will read font files and fontconfig related files, all GNOME apps will read GTK configuration files, icons, themes etc. Create path_group definitions for common stuff, e.g.
    path_group FONTS /etc/fonts/\*
    path_group FONTS /etc/fonts/\{\*\}/\*
    path_group FONTS /var/cache/fontconfig/\*
    path_group FONTS /home/\*/.fontconfig/\*
    path_group FONTS /etc/fontconfig/\{\*\}/\*
    path_group FONTS /usr/share/fonts/\{\*\}/\*
    path_group FONTS /usr/share/fonts/\*
    path_group FONTS /usr/share/fonts/\{\*\}/\*

    And then simplify your domain policy rules like this:
    allow_read @FONTS

    Do this for other common files, e.g. ICONS, THEMES, ALSACONF, SOUNDDEV etc.

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/foo.sh script or /usr/bin/bar.sh 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.