Running Tahoe-LAFS with AppArmor Linux Security Module (LSM, MAC)
What's it all about
AppArmor LSM allows better isolation of privileges and potential exploits than standard linux uid/gid mechanisms, also known as Discretionary Access Control (DAC).
Basic idea is that if there will be any kind of remote execution vulnerability in tahoe, python or any of the dozens of the libraries it's built upon (all the way down to a kernel itself), attacker will get access to uid/gid that the node is running under, and from there, there are dozens of attack vectors - from infamous forkbomb DoS attacks, sharing sensitive data with other uid/gid's or network and insecure /tmp files to a numerous kernel zero-day privilege escalation vulnerabilities.
Mandatory Access Control modules like AppArmor aim to prevent that by further restricting the app from being able to even do "ls /" to the bare minimum of the capabilities and permissions the app needs to operate.
AppArmor is mainly used on dpkg-oriented linux distributions like SUSE and Ubuntu. Fedora and Red Hat linux (and derivatives) tend to use SELinux LSM by default, but there are no fundamental problems with using AppArmor there as well.
See links section for more information about the approach itself and particulars of the technology used.
Profile
About the only special thing in tahoe apparmor confinement is the fact that python stdlib module "platform" runs binaries like shell (/bin/sh) and file (/usr/bin/file) via os.popen to get information about the unix platform it's running on.
These particular operations can be blocked (platform module will fall back to reporting "generic" values), leaving tahoe with no particulars about the platform it runs on.
Sufficient and zero-noise profile for generic non-packaged tahoe build (checked out to /home/tahoe/tahoe-lafs path) follows:
#include <tunables/global> /home/tahoe/tahoe-lafs/bin/tahoe { #include <abstractions/base> #include <abstractions/python> #include <abstractions/nameservice> # Helper binaries #include <abstractions/bash> /bin/bash ix, /bin/uname Ux, /usr/bin/file Ux, /sbin/ifconfig Ux, # Subprocesses /home/tahoe/tahoe-lafs/bin/tahoe ix, /home/tahoe/tahoe-lafs/support/bin/tahoe ix, # Misc harmless access deny /etc/ r, /dev/tty rw, /usr/bin/python2.[changeset:16bb529339e6cbd5] r, /usr/include/python2.7/pyconfig.h r, # Build tree of tahoe /home/tahoe/tahoe-lafs r, /home/tahoe/tahoe-lafs/** rm, # Grids and network network tcp, /home/tahoe/grids/ rw, /home/tahoe/grids/** krw, }
A few things to note:
- Data and configuration resides in /home/tahoe/grids/ path, and should be changed as necessary.
- "abstractions/bash" ruleset, execution of /bin/bash, /bin/uname, /usr/bin/file, as well as access to /bin/tty and /usr/bin/python* binary can be left out as noted above. It is only used to determine platform tahoe-lafs runs on.
- "owner" rule qualifier can be added if /home/tahoe belongs to the same uid tahoe node runs with.
- "network tcp" line can be changed to include only a particular node set, but abstractions/nameservice allows fairly liberal network usage, so that aspect is better left to other network control mechanisms like a firewall or user-space IDS.
Links
- AppArmor project page.
- Profile language documentation.
- Source of the profile, used by the original author of this page (can be more up-to-date than the page).