I've written before on noise reduction in the Windows security event log. I've also written to describe how object access auditing works. But, I still get questions on how to reduce noise from object access events. The other day I got that question, specific to Directory Service objects, on an internal discussion list so I thought I'd clean up the answer a bit and share it with the world. In general the same is true for any type of object, although there are a few more knobs to control for DS objects.
Object access audit is generated when the system access control list (SACL) on the object matches the access that was performed on ALL of the following conditions:
- Object - the object that was accessed must have either an explicit or inherited SACL. The access performed is compared against the ACEs in that SACL.
- Success or failure of activity - every audit access control entry (ACE) in a SACL will be either of type AUDIT_SUCCESS or AUDIT_FAILURE. The access performed must match the access type of the ACE for the rest of the ACE to be considered.
- User account - the accessing user's token is compared against each ACE matching the access type. If the user, or a group the user belongs to, matches the SID in the ACE, then an audit might be generated.
- Access - the access being performed must match the audited accesses in the access mask in an otherwise matching ACE.
The specific auditing algorithm is discussed here.
So the way to reduce the number of audit events (566 on Windows Server 2003, 4662 on Windows Server 2008, or one of the new DS Change events on Windows Server 2008) is to cause one or more of those conditions to fail, except in the specific cases that you care about.
The SACL which will generate the most audit events is "Everyone:Success & Failure:All accesses" on the domain head with OI,CI (object inherit & container inherit flags) for all object types. This SACL matches all of the above conditions in all cases. (Incidentally I think that this is pretty close to the default SACL- with the exception of failures- for Windows 2000 Active Directory installations, and SACLs are not updated when DCs are upgraded from version to version. Windows Server 2003 has much more conservative SACLs for new installations of AD.)
To reduce noise, I offer the following suggestions, addressing each of the above conditions:
- Audit only the objects that you care about. User accounts and groups already are well-audited with "Account Management" auditing, so don't audit them with DS access. Perhaps audit OUs, or other DS objects. Use the Object Type and attribute type restrictions that you have in DS Access auditing. Also, in Windows Server 2008, you can affect auditing on a per-object basis by adjusting the SearchFlags attribute in the AD schema for the object. SACLs are more easily reversed so are probably a more acceptable method of controlling audit for most organizations.
- Audit successful accesses only. Failed accesses are common and are NOT indicative of any security problem; in fact many failures are not even explicit requests by the user but are just normal requests made by the OS, and the OS will re-try with less access if the operation fails. In my experience failure auditing is primarily useful for troubleshooting, not for security.
- Audit the "Everyone" group. Although this matches any user, you will not accidentally miss any accesses that you care about due to failing to audit a user account who has access to the objects in question. The only time that you would NOT audit "Everyone" is if you had an application or service account which was very noisy; in that case you'd need to create a group with all accounts EXCEPT the noisy accounts, and audit that group.
- Audit only the accesses that you care about. Specifically, read accesses occur much more often (in my experience, a conservative estimate is about a 100:1 ratio) than write accesses. If you restrict your auditing to "write" type accesses (including change, delete, change permissions, create, etc.) then you will end up generating far fewer events. Auditing for read access is very noisy. If you must audit for reads, consider auditing fewer objects, perhaps only auditing reads on the container object instead of the objects in the container, or on one "interesting" object in any given container as a "canary".