Sharing AppArmor security profiles

AppArmor is a name-based mandatory access control mechanism for the Linux Kernel's LSM pluggable security infrastructure. Using AppArmor, system administrators can confine their applications to a subset of files and POSIX.1e draft-capabilities. Processes can run either unconfined or confined by a specific profile. Unconfined processes are completely trusted, and can do anything. Confined processes can only perform the filesystem operations listed in the profile and may only use the POSIX capabilities that are listed in the profile.

AppArmor's design is based significantly on two predominate use cases: server systems and single-user desktop systems. Server administrators often do not trust the software that they must run for business reasons, and AppArmor gives those system administrators a mechanism to confine those services. For example, a server running Apache HTTPD and Wietse Venema's Postfix can confine each service to only have access to its own files --- neither one can read or write the other's files except as allowed by AppArmor policy, regardless of any (potential) misconfiguration of either program or standard Unix DAC (Discretionary Access Control) permissions.

User workstations often run hastily-written software that the user would like to confine, or a user may wish to confine their programs to only a subset of their private data. For example, a user may wish to prevent Mozilla Firefox from reading or writing ~/.ssh/authorized_keys, or prevent mutt from reading ~/.gnupg/secring.gpg, or prevent GnuCash from writing data outside the user's preferences directory.

AppArmor is configured with plain-text policies that list the capabilities and files a program is allowed to use, as well as the privileges the program may have. In order for a program's request to be granted by AppArmor, the program must satisfy both the AppArmor policy as well as the native Linux permissions --- applying an AppArmor policy to a program cannot grant more privileges than the program would have without AppArmor. AppArmor's policy is a combination of a whitelist approach (in a given profile, only listed files and capabilities may be used) and blacklist (not all processes are confined).

Files may be described using a syntax similar to shell globbing; privileges that can be granted are read, write, execute, mmap PROT_EXEC, and link. There are several kinds of execute permission -- inherit, profile, and unconfined. When a program uses execve(2) to execute a new program, AppArmor will either inherit the current domain (ix), change to a new policy (px), or execute the child without any AppArmor policy (ux).

Here's a small example AppArmor policy for ntpd:


  /usr/sbin/ntpd flags=(complain) {
    capability ipc_lock,
    capability net_bind_service,
    capability setgid,
    capability setuid,
    capability sys_chroot,
    capability sys_resource,
    capability sys_time,
    /etc/ntpd.conf r,
    /proc/net/if_inet6 r,
    /tmp/ntp* rwl,
    /usr/sbin/ntpd rmix,
    /var/lib/ntp/drift rwl,
    /var/lib/ntp/drift.TEMP rwl,
    /var/log/ntp w,
    /var/run/ w,

This policy also demonstrates the C preprocessor style of including pieces of pre-written policy into other policies. For example, includes primarily read access to libraries, includes privileges required to do common name service operations. Users can add, remove, or modify the abstractions as they wish.

AppArmor polices are very easy to extend; adding new rules to a profile is very straightforward, and adding a new policy to the system is very straightforward. Users can author policies entirely by hand; however, we have written tools to assist profile authors. The tools are extremely adept at adding new rules to profiles based on program behaviour. Using the tools, system administrators can quickly iterate towards policy that matches the requirements of their software. (One large customer completely profiled their internet-facing commerce servers in under four hours; their extensive test suite was immensely valuable in this process.)

AppArmor comes with some pre-written policies. We feel these policies are a good fit for many users. However, some users may feel our policies are too loose; other users may feel our policies are too restrictive. In addition, we cannot provide policy for programs we're not familiar with --- users will always want to install their own programs --- so providing one-size-fits-all security policy is impossible.

Users should not be forced to write their security policies from a blank slate: we want to provide a useful starting point for users with wildly different security goals, but found this difficult to do with existing packaging tools. So, we have extended our policy authoring tools to work with an online profile repository. Users can upload and download policies from the repository, users can suggest enhancements to other's profiles, and distributors can publish updates.

When a user starts to profile a program, the tools will contact the online repository and request a list of profiles that have been uploaded by other users. After giving the user the chance to inspect profiles, the tool will either start with a profile from another user, as selected by the user, or will start with a nearly-blank template profile.

We'd like to take a small diversion to the Linux distributions: the success of Debian, Gentoo, PLD, and SUSE's openSUSE Build Service demonstrate more clearly than anything else that some users really enjoy working together to provide software to a larger community. Users will happily improve software simply so that other people may benefit from their efforts.

The AppArmor profile repository is designed to help our users work together to provide each other with high quality profiles. While no two users will have identical security policy needs, most users will want policy very similar to another user's policy, that can be customized with a few small changes. We believe that giving users an easy place to upload profiles and integrating profile searching and download into the tools will allow users to form communities around basic profiling principles.

For example, some users may wish to confine one or two large enterprise applications on their servers. Other users may wish to have AppArmor-secured kiosk-type systems, with relatively broad policies that do not grant many write privileges. Other users may wish to have extremely fine-grained profiles, so that every program is very closely limited to only what it actually needs. Still other users may have multiuser timeshare shell servers that need to generally keep users from causing trouble for other users.

When designing the profile repository, we tried to focus on the following use cases:

We're also hoping that through public sharing of policies, the policies will also see some of the benefits that open source software has enjoyed: Peer review to ensure high quality, less required individual effort to use policies, and improved speed and quality of fixes. We also hope that long-term support is improved. Distributions cannot support the security policy needs of all their users, but they can certainly cover large portions. The remaining users currently must resort to offline profile sharing and development. Integrating online profile development and sharing directly into the tools will allow fringe users to better support each other.

The profile repository and tool integration will drastically simplify publishing profiles and making updates as well as drastically simplify trying different profiles with different security goals.

We implemented the server using Ruby on Rails. Ruby on Rails was chosen for a variety of reasons: first, because Ruby is a type-safe programming language it cannot fall prey to entire classes of common programming flaws. Second, Ruby on Rails routing and event handling provides a very strong structure for programs to build from, a structure that eases maintenance programming by placing code in locations based on its function in the program. Third, Ruby on Rails has provided a fantastic Object-Relational-Mapping layer that abstracts the details of the database away from common code, handles marshalling objects into and out of the database, object dependencies, caching, and other niceties. Fourth, many of the supporting features of Ruby on Rails makes implementing code securely easier than implementing the code insecurely. Fifth, Ruby on Rails provides an easy interface to XML-RPC, which is the transport we chose for our tools. It's also easy to provide for standard human-interfaced HTTP. Sixth, Ruby on Rails built-in testing support ensures that tests are easy enough to write, and easy enough to run that they will be run during maintenance.

We implemented the clients using Perl and XML-RPC libraries. The pre-existing tools were already written in Perl because Perl is ubiquitous and makes handling a lot of text very simple. We extended our tools to retrieve profiles and perform searches with the repository over XML-RPC. XML-RPC provides an easy method to turn ActiveRecord Ruby objects into Perl objects over the network connection, and handles a wide variety of common network problems behind the scenes. However, the interface to expose error conditions is awkward at best. An implementation in another language may reduce this author's desire to re-implement the functionality using standard HTTP REST semantics.

The initial versions of these tools will be integrated into the openSUSE 10.3 distribution, and are likely to be included into the next Ubuntu distribution. Future versions of the tools may address several limitations in the current release, first and foremost is adding a new data-centric view of local and remote profiles. Our current tools are workflow-oriented (wizard-style) tools that guide users through specific tasks. While our wizards have proved to be very functional, some operations (such as "update my profiles to latest from the repository") do not map well into the workflow.

The primary difficulty with mandatory access control systems has historically been the difficulty of use. AppArmor's ease of use is unparalleled; providing tools to allow users to seamlessly share their security policies is another step to making mandatory access control more ubiquitous.