Chapter 19. Immunizing Programs

Contents

19.1. Introducing the AppArmor Framework
19.2. Determining Programs to Immunize
19.3. Immunizing cron Jobs
19.4. Immunizing Network Applications

Effective hardening of a computer system requires minimizing the number of programs that mediate privilege, then securing the programs as much as possible. With Novell AppArmor, you only need to profile the programs that are exposed to attack in your environment, which drastically reduces the amount of work required to harden your computer. AppArmor profiles enforce policies to make sure that programs do what they are supposed to do, but nothing else.

Novell® AppArmor provides immunization technologies that protect applications from the inherent vulnerabilities they possess. After installing Novell AppArmor, setting up Novell AppArmor profiles, and rebooting the computer, your system becomes immunized because it begins to enforce the Novell AppArmor security policies. Protecting programs with Novell AppArmor is referred to as immunizing.

Administrators need only concern themselves with the applications that are vulnerable to attacks, and generate profiles for these. Hardening a system thus comes down to building and maintaining the AppArmor profile set and monitoring any policy violations or exceptions logged by AppArmor's reporting facility.

Users should not notice AppArmor at all. It runs behind the scenes and does not require any user interaction. Performance is not noticeably affected by AppArmor. If some activity of the application is not covered by an AppArmor profile or if some activity of the application is prevented by AppArmor, the administrator needs to adjust the profile of this application to cover this kind of behavior.

Novell AppArmor sets up a collection of default application profiles to protect standard Linux services. To protect other applications, use the Novell AppArmor tools to create profiles for the applications that you want protected. This chapter introduces the philosophy of immunizing programs. Proceed to Chapter 20, Profile Components and Syntax, Chapter 22, Building and Managing Profiles with YaST, or Chapter 23, Building Profiles from the Command Line if you are ready to build and manage Novell AppArmor profiles.

Novell AppArmor provides streamlined access control for network services by specifying which files each program is allowed to read, write, and execute, and which type of network it is allowed to access. This ensures that each program does what it is supposed to do, and nothing else. Novell AppArmor quarantines programs to protect the rest of the system from being damaged by a compromised process.

Novell AppArmor is a host intrusion prevention or mandatory access control scheme. Previously, access control schemes were centered around users because they were built for large timeshare systems. Alternatively, modern network servers largely do not permit users to log in, but instead provide a variety of network services for users (such as Web, mail, file, and print servers). Novell AppArmor controls the access given to network services and other programs to prevent weaknesses from being exploited.

[Tip]Background Information for Novell AppArmor

To get a more in-depth overview of AppArmor and the overall concept behind it, refer to Section 17.1, “Background Information on AppArmor Profiling”.

19.1. Introducing the AppArmor Framework

This section provides a very basic understanding of what is happening behind the scenes (and under the hood of the YaST interface) when you run AppArmor.

An AppArmor profile is a plain text file containing path entries and access permissions. See Section 20.1, “Breaking a Novell AppArmor Profile into Its Parts” for a detailed reference profile. The directives contained in this text file are then enforced by the AppArmor routines to quarantine the process or program.

The following tools interact in the building and enforcement of AppArmor profiles and policies:

aa-unconfined / unconfined

aa-unconfined detects any application running on your system that listens for network connections and is not protected by an AppArmor profile. Refer to Section 23.6.3.8, “aa-unconfined—Identifying Unprotected Processes” for detailed information about this tool.

aa-autodep / autodep

aa-autodep creates a basic framework of a profile that needs to be fleshed out before it is put to use in production. The resulting profile is loaded and put into complain mode, reporting any behavior of the application that is not (yet) covered by AppArmor rules. Refer to Section 23.6.3.1, “aa-autodep—Creating Approximate Profiles” for detailed information about this tool.

aa-genprof / genprof

aa-genprof generates a basic profile and asks you to refine this profile by executing the application and generating log events that need to be taken care of by AppArmor policies. You are guided through a series of questions to deal with the log events that have been triggered during the application's execution. After the profile has been generated, it is loaded and put into enforce mode. Refer to Section 23.6.3.4, “aa-genprof—Generating Profiles” for detailed information about this tool.

aa-logprof / logprof

aa-logprof interactively scans and reviews the log entries generated by an application that is confined by an AppArmor profile in complain mode. It assists you in generating new entries in the profile concerned. Refer to Section 23.6.3.5, “aa-logprof—Scanning the System Log” for detailed information about this tool.

aa-complain / complain

aa-complain toggles the mode of an AppArmor profile from enforce to complain. Exceptions to rules set in a profile are logged, but the profile is not enforced. Refer to Section 23.6.3.2, “aa-complain—Entering Complain or Learning Mode” for detailed information about this tool.

aa-enforce / enforce

aa-enforce toggles the mode of an AppArmor profile from complain to enforce. Exceptions to rules set in a profile are logged, but not permitted—the profile is enforced. Refer to Section 23.6.3.3, “aa-enforce—Entering Enforce Mode” for detailed information about this tool.

Once a profile has been built and is loaded, there are two ways in which it can get processed:

aa-complain / complain

In complain mode, violations of AppArmor profile rules, such as the profiled program accessing files not permitted by the profile, are detected. The violations are permitted, but also logged. To improve the profile, turn complain mode on, run the program through a suite of tests to generate log events that characterize the program's access needs, then postprocess the log with the AppArmor tools (YaST or aa-logprof) to transform log events into improved profiles.

aa-enforce / enforce

In enforce mode, violations of AppArmor profile rules, such as the profiled program accessing files not permitted by the profile, are detected. The violations are logged and not permitted. The default is for enforce mode to be enabled. To log the violations only, but still permit them, use complain mode. Enforce toggles with complain mode.

19.2. Determining Programs to Immunize

Now that you have familiarized yourself with AppArmor, start selecting the applications for which to build profiles. Programs that need profiling are those that mediate privilege. The following programs have access to resources that the person using the program does not have, so they grant the privilege to the user when used:

cron Jobs

Programs that are run periodically by cron. Such programs read input from a variety of sources and can run with special privileges, sometimes with as much as root privilege. For example, cron can run /usr/sbin/logrotate daily to rotate, compress, or even mail system logs. For instructions for finding these types of programs, refer to Section 19.3, “Immunizing cron Jobs”.

Web Applications

Programs that can be invoked through a Web browser, including CGI Perl scripts, PHP pages, and more complex Web applications. For instructions for finding these types of programs, refer to Section 19.4.1, “Immunizing Web Applications”.

Network Agents

Programs (servers and clients) that have open network ports. User clients, such as mail clients and Web browsers mediate privilege. These programs run with the privilege to write to the user's home directory and they process input from potentially hostile remote sources, such as hostile Web sites and e-mailed malicious code. For instructions for finding these types of programs, refer to Section 19.4.2, “Immunizing Network Agents”.

Conversely, unprivileged programs do not need to be profiled. For instance, a shell script might invoke the cp program to copy a file. Because cp does not have its own profile, it inherits the profile of the parent shell script, so can copy any files that the parent shell script's profile can read and write.

19.3. Immunizing cron Jobs

To find programs that are run by cron, inspect your local cron configuration. Unfortunately, cron configuration is rather complex, so there are numerous files to inspect. Periodic cron jobs are run from these files:

/etc/crontab 
/etc/cron.d/* 
/etc/cron.daily/* 
/etc/cron.hourly/*
/etc/cron.monthly/* 
/etc/cron.weekly/*

For root's cron jobs, edit the tasks with crontab -e and list root's cron tasks with crontab -l. You must be root for these to work.

Once you find these programs, you can use the Add Profile Wizard to create profiles for them. Refer to Section 22.1, “Adding a Profile Using the Wizard”.

19.4. Immunizing Network Applications

An automated method for finding network server daemons that should be profiled is to use the aa-unconfined tool. You can also simply view a report of this information in the YaST module (refer to Section 26.3.1.1, “Application Audit Report” for instructions).

The aa-unconfined tool uses the command netstat -nlp to inspect your open ports from inside your computer, detect the programs associated with those ports, and inspect the set of Novell AppArmor profiles that you have loaded. aa-unconfined then reports these programs along with the Novell AppArmor profile associated with each program, or reports none (if the program is not confined).

[Note]

If you create a new profile, you must restart the program that has been profiled to have it be effectively confined by AppArmor.

Below is a sample aa-unconfined output:

2325 /sbin/portmap not confined 
37021 /usr/sbin/sshd2 confined
   by '/usr/sbin/sshd3 (enforce)' 
4040 /usr/sbin/ntpd confined by '/usr/sbin/ntpd (enforce)' 
4373 /usr/lib/postfix/master confined by '/usr/lib/postfix/master (enforce)' 
4505 /usr/sbin/httpd2-prefork confined by '/usr/sbin/httpd2-prefork (enforce)'
5274 /sbin/dhcpcd not confined 
5592 /usr/bin/ssh not confined 
7146 /usr/sbin/cupsd confined by '/usr/sbin/cupsd (complain)'
  

1

The first portion is a number. This number is the process ID number (PID) of the listening program.

2

The second portion is a string that represents the absolute path of the listening program

3

The final portion indicates the profile confining the program, if any.

[Note]

aa-unconfined requires root privileges and should not be run from a shell that is confined by an AppArmor profile.

aa-unconfined does not distinguish between one network interface and another, so it reports all unconfined processes, even those that might be listening to an internal LAN interface.

Finding user network client applications is dependent on your user preferences. The aa-unconfined tool detects and reports network ports opened by client applications, but only those client applications that are running at the time the aa-unconfined analysis is performed. This is a problem because network services tend to be running all the time, while network client applications tend only to be running when the user is interested in them.

Applying Novell AppArmor profiles to user network client applications is also dependent on user preferences. Therefore, we leave the profiling of user network client applications as an exercise for the user.

To aggressively confine desktop applications, the aa-unconfined command supports a paranoid option, which reports all processes running and the corresponding AppArmor profiles that might or might not be associated with each process. The user can then decide whether each of these programs needs an AppArmor profile.

If you have new or modified profiles, you can submit them to the apparmor-general@forge.novell.com mailing list along with a use case for the application behavior that you exercised. The AppArmor team reviews and may submit the work into openSUSE. We cannot guarantee that every profile will be included, but we make a sincere effort to include as much as possible so that end users can contribute to the security profiles that ship in openSUSE.

Alternatively, use the AppArmor profile repository to make your profiles available to other users and to download profiles created by other AppArmor users and the AppArmor developers. Refer to Chapter 21, AppArmor Profile Repositories for more information on how to use the AppArmor profile repository.

19.4.1. Immunizing Web Applications

To find Web applications, investigate your Web server configuration. The Apache Web server is highly configurable and Web applications can be stored in many directories, depending on your local configuration. openSUSE, by default, stores Web applications in /srv/www/cgi-bin/. To the maximum extent possible, each Web application should have an Novell AppArmor profile.

Once you find these programs, you can use the AppArmor Add Profile Wizard to create profiles for them. Refer to Section 22.1, “Adding a Profile Using the Wizard”.

Because CGI programs are executed by the Apache Web server, the profile for Apache itself, usr.sbin.httpd2-prefork for Apache2 on openSUSE, must be modified to add execute permissions to each of these programs. For instance, adding the line /srv/www/cgi-bin/my_hit_counter.pl rpx grants Apache permission to execute the Perl script my_hit_counter.pl and requires that there be a dedicated profile for my_hit_counter.pl. If my_hit_counter.pl does not have a dedicated profile associated with it, the rule should say /srv/www/cgi-bin/my_hit_counter.pl rix to cause my_hit_counter.pl to inherit the usr.sbin.httpd2-prefork profile.

Some users might find it inconvenient to specify execute permission for every CGI script that Apache might invoke. Instead, the administrator can grant controlled access to collections of CGI scripts. For instance, adding the line /srv/www/cgi-bin/*.{pl,py,pyc} rix allows Apache to execute all files in /srv/www/cgi-bin/ ending in .pl (Perl scripts) and .py or .pyc (Python scripts). As above, the ix part of the rule causes Python scripts to inherit the Apache profile, which is appropriate if you do not want to write individual profiles for each Python script.

[Note]

If you want the subprocess confinement module (apache2-mod-apparmor) functionality when Web applications handle Apache modules (mod_perl and mod_php), use the ChangeHat features when you add a profile in YaST or at the command line. To take advantage of the subprocess confinement, refer to Section 24.1, “Apache ChangeHat”.

Profiling Web applications that use mod_perl and mod_php requires slightly different handling. In this case, the program is a script interpreted directly by the module within the Apache process, so no exec happens. Instead, the Novell AppArmor version of Apache calls change_hat() using a subprofile (a hat) corresponding to the name of the URI requested.

[Note]

The name presented for the script to execute might not be the URI, depending on how Apache has been configured for where to look for module scripts. If you have configured your Apache to place scripts in a different place, the different names appear in log file when Novell AppArmor complains about access violations. See Chapter 26, Managing Profiled Applications.

For mod_perl and mod_php scripts, this is the name of the Perl script or the PHP page requested. For example, adding this subprofile allows the localtime.php page to execute and access the local system time:

/usr/bin/httpd2-prefork {
  # ...
  ^/cgi-bin/localtime.php {
    /etc/localtime                  r,
    /srv/www/cgi-bin/localtime.php  r,
    /usr/lib/locale/**              r,
  }
}

If no subprofile has been defined, the Novell AppArmor version of Apache applies the DEFAULT_URI hat. This subprofile is basically sufficient to display an HTML Web page. The DEFAULT_URI hat that Novell AppArmor provides by default is the following:

^DEFAULT_URI {
    /usr/sbin/suexec2                  mixr,
    /var/log/apache2/**                rwl,
    @{HOME}/public_html                r,
    @{HOME}/public_html/**             r,
    /srv/www/htdocs                    r,
    /srv/www/htdocs/**                 r,
    /srv/www/icons/*.{gif,jpg,png}     r,
    /srv/www/vhosts                    r,
    /srv/www/vhosts/**                 r,
    /usr/share/apache2/**              r,
    /var/lib/php/sess_*                rwl }
    

To use a single Novell AppArmor profile for all Web pages and CGI scripts served by Apache, a good approach is to edit the DEFAULT_URI subprofile.

19.4.2. Immunizing Network Agents

To find network server daemons and network clients (such as fetchmail, Firefox, Amarok or Banshee) that need to be profiled, you should inspect the open ports on your machine, consider the programs that are answering on those ports, and provide profiles for as many of those programs as possible. If you provide profiles for all programs with open network ports, an attacker cannot get to the file system on your machine without passing through a Novell AppArmor profile policy.

Scan your server for open network ports manually from outside the machine using a scanner (such as nmap), or from inside the machine using the netstat --inet -n -p command. Then, inspect the machine to determine which programs are answering on the discovered open ports.

[Tip]

Refer to the man page of the netstat command for a detailed reference of all possible options.