This chapter describes how to set up and administer auditing. Auditing enables system administrators to monitor the actions of the users. The auditing mechanism enables an administrator to detect potential security breaches. Auditing can reveal suspicious or abnormal patterns of system usage and provides the means to trace suspect actions back to a specific user. Auditing can serve as a deterrent: if users know that their actions are likely to be audited, they might be less likely to attempt malicious activities.
Successful auditing depends on two other security features: identification and authentication. At login, after a user supplies a user name and password, a unique audit ID is associated with the user's process. The audit ID is inherited by every process started during the login session. Even if a user changes identity (see the su(1M) man page), all actions performed are tracked with the same audit ID.
Auditing makes it possible to:
Monitor security-relevant events that take place on the system
Record the events in an audit trail
Detect misuse or unauthorized activity (by analyzing the audit trail)
During system configuration, the system administrator selects which activities to monitor. The administrator can also fine-tune the degree of auditing that is done for individual users.
After audit data is collected, audit-reduction and interpretation tools allow the examination of interesting parts of the audit trail. For example, you can choose to look at audit records for individual users or groups, look at all records for a certain type of event on a specific day, or select records that were generated at a certain time of day.
The rest of this chapter describes how to set up and administer auditing. Chapter 4, Device Allocation describes how to interpret the audit data.
Auditing is enabled by starting up the audit daemon, (see the auditd(1M) man page). This can be done manually be executing /usr/sbin/auditd as root.
The existence of a file with the path name /etc/security/audit_startup causes the audit daemon to be run automatically when the system enters multiuser mode. The file is actually an executable script that is invoked as part of the startup sequence just prior to the execution of the audit daemon (see the audit_startup(1M) man page). A default audit_startup script that automatically configures the event to class mappings and sets the audit policies is set up during the BSM package installation.
Security-relevant actions can be audited. The system actions that are auditable are defined as audit events in the /etc/security/audit_event file. Each auditable event is defined in the file by a symbolic name, an event number, a set of preselection classes, and a short description (see the audit_event(4) man page).
Most events are attributable to an individual user. However, some events are nonattributable because they occur at the kernel-interrupt level or before a user is identified and authenticated. Nonattributable events are auditable as well.
Each audit event is also defined as belonging to an audit class or classes. By assigning events to classes, an administrator can more easily deal with large numbers of events. When naming a class, you simultaneously addresses all of the events in that class. The mapping of audit events to classes is configurable and the classes themselves are configurable. These configuration changes can be made in the audit_event file.
Whether or not an auditable event is recorded in the audit trail depends on whether the administrator preselects a class for auditing that includes the specific event. Out of 32 possible audit classes, 18 are defined. The 18 classes include the two global classes: all and no.
Events generated by the kernel (system calls) have event numbers between 1 and 2047. The event names for kernel events begin with AUE_, followed by an uppercase mnemonic for the event. For example, the event number for the creat() system call is 4 and the event name is AUE_CREAT.
Events generated by application software outside the kernel range from 2048 to 65535. The event names begin with AUE_, followed by a lowercase mnemonic for the event. Check the file, /etc/security/audit_event, for exact numbers of individual events. Table 2-1 shows general categories of user-related events.
Table 2-1 Audit Event Categories
Number Range |
Type of Event |
---|---|
2048-65535 |
User-level audit events |
2048-32767 |
Reserved for SunOS user-level programs |
32768-65536 |
Each audit record describes the occurrence of a single audited event and includes such information as who did the action, which files were affected, what action was attempted, and where and when it occurred.
The type of information saved for each audit event is defined as a set of audit tokens. Each time an audit record is created for an event, the record contains some or all of the tokens defined for it, depending on the nature of the event. The audit record descriptions in Appendix A list all the audit tokens defined for each event and what each token means.
Audit records are collected in a trail (see the audit.log(4) man page) and can be converted to a human readable format by praudit (see the praudit(1M) man page). See Chapter 3, Audit Trail Analysis for details.
Audit flags indicate classes of events to audit. Machine-wide defaults for auditing are specified for all users on each machine by flags in the audit_control file, which is described in "The audit_control File".
The system administrator can modify what is audited for individual users by putting audit flags in a user's entry in the audit_user file. The audit flags are also used as arguments to auditconfig (see the auditconfig(1M) man page).
Each predefined audit class is shown in Table 2-2 with the audit flag (which is the short name that stands for the class), the long name, a short description, and a longer definition. The system administrator uses the audit flags in the auditing configuration files to specify which classes of events to audit. Additional classes can be defined and existing classes can be renamed by modifying the audit_class file (see the audit_class(4) man page).
Table 2-2 Audit Classes
Short Name |
Long Name |
Short Description |
---|---|---|
Read of data, open for reading, and so forth |
||
Write of data, open for writing, and so forth |
||
Access of object attributes: stat, pathconf, and so forth |
||
Change of object attributes: chown, flock, and so forth |
||
Creation of object |
||
Deletion of object |
||
Process operations: fork, exec, exit, and so forth |
||
Network events: bind, connect, accept, and so forth |
||
Nonattributable events |
||
Administrative actions |
||
Login and logout events |
||
Application-defined event |
||
Program execution |
||
Miscellaneous |
||
Depending on the prefixes, a class of events can be audited whether it succeeds or fails, or only if it succeeds, or only if it fails. The format of the audit flag is shown here.
prefixflag
Table 2-3 shows prefixes that specify whether the audit class is audited for success or failure or both.
Table 2-3 Prefixes Used in Audit Flags
Prefix |
Definition |
---|---|
none | |
+ |
Audit for success only |
- |
Audit for failure only |
To give an example of how these work together, the audit flag lo means "all successful attempts to log in and log out and all failed attempts to log in." (You cannot fail an attempt to logout.) For another example, the -all flag refers to all failed attempts of any kind, and the +all flag refers to all successful attempts of any kind.
The -all flag can generate large amounts of data and fill up audit file systems quickly, so use it only if you have extraordinary reasons to audit everything.
Use the following prefixes in any of three ways: in the flags line in the audit_control file to modify already specified flags, in flags in the user's entry in the audit_user file, or with auditconfig (see the auditconfig(1M) man page).
The prefixes in the following table, along with the short names of audit classes, turn on or turn off previously specified audit classes. These prefixes only turn on or off previously specified flags.
Table 2-4 Prefixes Used to Modify Already-Specified Audit Flags
Prefix |
Definition |
---|---|
^- |
Turn off for failed attempts |
^+ | |
^ |
Turn off for both failed and successful attempts |
The ^- prefix is used in the flags line in the following example from an audit_control file.
In the sample screen below, the lo and ad flags specify that all logins and administrative operations are to be audited when they succeed and when they fail. The -all means audit "all failed events." Because the ^- prefix means "turn off auditing for the specified class for failed attempts," the ^-fc flag modifies the previous flag that specified auditing of all failed events; the two fields together mean "audit all failed events, except failed attempts to create file system objects."
flags:lo,ad,-all,^-fc |
An audit_control file on each machine is read by the audit daemon (see the audit_control(4) man page). The audit_control file is located in the /etc/security directory. A separate audit_control file is maintained on each machine because machines in the distributed system can mount their audit file systems from different locations or in a different order. For example, the primary audit file system for machineA might be the secondary audit file system for machineB.
You specify four kinds of information in four kinds of lines in the audit_control file:
The audit flags line (flags:) contains the audit flags that define what classes of events are audited for all users on the machine. The audit flags specified here are referred to as the machine-wide audit flags or the machine-wide audit preselection mask. Audit flags are separated by commas, with no spaces.
The nonattributable flags line (naflags:) contains the audit flags that define what classes of events are audited when an action cannot be attributed to a specific user. The flags are separated by commas, with no spaces.
The audit threshold line (minfree:) defines the minimum free-space level for all audit file systems. See "What Makes a Directory Suitable". The minfree percentage must be greater than or equal to 0. The default is 20 percent.
The directory definition lines (dir:) define which audit file systems and directories the machine will use to store its audit trail files. There can be one or more directory definition lines. The order of the dir: lines is significant, because auditd opens audit files in the directories in the order specified (see the audit(1M) man page). The first audit directory specified is the primary audit directory for the machine, the second is the secondary audit directory where the audit daemon puts audit trail files when the first one fills, and so forth.
The administrator creates an audit_control file during the configuration process on each machine.
After the audit_control file is created during system configuration, the administrator can edit it. After a change, the administrator runs audit -s to instruct the audit daemon to reread the audit_control file.
The audit -s command does not change the preselection mask for existing processes. Use autoconfig, setaudit (see the getuid(2) man page), or auditon for existing processes.
Following is a sample audit_control file for the machine dopey. dopey uses two audit file systems on the audit server blinken, and a third audit file system mounted from the second audit server winken, which is used only when the audit file systems on blinken fill up or become unavailable. The minfree value of 20 percent specifies that the warning script is run when the file systems are 80 percent filled and the audit data for the current machine will be stored in the next available audit directory, if any (see the audit_warn(1M) man page). The flags specify that all logins and administrative operations are to be audited (whether or not they succeed), and that failures of all types, except failures to create a file system object, are to be audited.
flags:lo,ad,-all,^-fc naflags:lo,nt minfree:20 dir:/etc/security/audit/blinken/files dir:/etc/security/audit/blinken.1/files # # Audit filesystem used when blinken fills up # dir: /etc/security/audit/winken |
If it is desirable to audit some users differently from others, the administrator can edit the audit_user file to add audit flags for individual users. If specified, these flags are combined with the system-wide flags specified in the audit control file to determine which classes of events to audit for that user. The flags the administrator adds to the user's entry in the audit_user file modify the defaults from the audit_control file in two ways: by specifying a set of event classes that are never to be audited for this user or by specifying a set of event classes that are always to be audited.
Three fields are in the audit_user file entry for each user. The first field is the username, the second field is the always-audit field, and the third is the never-audit field. The two auditing fields are processed in sequence, so auditing is enabled by the first field and turned off by the second.
Avoid the common mistake of leaving the all set in the never-audit field. This causes all auditing to be turned off for that user, overriding the flags set in the always-audit field.
Using the never-audit flags for a user is not the same as removing classes from the always-audit set. For example, suppose (as shown in the examples below), you have a user fred for whom you want to audit everything except successful reads of file system objects. (This is a good way to audit almost everything for a user while generating only about three-quarters of the audit data that would be produced if all data reads were also audited.) You also want to apply the system defaults to fred. Here are two possible audit_user entries.
The correct entry:
fred:all,^+fr: |
The incorrect entry:
fred:all:+fr |
The first example says, "always audit everything except successful file-reads." The second example says "always audit everything, but never audit successful file-reads." The second example is incorrect because it overrides the system default. The first example achieves the desired effect: any earlier default applies, as well as what's specified in the audit_user entry.
Successful events and failed events are treated separately, so a process can (for example) generate more audit records when an error occurs than when the event is successful.
The following audit characteristics are set at initial login:
Process preselection mask
Audit ID
Audit Session ID
Terminal ID (port ID, machine ID)
When a user logs in, login combines the machine-wide audit flags from the audit_control file with the user-specific audit flags (if any) from the audit_user file, to establish the process preselection mask for the user's processes. The process preselection mask specifies whether events in each audit event class are to generate audit records.
The algorithm for obtaining the process preselection mask is as follows: the audit flags from the flags: line in the audit_control file are added to the flags from the always-audit field in the user's entry in the audit_user file. The flags from the never-audit field from the user's entry in the audit_user file are then subtracted from the total:
user's process preselection mask = (flags: line + always audit flags) - never audit flags
A process also acquires its audit ID when the user logs in, and this audit ID is inherited by all child processes started by the user's initial process. The audit ID helps enforce accountability. Even after a user becomes root, the audit ID remains the same. The audit ID that is saved in each audit record always allows the administrator to trace actions back to the original user who had logged in.
The audit session ID is assigned at login and inherited by all descendant processes.
The terminal ID consists of the host name and the Internet address, followed by a unique number that identifies the physical device on which the user logged in. Most of the time the login is through the console and the number that corresponds to the console device is 0.
The audit trail is created by the audit daemon (see the auditd(1M) man page). The audit daemon starts on each machine when the machine is brought up. After auditd starts at boot time, it is responsible for collecting the audit trail data and writing the audit records into audit files, which are also called audit log files. See the audit.log(4) man page for a description of the file format.
The audit daemon runs as root. All files it creates are owned by root. Even when auditd has no classes to audit, auditd continuously operates, looking for a place to put audit records. The auditd operations continue even if the rest of the machine's activities are suspended because the kernel's audit buffers are full. The audit operations can continue because auditd is not audited.
Only one audit daemon can run at a time. An attempt to start a second one results in an error message, and the new one exits. If there is a problem with the audit daemon, you should try using audit -t to terminate auditd gracefully, then restart it manually.
The audit_warn script is run by auditd whenever the daemon switches audit directories or encounters difficulty (such as a lack of storage). As distributed, the audit_warn script sends mail to an audit_warn alias and sends a message to the console. Your site should customize audit_warn to suit your needs. Customizing the audit_warn script is described in "The audit_warn Script".
When auditd starts on each machine, it creates the file /etc/security/audit_data. The format of the file consists of a single entry with the two fields separated by a colon (see the audit_data(4) man page). The first field is the audit daemon's process ID, and the second field is the path name of the audit file to which the audit daemon is currently writing audit records. Here is an example:
# cat /etc/security/audit_data 116:/etc/security/audit/blinken.1/files/19910320100002.not_terminated.lazy |
The following list summarizes what the audit daemon, auditd, does.
auditd opens and closes audit log files in the directories specified in the audit_control file, in the order in which they are specified.
auditd reads audit data from the kernel and writes it to an audit file.
auditd executes the audit_warn script when the audit directories fill past limits specified in the audit_control file. The script, by default, sends warnings to the audit_warn alias and to the console.
With the system default configuration, when all audit directories are full, processes that generate audit records are suspended. In addition, auditd writes a message to the console and to the audit_warn alias. (The auditing policy can be reconfigured with autoconfig.) At this point only the system administrator can log in to write audit files to tape, delete audit files from the system, or do other cleanup.
When the audit daemon starts as the machine is brought up to multiuser mode, or when the audit daemon is instructed by the audit -s command to reread the file after the file has been edited, auditd determines the amount of free space necessary and reads the list of directories from the audit_control file. It then uses those directories as possible locations for creating audit files.
The audit daemon maintains a pointer into this list of directories, starting with the first. Every time the audit daemon needs to create an audit file, it puts the file into the first available directory in the list, starting at the audit daemon's current pointer. The pointer can be reset to the beginning of the list if the administrator enters the audit -s command. When you use the audit -n command to instruct the daemon to switch to a new audit file, the new file is created in the same directory as the current file.
A directory is suitable to the audit daemon if it is accessible to the audit daemon, which means that it must be mounted, that the network connection (if remote) permits successful access, and that the permissions on the directory allow access. Also, in order for a directory to be suitable for audit files, it must have sufficient free space remaining. You can edit the minfree: line in the audit_control file to change the default of 20 percent. To give an example of how the minfree percentage is applied, if the default minimum free space of 20 percent is accepted, an email notice is sent to the audit_warn alias whenever a file system becomes more than 80 percent full.
When no directories on the list have enough free space left, the daemon starts over from the beginning of the list and picks the first accessible directory that has any space available until the hard limit is reached. In the default configuration, if no directories are suitable, the daemon stops processing audit records, and they accumulate within the kernel until all processes generating audit records are suspended.
To keep audit files at a manageable size, a cron job can be set up that periodically switches audit files (see the cron(1M) man page). Intervals might range from once per hour to twice per day, depending on the amount of audit data being collected. The data can then be filtered to remove unnecessary information, and then compressed.
Whenever the audit daemon encounters an unusual condition while writing audit records, it invokes the /etc/security/audit_warn script. See the audit_warn(1M) man page. This script can be customized by your site to warn of conditions that might require manual intervention or to handle them automatically. For all error conditions, audit_warn writes a message to the console and sends a message to the audit_warn alias. This alias should be set up by the administrator after enabling BSM.
When the following conditions are detected by the audit daemon, it invokes audit_warn.
An audit directory has become more full than the minfree value allows. (The minfree or soft limit is a percentage of the space available on an audit file system.)
The audit_warn script is invoked with the string soft and the name of the directory whose space available has gone below the minimum. The audit daemon switches automatically to the next suitable directory and writes the audit files there until this new directory reaches its minfree limit. The audit daemon then goes to each of the remaining directories in the order listed in audit_control, and writes audit records until each is at its minfree limit.
All the audit directories are more full than the minfree threshold.
The audit_warn script is invoked with the string allsoft as an argument. A message is written to the console and mail is sent to the audit_warn alias.
When all audit directories listed in audit_control are at their minfree limits, the audit daemon switches back to the first one, and writes audit records until the directory completely fills.
An audit directory has become completely full with no space remaining.
The audit_warn script is invoked with the string hard and the name of the directory as arguments. A message is written to the console and mail is sent to the audit_warn alias.
The audit daemon switches automatically to the next suitable directory with any space available, if any. The audit daemon goes to each of the remaining directories in the order listed in audit_control and writes audit records until each is full.
All the audit directories are completely full. The audit_warn script is invoked with the string allhard as an argument.
In the default configuration, a message is written to the console and mail is sent to the audit_warn alias. The processes generating audit records are suspended. The audit daemon goes into a loop, waiting for space to become available, and resumes processing audit records when that happens. While audit records are not being processed, no auditable activities take place--every process that attempts to generate an audit record is suspended. This is one reason why you would want to set up a separate audit administration account that could operate without any auditing enabled. The administrator could then operate without being suspended.
An internal error occurs: another audit daemon process is already running (string ebusy), a temporary file cannot be used (string tmpfile), the auditsvc() system call fails (string auditsvc), or a signal was received during auditing shutdown (string postsigterm).
Mail is sent to the audit_warn alias.
A problem is discovered with the audit_control file's contents. By default, mail is sent to the audit_warn alias and a message is sent to the console.
Use auditreduce to merge audit records from one or more input audit files or to perform a post selection of audit records. See the auditreduce(1M) man page. To merge the entire audit trail, the system administrator enters the command on the machine on which all the audit file systems for the distributed system are mounted.
When multiple machines running BSM are administered as part of a distributed system, each machine performs auditable events, and each machine writes audit records to its own machine-specific audit file. This procedure simplifies software and is robust in the face of machine failures. However, without auditreduce, you would have to look at every one of the files to determine what a particular user did because each machine produces its own set of audit files.
The auditreduce command makes the job of maintaining the whole audit trail practical. Using auditreduce (or shell scripts you write yourself to provide a higher-level interface), you can read the logical combination of all audit files in the system as a single audit trail without regard to how the records were generated or where they are stored.
The auditreduce program operates on the audit records produced by the audit daemon. Records from one or more audit files are selected and merged into a single, chronologically ordered output file. The merging and selecting functions of auditreduce are logically independent. auditreduce selects messages from the input files as the records are read, before the files are merged and written to disk.
Without options, auditreduce merges the entire audit trail (which consists of all of the audit files in all of the subdirectories in the audit root directory /etc/security/audit) and sends all the audit records to standard output. Making the records human-readable is done by the praudit command.
Following are some of the actions performed by some of the options to the auditreduce command.
You can request that the output contain audit records generated by only certain audit flags.
You can request audit records generated by one particular user.
You can request audit records generated on specific dates.
With no arguments, auditreduce looks in all subdirectories below /etc/security/audit, the default audit root directory, for a files directory in which the date.date.hostname files reside. The auditreduce command is very useful when the audit data for different hosts (Figure 2-1) or for different audit servers (Figure 2-2) reside in separate directories.
The audit data cannot be in the default directory -- perhaps because the partition for /etc/security/audit is very small or because you want to store audit data on another partition without symbolically linking that partition to /etc/security/audit. You can give auditreduce another directory (-R) to substitute for /etc/security/audit, or you can specify one particular subdirectory (-S):
# auditreduce -R /var/audit-alt # auditreduce -S /var/audit-alt/host1 |
You can direct auditreduce to treat only certain files by specifying them as command arguments:
# auditreduce /var/audit/bongos/files/1993*.1993*.bongos |
The auditreduce(1M) man page for auditreduce lists other options and provides additional examples for using the command.
Because auditing consumes system resources, you must control the degree of detail that is recorded. When you decide what to audit, consider the following costs of auditing:
Costs of increased processing time
Costs of analysis of audit data
Costs of storage of audit data
The cost of increased processing time is the least significant of the costs of auditing. The first reason is that auditing generally does not occur during computational-intensive tasks--image processing, complex calculations, and so forth. The other reason that processing cost is usually insignificant is that single-user workstations have plenty of extra CPU cycles.
The cost of analysis is roughly proportional to the amount of audit data collected. The cost of analysis includes the time it takes to merge and review audit records, and the time it takes to archive them and keep them in a safe place.
The fewer records you generate, the less time it takes to analyze them, so upcoming sections describe how you can reduce the amount of data collected, while still providing enough coverage to achieve your site's security goals.
Storage cost is the most significant cost of auditing. The amount of audit data depends on the following:
Number of users
Number of machines
Amount of use
Degree of security required
Because the factors vary from one situation to the next, no formula can determine in advance the amount of disk space to set aside for audit data storage.
Full auditing (with the all flag) can fill up a disk in no time. Even a simple task like compiling a program of modest size (for example, 5 files, 5000 lines total) in less than a minute could generate thousands of audit records, occupying many megabytes of disk space. Therefore, it is very important to use the preselection features to reduce the volume of records generated. For example, omitting the fr class instead of all classes can reduce the audit volume by more than two-thirds. Efficient audit file management is also important after the audit records are created, to reduce the amount of storage required.
The following sections give some ideas about how to reduce the costs of storage by auditing selectively to reduce the amount of audit data collected, while still meeting your site's security needs. Also discussed are how to set up audit file storage and archiving procedures to reduce storage requirements.
Before configuring auditing, understand the audit flags and the types of events they flag. Develop a philosophy of auditing for your organization that is based on the amount of security your site requires, and the types of users you administer.
Unless the process audit preselection mask is modified dynamically, the audit characteristics in place when a user logs in are inherited by all processes during the login session, and, unless the databases are modified, the process preselection mask applies in all subsequent login sessions.
Dynamic controls refer to controls put in place by the administrator while processes are running. These persist only while the affected processes (and any of their children) exist, but will not continue in effect at the next login. Dynamic controls apply to one machine at a time, since the audit command only applies to the current machine where you are logged in. However, if you make dynamic changes on one machine, you should make them on all machines at the same time.
Each process has two sets of one-bit flags for audit classes. One set controls whether the process is audited when an event in the class is requested successfully; the other set when an event is requested but fails (for any reason). It is common for processes to be more heavily audited for failures than for successes, since this can be used to detect attempts at browsing and other types of attempts at violating system security.
In addition to supplying the per-user audit control information in the static databases, you can dynamically adjust the state of auditing while a user's processes are active on a single machine.
To change the audit flags for a specific user to a supplied value, use the auditconfig command with the -setpmask, -setsmask, or -setumask options. The command changes the process audit flags for one process, one audit session ID, or one audit user ID respectively. See the auditconfig(1M) man page and "The auditconfig Command".
The administrator sets up auditing for the default configuration. You might want all users and administrators to be audited according to the system-wide audit flags you specified in the audit_control file. To fine-tune auditing for individual users, you modify the users' entries in the audit_user file. See the audit_control(4) and audit_user(4) man pages. You can also choose to add audit flags to users' entries at the time you add new users, and you should probably set up auditing for the new user just after you unlock the account and configure the security attributes for that user.
Techniques in this section can allow you to achieve your organization's security goals while auditing more efficiently:
Random auditing of only a certain percentage of users at any one time
Real-time monitoring of the audit data for unusual behaviors. (You set up procedures to monitor the audit trail as it is generated for certain activities and to trigger higher levels of auditing of particular users or machines when suspicious events occur.)
Reducing the disk-storage requirements for audit files by combining, reducing, and compressing them, and developing procedures for storing them offline
Another technique is to monitor the audit trail in real time. You can write a script to trigger an automatic increase in the auditing of certain users or certain machines in response to detection of unusual events.
To monitor the audit trail in real time and watch for unusual events, write a script that monitors creation of audit files on all the audit file servers and processes them with the tail command (see the tail(1) man page). The output of tail -0f, piped through praudit, yields a stream of audit records as soon as they are generated. This stream can be analyzed for unusual message types or other indicators and delivered to the auditor or used to trigger automatic responses. The script should be written to constantly watch the audit directories for the appearance of new not_terminated audit files, and also the termination of outstanding tail processes when their files are no longer being written to (that is, have been replaced by new ones).
Use auditreduce with the -O option to combine several audit files into one and save them in a specified output file.
Although auditreduce can do this type of combination and deletion automatically (see the -C and -D options in the auditreduce(1M) man page), it is often easier to select the files manually (perhaps with find) and use auditreduce to combine just the named set of files. When auditreduce is used this way, it merges all the records from its input files into a single output file. The input files should then be deleted, and the output file kept in a directory named /etc/security/audit/server-name/files so that auditreduce can find it.
# auditreduce -O combined-filename |
The auditreduce program can also reduce the number of records in its output file by eliminating the less interesting ones as it combines the input files. You might use auditreduce to eliminate all except the login/logout events in audit files over a month old, assuming that if you needed to retrieve the complete audit trail, you could recover it from backup tapes.
# auditreduce -O daily.summary -b 19930513 -c lo; compress *daily.summary # mv *daily.summary /etc/security/summary.dir |
This section describes where audit files are stored, how they are named, and how to manage audit file storage throughout a distributed system.
The audit trail is created when the audit daemon, auditd, is started, and is closed when a new audit trail file is created, or when the audit daemon is terminated. The audit trail can consist of audit files in several audit directories, or an audit directory can contain several audit trails.
Most often the audit directories are separate audit file system partitions. Even though they can be included in other file systems, this is not recommended.
As a rule, locate primary audit directories in dedicated audit file systems mounted on separate partitions. Normally, all audit file systems are subdirectories of /etc/security/audit. These should be dedicated audit file systems to ensure that normal use of the partition is not interrupted, if the audit directories become filled with audit files.
Even though you can physically locate audit directories within other file systems that are not dedicated to auditing, do not do this except for directories of last resort. Directories of last resort are directories where audit files are written only when there is no other suitable directory available.
One other scenario where locating audit directories outside of dedicated audit file systems could be acceptable is in a software development environment where auditing is optional, and where it is more important to make full use of disk space than to keep an audit trail. Putting audit directories within other file systems would never be acceptable in a security-conscious production environment.
A diskfull machine should have at least one local audit directory, which it can use as a directory of last resort, if unable to communicate with the audit server.
Mount audit directories with the read-write (rw) option. When mounting audit directories remotely (using NFS software), also use the intr option.
List the audit file systems on the audit server where they reside. The export list should include all machines in the configuration.
Each audit file is a self-contained collection of records; the file's name identifies the time span during which the records were generated and the machine that generated them.
Audit files that are complete have names of the following form:
start-time.finish-time.machine |
where start-time is the time of the first audit record in the audit file, finish-time is the time of the last record, and machine is the name of the machine that generated the file. An example of these names can be found in "Example of a Closed Audit File Name".
If the audit log file is still active, it has a name of the following form:
start-time.not_terminated.machine |
The file name time stamps are used by auditreduce to locate files containing records for the specific time range that has been requested; this is important because there can be a month's supply or more of audit files on line, and searching them all for records generated in the last 24 hours would be unacceptably expensive.
The start-time and end-time are time stamps with one-second resolution; they are specified in Greenwich mean time. The format is four digits for the year, followed by two for each month, day, hour, minute, and second, as shown below.
YYYYMMDDHHMMSS |
The time stamps are in GMT to ensure that they will sort in proper order even across a daylight savings time boundary. Because they are in GMT, the date and hour must be translated to the current time zone to be meaningful; beware of this whenever manipulating these files with standard file commands rather than with auditreduce.
The format of a file name of a still-active file is shown below:
YYYYMMDDHHMMSS.not_terminated.hostname |
Here is an example:
19900327225243.not_terminated.lazy |
The audit log files are named by the beginning date, so the example above was started in 1990, on March 27, at 10:52:43 p.m, GMT. The not_terminated in the file name means either that the file is still active or that auditd was unexpectedly interrupted. The name lazy at the end is the host name whose audit data is being collected.
The format of the name of a closed audit log file is shown below:
YYYYMMDDHHMMSS.YYYYMMDDHHMMSS.hostname |
Here is an example:
19900320005243.19900327225351.lazy |
The example above was started in 1990, on March 20, at 12:52:43 a.m., GMT. The file was closed March 27, at 10:53:51 p.m., GMT. The name lazy at the end is the host name of the machine whose audit data is being collected.
Whenever auditd is unexpectedly interrupted, the audit file open at the time gets the not_terminated end file name time stamp. Also, when a machine is writing to a remotely mounted audit file and the file server crashes or becomes inaccessible, the not_terminated end time stamp remains in the current file's name. The audit daemon opens a new audit file and keeps the old name intact.
The auditreduce command processes files marked not_terminated, but because such files can contain incomplete records at the end, future processing can generate errors. To avoid errors, clean the files of any incomplete records. Before cleaning the files, make sure that auditd is not currently writing to the files you want to clean. To check, look at the audit_data file to determine the current process number of auditd. If that process is still running, and if the file name in audit_data is the same as the file in question, do not clean the file.
You can clean a file with the -O option of auditreduce. This creates a new file containing all the records that were in the old one, but with a proper file name time stamp. This operation loses the previous file pointer that's kept at the beginning of each audit file.
Or you can write a program to read through the file, locate the last record, rename the file, and clear out any incomplete records. A program can also keep the previous file pointer intact and determine which file to use next.
Assign at least one primary audit directory to each machine.
The primary audit directory is the directory where a machine places its audit files under normal conditions.
Assign at least one secondary audit directory to each machine that is located on a different audit file server than the primary directory.
The secondary audit directory is where a machine places audit files if the primary directory is full or inaccessible, because of network failure, NFS server crash, or some other reason.
On every diskfull machine create a local audit directory of last resort (preferably a dedicated audit file system) that is used when the network is inaccessible or the primary and secondary directories are unusable.
Spread the directories used as primary and secondary destinations evenly over the set of audit servers in the system.
Create audit file systems according to the requirements discussed in this section.
The /etc/security directory contains subdirectories with all the audit files and also contains several other files related to audit control. Because the /etc/security directory contains the per-machine audit_data file, which must be available for successful startup of the audit daemon at boot time, the /etc/security directory must be part of the root file system.
The audit post-selection tools look in directories under /etc/security/audit by default. For this reason, the path name of the mount point for the first audit file system on an audit server is in the form: /etc/security/audit/server-name (where server-name is the name of the audit server). If more than one audit partition is on an audit server, the name of the second mount point is: /etc/security/audit/server-name.1, the third is /etc/security/audit/server-name.2, and so forth.
For example, the names of the audit file systems available on the audit server winken are /etc/security/audit/winken and /etc/security/audit/winken.1.
On the audit server, each audit file system must also have a subdirectory named files. This files subdirectory is where the audit files are located and where the auditreduce commands look for them. For example, the audit file system on audit server winken should have a files subdirectory whose full path name is: /etc/security/audit/winken/files.
You should make sure that the local audit_control file on each machine tells the audit daemon to put the audit files in the files subdirectory. Here is the dir: line for the audit_control file on a machine mounting the audit file system from eagle:
dir: /etc/security/audit/eagle/files
The extra level of hierarchy is required to prevent a machine's local root file system from filling with audit files when (for whatever reason) the /etc/security/audit/server-name[.suffix] directory is not available on the audit server. Because the files subdirectory is present on the audit server and there are no files subdirectory on any of the clients, audit files cannot be created unintentionally in the local mount-point directory if the mount fails.
Make sure that each audit directory contains nothing except audit files.
Assign the required permissions to the audit file systems.
The permissions that must appear on the /etc/security/audit/server-name directory and the files directory that must be created beneath it on the audit server are shown in Table 2-5.
Table 2-5 Audit File Permissions
Owner |
Group |
Permissions |
---|---|---|
root |
staff |
2750 |
When you add the dir: entries in the audit_control file, make sure the full path down to the files subdirectory is specified. The following example shows an audit_control file dir: entry for the server blinken, which is storing its audit files on its own local disk.
# cat /etc/security/audit_control dir:/etc/security/audit/blinken.1/files dir:/etc/security/audit/blinken.2/files |
The following steps are included here to provide an overview of what is required to set up audit directories and specify which audit classes will be audited.
Format and partition the disks to create the dedicated audit partitions.
A rule of thumb is to assign 100 MBytes of space for each machine that is on the distributed system; but remember that the disk space requirements at your site will be based on how much auditing you perform and can be far greater than this figure per machine.
Assign the audit file systems to the dedicated partitions.
Each diskfull machine should have a backup audit directory on the local machine in case its NFS-mounted audit file systems are not available.
While each machine is in single-user mode, run tunefs -m 0 on each dedicated audit partition to reduce reserved file system space to 0 percent.
A reserved space percentage (called the minfree limit) is specified for audit partitions in the audit_control file. The default is 20 percent, and this percentage is tunable. Because this value is set by each site in the audit_control file, you should remove the automatically reserved file system space that is set aside by default for all file systems.
Set the required permissions on each of the audit directories on the audit servers, and make a subdirectory in each audit directory called files.
Use chown and chmod to assign each audit directory and each files subdirectory the required permissions.
If using audit servers, export the audit directories with the /etc/dfs/dfstab file.
Create the audit_control file entries for all the audit directories in the audit_control file on each machine, specifying the files subdirectory.
On each audit client, create the entries for the audit file systems in the /etc/vfstab file.
On each audit client, create the mount point directories and use chmod and chown to set the correct permissions.
First, plan for audit trail storage.
In the /etc/security/audit_class file, define the classes needed at your site.
If the default classes are suitable, you do not need to define new ones. See the audit_class(4) man page.
Set up event-to-class mapping in /etc/security/audit_event.
This step is not needed if the default mapping suits your site's needs. See the audit_event(4) man page.
Determine how much auditing your site needs to do.
Balance your site's security needs against the availability of disk space for audit trail storage.
See "Controlling Audit Costs", "Auditing Efficiently", and "Learning About the Audit Trail" for guidance on how to reduce storage requirements while still maintaining site security, as well as how to design audit storage.
Determine which machines will be audit servers and which will be clients of the audit servers.
Determine the names and locations of audit file systems.
Plan which machines will use which audit file systems on the audit servers.
After dealing with storage, decide who and what to audit.
Determine which audit classes you want to be audited system-wide and which flags to use to select the audit classes.
Determine if some users will be audited more than others, then decide which flags to use to modify a user's audit characteristics.
Determine the minimum free space (minfree), also called the soft limit, that should be on an audit file system before a warning is sent.
When the amount of space available goes below the minfree percentage, the audit daemon switches to the next suitable audit file system and sends a notice that the soft limit has been exceeded. (What makes an audit file system suitable is defined in "What Makes a Directory Suitable".)
A certain amount of auditing is configured by default on each machine. The default audit_control file contains the lines shown in Table 2-6, which set the audit directory as /var/audit, one system-wide audit flag (lo), a minfree threshold of 20 percent, and one nonattributable flag.
Table 2-6 audit_control File Entries
dir:/var/audit flags:lo minfree:20 naflags:ad |
Edit the /etc/security/audit_control file.
Specify which audit file systems to use for audit trail storage on this machine.
Make a dir: entry for each audit directory available to the current machine. See "Learning About the Audit Trail" for how to set up the audit directory scheme for the distributed system.
Specify the system-wide audit flags that will apply to all users' processes in the flags: field.
The system-wide audit flags in the flags: field will apply to all users' processes, and you should set the flag the same on every machine.
Change the minfree percentage, if desired, to reduce or enlarge the audit threshold.
Specify the naflags: that will apply to events that cannot be attributed to a particular user.
Use auditconfig to modify the audit policy, if you want modification.
See the auditconfig(1M) man page or "The auditconfig Command". The policy variable is a dynamic kernel variable, so its value is not saved when the system is brought down. Therefore, you should set the desired policy using the appropriate startup script.
Set the cnt policy or set up an audit administration account.
In the event of an audit trail overflow, either the cnt policy must be enabled, which allows further system functioning, or an account must be available that can work without being audited. To set up such an account:
In the /etc/passwd file, add the following entry.
audit::0:1::/:/sbin/sh |
This entry must be placed below the entry for the root user for processes owned by root to function properly.
To add a corresponding entry into the /etc/shadow file, type the following.
# pwconv pwconv: WARNING user audit has no password |
The password for the audit account will be established in Step d.
In the /etc/security/audit_user file, add the following entry to turn off auditing for the account.
audit:no:all |
Set a password for the new account using passwd.
# passwd audit |
Remember that actions taken through this account are not audited. To protect system integrity, choose a password that is not easily compromised. This example uses an account name of audit. Choose a name more appropriate for your site if you set up such an account.
If all audit file systems fill up, the audit_warn script sends a message to the console that the hard limit has been exceeded on all audit file systems and also sends mail to the alias. By default, the audit daemon remains in a loop sleeping and checking for space until some space is freed. All auditable actions are suspended.
A site's security requirements can be such that the loss of some audit data is preferable to having system activities suspended due to audit trail overflow. In that case, you can build automatic deletion or moving of audit files into the audit_warn script or set the auditconfig policy to drop records.
If your security policy requires that all audit data be saved, do the following:
Set up a schedule to regularly archive audit files and to delete the archived audit files from the audit file system.
Manually archive audit files by backing them up on tape or moving them to an archive file system.
Store context-sensitive information that will be needed to interpret audit records along with the audit trail.
Keep records of what audit files are moved off line.
Store the archived tapes appropriately.
Reduce the volume of audit data you store by creating summary files.
You can extract summary files from the audit trail using options to auditreduce, so that the summary files contain only records for certain specified types of audit events. An example of this is a summary file containing only the audit records for all logins and logouts. See Chapter 3, Audit Trail Analysis.
The autoconfig command provides a command line interface to get and set audit configuration parameters. See the auditconfig(1M) man page. Some of the options to auditconfig are:
Check the configuration of kernel audit event to class mappings and report any inconsistencies.
Reconfigure kernel event to class mappings at runtime to match the current mappings in the audit_event file.
Retrieve the machine-auditing condition. Table 2-7 shows the possible responses.
Table 2-7 Possible Auditing Conditions
Response |
Meaning |
---|---|
auditing |
Auditing is enabled and turned on. |
no audit |
Auditing is enabled but turned off. |
disabled |
The audit module is not enabled. |
Get the preselection classes to which the specified event is mapped.
Set the preselection classes to which the specified event is mapped.
Display the currently configured (runtime) kernel and user audit event information.
Get the audit ID, preselection mask, terminal ID, and audit session ID of the specified process.
Set the preselection mask of all processes with the specified audit session ID.
Set the preselection mask of all processes with the specified user audit ID.
Display the list of audit policies with a short description of each one.
Set the audit policy flags to the specified policies (see "Setting Audit Policies").
You can use auditconfig with the -setpolicy flag to change the default Solaris-BSM audit policies. The auditconfig command with the -lspolicy argument shows the audit policies that you can change. The policy flags are described below.
Record the environment and arguments on execv (see the exec(2) man page). The default is not to record these.
Record command-line arguments to execv. The default is not to record these.
Do not suspend auditable actions when the queue is full; just count how many audit records are dropped. The default is suspend.
Include the supplementary groups token in audit records. The default is that group token is not included.
Add secondary path tokens to audit record. These secondary paths are typically the path names of dynamically linked shared libraries or command interpreters for shell scripts. By default they are not included.
Include the trailer token in all records. The default is that the trailer token is not recorded.
Include a sequence number in every audit record. The default is to not include. (The sequence number could be used to analyze a crash dump to find out whether any audit records are lost.)
This procedure describes how to modify the default event to class mappings.
Edit the /etc/security/audit_event file to change the class mapping for each event to be changed.
Reboot the system or run auditconfig -conf to change the runtime kernel event-to-class mappings.
The file /etc/security/audit_class stores class definitions. Site-specific definitions can be added and default definitions can be changed. Each entry in the file has the form:
mask:name:description
Each class is represented as a bit in the mask, which is an unsigned integer, giving 32 different available classes plus two meta-classes of all and no; all is a conjunction of all allowed classes; no is the invalid class. Events mapped to this class are not audited. Events mapped solely to the no class are not audited, even if the all class is turned on. Below is a sample audit_class file:
0x00000000:no:invalid class 0x00000001:fr:file read 0x00000002:fw:file write 0x00000004:fa:file attribute access 0x00000008:fm:file attribute modify 0x00000010:fc:file create 0x00000020:fd:file delete 0x00000040:cl:file close 0xffffffffff:all:all classes |
If the no class is turned on in the system kernel,
the audit trail is flooded with records for the audit event AUE_NULL
.