The term auditing has multiple meanings within the domain of information security. For example, a security audit is a term used to describe the process of evaluating the security posture of an organization through penetration testing (pen testing), formal review of security policies, systems and networks.
At an individual system level, auditing refers to the logging of some or all of the actions of users and/or applications. It is passive security in that it only detects violations of security policy, but does not enforce it. It performs a similar role to that of network and host-based intrusion detection systems (IDS).
Auditing has been built into the Linux kernel since the release of the 2.6 kernel. The Linux Auditing Subsystem (LAuS) was developed by IBM and Novell/SUSE to meet CAPP (Controlled Access Protection Profile) compliance and to “make Linux more secure and to attain the Common Criteria EAL4 certificate.” Being a part of the kernel also has the advantage of lower overhead and being far more difficult to bypass except possibly with a rootkit.
At its most basic level, the auditing subsystem can monitor all system calls (events) made to the kernel. As the kernel provides the lowest-level access to system resources, every application must make more or more system calls, either directly or indirectly, when executed. The userspace audit daemon (/sbin/auditd) is responsible for writing the audit events to the audit log file which, in Fedora, is at /var/log/audit/audit.log. The audit daemon adds events to the audit log file as they occur. Audit logs can be configured to rotate. The audit daemon can also be configured to send audit events to a remote audit logging server. You must be root to manipulate audit files.
There are three types of audit rules:
- system call auditing.
- file and directory watch.
- audit system configuration.
At this stage a few simple examples might help you more easily understand the role of how the auditing works. All examples are based on recent releases of Fedora and Centos. Your mileage may vary on other distributions such as Ubuntu or Suse.
Suppose you wish to monitor (audit) all access to the password file /etc/passwd. As root enter the following command:
# auditctl -w /etc/passwd -k password-file -p war
where
- -w /etc/passwd: Insert a watch for the file system object at specified path (watch file).
- -p war: Set a permissions filter for the watch file. (r – read, w – write, x – execute, a – append).
- -k password-file: Set a filterkey (string , max 31 bytes) on the watch file.
The filterkey is a string of text up to 31 bytes long. It can uniquely identify the audit records produced by the watch. You will need to use filter key when searching audit logs. After this command is executed auditd is watching, i.e. monitoring, the file /etc/passwd for anything or anyone that might perform a read, write or append operation on the file. By the way, pathname globbing is not supported; a full pathname must always be specified.
If you deem it prudent to audit /etc/passwd, you also really should audit /etc/shadow. As root enter the following command:
# auditctl -w /etc/shadow -k shadow-file -p warx
The configuration file for the audit daemon (/sbin/auditd) is /etc/audit/auditd.conf. The default contents of this file on Fedora are:
log_file = /var/log/audit/audit.log log_format = RAW log_group = root priority_boost = 4 flush = INCREMENTAL freq = 20 num_logs = 4 disp_qos = lossy dispatcher = /sbin/audispd name_format = NONE ##name = mydomain max_log_file = 5 max_log_file_action = ROTATE space_left = 75 space_left_action = SYSLOG action_mail_acct = root admin_space_left = 50 admin_space_left_action = SUSPEND disk_full_action = SUSPEND disk_error_action = SUSPEND ##tcp_listen_port = tcp_listen_queue = 5 tcp_max_per_addr = 1 ##tcp_client_ports = 1024-65535 tcp_client_max_idle = 0 enable_krb5 = no krb5_principal = auditd ##krb5_key_file = /etc/audit/audit.key
As you can see, auditing is simply suspended in a number of cases (disk full, disk_error, and low disk space) but to reduce that possibility warnings are send to syslog when the disk space is less than 75 Mb and mailed to root when the disk space is less than 50Mb.
Here is the default contents of /etc/audit.rules:
This file contains the auditctl rules that are loaded # whenever the audit daemon is started via the initscripts. # The rules are simply the parameters that would be passed # to auditctl. # First rule - delete all -D # Increase the buffers to survive stress events. # Make this bigger for busy systems -b 320 # Feel free to add below this line. See auditctl man page
As you can see Fedora comes with no default rules. if you wanted to add the two rules we used above to monitor /etc/passwd and /etc/shadow to this file in order to survive a reboot, here are the appropriate lines to add:
-w /etc/passwd -k password-file -p war -w /etc/shadow -k shadow-file -p warx
So now that auditing is enabled for the two password files of interest to us, how do we create and view a report about any auditing events that occurred on this two files? Two CLI tools are provided to parse audit log files. ausearch searches the audit log(s) based upon specified criteria and returns any audit log entries matching those criteria. aureport produces reports on events of interest. You can also develop custom tools using the Audit Event Parsing Library (libaudit) to parse audit events.
Here is an example of using ausearch to check who accessed /etc/passwd:
# ausearch -f /etc/passed time->Sat Jun 26 22:45:26 2008 type=PATH msg=audit(1277606726.480:120): item=0 name="/etc/passwd" inode=2536140 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:etc_t:s0 type=CWD msg=audit(1277606726.480:120): cwd="/home/mpfj" type=SYSCALL msg=audit(1277606726.480:120): arch=c000003e syscall=2 success=yes exit=3 a0=7fff95dea57d a1=0 a2=619448 a3=1 items=1 ppid=3853 pid=3918 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="grep" exe="/bin/grep" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="password-file" ---- time->Sat Jun 26 22:45:33 2008 type=PATH msg=audit(1277606733.422:121): item=0 name="/etc/passwd" inode=2536140 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:etc_t:s0 type=CWD msg=audit(1277606733.422:121): cwd="/home/mpfj" type=SYSCALL msg=audit(1277606733.422:121): arch=c000003e syscall=191 success=yes exit=27 a0=407580 a1=3847815689 a2=a27050 a3=ff items=1 ppid=3853 pid=3919 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="vipw" exe="/usr/sbin/vipw" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="password-file"
There are a number of options available for ausearch to convert output to a more readable format or to restrict the range of records. See the ausearch man page for details.
Here are examples of the output from aureport:
# aureport --summary Summary Report ====================== Range of time in logs: 05/10/2008 11:04:35.579 - 06/27/2008 13:01:01.414 Selected time for report: 05/10/2010 11:04:35 - 06/27/2008 13:01:01.414 Number of changes in configuration: 97 Number of changes to accounts, groups, or roles: 24 Number of logins: 88 Number of failed logins: 2 Number of authentications: 426 Number of failed authentications: 9 Number of users: 3 Number of terminals: 16 Number of host names: 2 Number of executables: 31 Number of files: 2 Number of AVC's: 0 Number of MAC events: 231 Number of failed syscalls: 0 Number of anomaly events: 7 Number of responses to anomaly events: 0 Number of crypto events: 0 Number of keys: 2 Number of process IDs: 994 Number of events: 5031 # aureport -f File Report =============================================== # date time file syscall success exe auid event =============================================== 27. 06/26/2008 22:56:01 /etc/passwd 2 yes /usr/sbin/crond -1 146 28. 06/26/2008 22:56:01 /etc/passwd 2 yes /usr/sbin/crond -1 145 29. 06/26/2008 22:56:56 /etc/passwd 2 yes /lib64/dbus-1/dbus-daemon-launch-helper -1 148 30. 06/26/2008 22:56:56 /etc/passwd 2 yes /lib64/dbus-1/dbus-daemon-launch-helper -1 147 31. 06/26/2008 22:57:01 /etc/passwd 2 yes /usr/sbin/crond -1 150 32. 06/26/2008 22:57:01 /etc/passwd 2 yes /usr/sbin/crond -1 149 33. 06/26/2008 22:57:15 /etc/passwd 2 yes /usr/libexec/gnome-screensaver-gl-helper 500 151 34. 06/26/2008 22:58:01 /etc/passwd 2 yes /usr/sbin/crond -1 152 35. 06/26/2008 22:58:01 /etc/passwd 2 yes /usr/sbin/crond -1 153 36. 06/26/2008 22:58:03 /etc/passwd 2 yes /usr/libexec/gnome-screensaver-dialog 500 154 37. 06/26/2008 22:58:03 /etc/passwd 2 yes /usr/libexec/gnome-screensaver-dialog 500 155 38. 06/26/2008 22:58:03 /etc/passwd 2 yes /usr/libexec/gnome-screensaver-dialog 500 156 39. 06/26/2008 22:58:03 /etc/passwd 2 yes /usr/libexec/gnome-screensaver-dialog 500 157 40. 06/26/2008 22:58:03 /etc/passwd 2 yes /lib64/dbus-1/dbus-daemon-launch-helper -1 158 41. 06/26/2008 22:58:03 /etc/passwd 2 yes /lib64/dbus-1/dbus-daemon-launch-helper -1 159 42. 06/26/2008 22:58:03 /etc/passwd 2 yes /usr/libexec/gnome-screensaver-dialog 500 160 43. 06/26/2008 22:58:03 /etc/passwd 2 yes /sbin/unix_chkpwd 500 161 44. 06/26/2008 22:58:03 /etc/passwd 2 yes /sbin/unix_chkpwd 500 162 45. 06/26/2008 22:58:03 /etc/shadow 2 yes /sbin/unix_chkpwd 500 163 46. 06/26/2008 22:58:06 /etc/passwd 2 yes /sbin/unix_chkpwd 500 165 47. 06/26/2008 22:58:06 /etc/passwd 2 yes /sbin/unix_chkpwd 500 166 48. 06/26/2008 22:58:06 /etc/shadow 2 yes /sbin/unix_chkpwd 500 167 49. 06/26/2008 22:58:06 /etc/passwd 2 yes /usr/libexec/gnome-screensaver-dialog 500 169 50. 06/26/2008 22:58:06 /etc/passwd 2 yes /sbin/unix_chkpwd 500 170 51. 06/26/2008 22:58:06 /etc/passwd 2 yes /sbin/unix_chkpwd 500 171 52. 06/26/2008 22:58:06 /etc/shadow 2 yes /sbin/unix_chkpwd 500 172
Another interesting auditing tool which you should become familiar with is autrace.
# autrace /usr/bin/less /etc/yum.conf Waiting to execute: /usr/bin/less Cleaning up... Trace complete. You can locate the records with 'ausearch -i -p 2916' # ausearch -i -p 2916 type=SYSCALL msg=audit(06/27/2008 13:28:14.133:26003) : arch=x86_64 syscall=close success=yes exit=0 a0=3 a1=7fff0c7a8db0 a2=1 a3=fffffff3 items=0 ppid=2914 pid=2916 auid=fpm uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=1 comm=autrace exe=/sbin/autrace subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null) ---- type=PATH msg=audit(06/27/2008 13:28:14.133:26004) : item=1 name=(null) inode=1179655 dev=fd:00 mode=file,755 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:ld_so_t:s0 type=PATH msg=audit(06/27/2008 13:28:14.133:26004) : item=0 name=/usr/bin/less inode=2530563 dev=fd:00 mode=file,755 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:bin_t:s0 type=CWD msg=audit(06/27/2008 13:28:14.133:26004) : cwd=/etc/audit type=EXECVE msg=audit(06/27/2008 13:28:14.133:26004) : argc=(null) a0=/usr/bin/less a1=/etc/yum.conf type=SYSCALL msg=audit(06/27/2008 13:28:14.133:26004) : arch=x86_64 syscall=execve success=yes exit=0 a0=7fff0c7a9552 a1=7fff0c7a8ee0 a2=7fff0c7a8ef8 a3=fffffff3 items=2 ppid=2914 pid=2916 auid=fpm uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=1 comm=less exe=/usr/bin/less subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null) ---- type=SYSCALL msg=audit(06/27/2008 13:28:14.133:26005) : arch=x86_64 syscall=brk success=yes exit=38514688 a0=0 a1=401a20 a2=0 a3=64 items=0 ppid=2914 pid=2916 auid=fpm uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=1 comm=less exe=/usr/bin/less subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null) ---- type=SYSCALL msg=audit(06/27/2008 13:28:14.133:26006) : arch=x86_64 syscall=mmap success=yes exit=-1193029632(Unknown error 1193029632) a0=0 a1=1000 a2=3 a3=22 items=0 ppid=2914 pid=2916 auid=fpm uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=1 comm=less exe=/usr/bin/less subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null) ---- # Note to readers. I removed many of the entries to reduce size of post. type=SYSCALL msg=audit(06/27/2008 13:28:21.435:26426) : arch=x86_64 syscall=read success=yes exit=1 a0=3 a1=7fffaab81edf a2=1 a3=0 items=0 ppid=2914 pid=2916 auid=fpm uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=1 comm=less exe=/usr/bin/less subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null) ---- type=SYSCALL msg=audit(06/27/2008 13:28:23.651:26427) : arch=x86_64 syscall=close success=yes exit=0 a0=4 a1=24c0720 a2=0 a3=623180 items=0 ppid=2914 pid=2916 auid=fpm uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=1 comm=less exe=/usr/bin/less subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null) #
Well, that is about all there is to auditing. As you can see it is a very powerful mechanism for tracing events on a GNU/Linux system. The only major limitation that I can see is the fact that it cannot log individual shell commands. That can only be handled by adding auditing capabilities to individual shells. ksh93 already has good auditing capabilities but unfortunately bash has no such capabilities.