Hello,
didn't we have this discussion already a couple of months ago? :-(
Anyway, I'll first try to summarize what the CAPP requirements regarding
file audit are. More specific comments are embedded below.
Fundamentally, files need to be auditable for one of two reasons:
- the content is confidential, these are the authentication secrets
(/etc/shadow) and the audit log files.
- the content integrity is important, these are configuration files that
affect the operation of trusted programs. This for example includes:
/etc/passwd
/etc/shadow
/etc/audit.rules
/etc/ssh/sshd_config
...
Note that /etc/shadow requires both confidentiality and integrity due to
its dual role.
CAPP doesn't phrase things in exactly these terms since it's more
abstract and not specifically tied to a file system. The specific CAPP
auditable event requirements are in section 5.1, specifically Table 1,
and include:
5.1.3 FAU_SAR.1 "Reading of information from the audit records"
5.1.4 FAU_SAR.2 "Unsuccessful attempts to read information from
the audit records"
[ These are both about confidentiality ]
5.1.6 FAU_SEL.1 "All modifications to the audit configuration
that occur while the audit collection functions are operating"
[ Integrity ]
5.2.2 FDP_ACF.1 "All requests to perform an operation on an
object covered by the SFP"
[ This is the abstract general requirement concerning any type of
operation on anything the security target defines to be an
"object", these are filesystem objects and IPC objects in this
case. The audit log must contain "the identity of the object",
device/inode pairs would do here, but having pathnames in
addition is clearly useful to tell where the object actually is.
]
5.4.1 FMT_MSA.1 "All modifications of the values of security
attributes"
( also 5.4.{2,3,4,5,6,7,8,9} which are similar )
[ A file corresponds to a security attribute based on its path
name since that's what the trusted apps refer to, not its
device/inode identity. This is where the watch lists are needed. ]
In general, whenever a file is confidential, device/inode based audit is
appropriate, since that directly corresponds to the file content, and you
want access to the content to remain audited even when the file is
renamed. That is already addressed by the device/inode based audit rules
implemented in LAF.
If the file integrity is required, path name based audit is appropriate.
Nobody cares if somebody makes a copy of /etc/passwd and modifies the
copy. But if someone creates a new version of such a file that is based
on a different inode, you need to audit access to the new inode. That's
the problem that the watch list based approach solves. You need to be
able to reliably audit access to whichever file a certain path name
refers to. This is fundamentally related to directory entries and their
pointers to other inodes, not the individual file inodes themselves.
Hard links confuse the issue a bit, mainly due to the annoying semantics
that permit creating a hard link to a file (inode) that you don't have
read/write/execute permissions for.
The desired behavior with respect to hard links is different for the two
auditability requirements.
When the integrity is important, you want access to a hard link audited
as long as the link is pointing to the same file. When the link is broken
(i.e. due to the original name being removed), you don't care anymore
about access to the link. You do want audit to start for a new file being
created at the old location.
When confidentiality is important, you want a hard link to remain
audited, even after the link to the original location is broken.
We had originally considered supporting persistently stored audit flags
(using an extended attribute) for confidential data, but had decided
against it since this would only be needed for /etc/shadow and the audit
logs in the CAPP configuration. Instead, the evaluated configuration
guide contains the requirement that the file systems containing
/etc/shadow and the audit logs do not contain any directories writable by
untrusted users, this way there is no way for them to create hard links
to those files in the first place.
Auditing of access to confidential data beyond the very basic CAPP
requirements would probably be better solved by a different mechanism
such as SELinux policies for people who need that, but this goes beyond
CAPP.
Embedded comments below...
On Thu, Apr 28, 2005 at 03:03:52PM -0400, Stephen Smalley wrote:
On Tue, 2005-04-26 at 10:38 -0500, Loulwa F Salem wrote:
> Test 2 : Create a watched file (file created after watch is inserted)
> Expected: 1 watch records for open() with regards to
> file creation
Only makes sense for the name-based watches. I think that the closest
equivalent for inode-based syscall filter would be to monitor file
creation syscalls on the parent directory.
In the previous discussion, I thought we had reached a consensus that
monitoring access to the parent directory on a per-syscall level was too
low level to provide a useful audit trail?
> Test 3 : Create hard link to a watched file and then access it
by
> opening it for read
> Expected: 1 watch record for open() on original file
This also generates a record for the link(2) call on the watched file.
That's what I would expect, but you didn't list it above.
Loulwa's list wasn't intended to be exhaustive, it just showed specific
audit events that the test cases are looking for, with the goal of
providing sufficient information to verify if the audit trail is
sufficiently complete. There are certainly other combinations of audit
events which would meet the requirements.
Note that an inode-based syscall filter would yield the same result
for
this particular test, but the inode-based filter would persist across
reboots (if loaded by auditd on each boot) unlike the watch (which was
only on the original file path, unless you explicitly add the new link
name to the watch list). Hence, watch-based auditing differs from
inode-based filtering in its persistence of tracking of hard links.
Rebooting is not a problem, you would configure the audit system to
add both an inode based audit rule and a watch list for /etc/shadow since
it needs audit for both confidentiality and integrity. That way access to
the link would still be audited after the reboot.
And actually, the watch-based auditing of access via the hard link
would also cease if the incore inode is evicted under memory pressure
and then brought incore again later via the link name, right? So how
do you explain to users that the watch _may_ be triggered by subsequent
accesses via the hard link (until reboot) but can be lost at any time
due to memory pressure? Is that the behaviour you want?
No, that's not the desired behavior, and I had expected that the audit
information would be locked in memory to prevent this. It could be worked
around by creating both inode based rules and watch lists for trusted
databases.
> Test 5 : Create hard link to watched file, delete watched file,
then
> access hard link by opening it for read
> Expected: No watch record
This will also generate records for the link(2) call and the unlink(2)
call (and if using rm to delete, it will also generate one for access(2)
to check file existence and permissions prior to unlinking). Note that
an inode-based syscall filter would generate an audit record upon the
access to the hard link since the inode is unchanged. Which behavior
will most users want?
It is the expected behavior for files where the admin is interested in
integrity but not confidentiality.
I would suggest changing the test case to use "write" instead of
"read"
since that would be the interesting access pattern in that case. You
normally won't be auditing read access to /etc/hosts or similar files.
> Test 11 : copy a file to a watched name (copy in) - access
through new
> name
> Expected: 1 record for file creation in new name
> Expected: 1 record for new file access/open
Distinctive to the watch-based approach; inode-based syscall filter
could catch the file creation on the parent directory, but would require
some kind of userspace assist to set up the filter on the new file.
The point of the watch list based approach was to avoid the need for
invasive (and potentially fragile) userspace modifications.
> Test 12 : Move a watched file out of a watched location and
access by
> opening it for read
> Expected: 1 watch record for rename() with regards to
> moving out of a watched location.
> Expected: No watch record for new file open()
An inode-based syscall filter would continue auditing on the file. What
will the users want?
See above, and this test should also use "write" since it's about
integrity audit.
What concerns me is unclear/unstable semantics and a lack of a clear
subdivision between this mechanism and the inode-based syscall filters:
- Auditing may or may not be preserved on hard links when using the
watches depending on memory pressure, reboots, or whether the watched
name is unlinked; is always preserved for inode-based watches.
The point is that you want different behavior depending on the goal of
the audit rule, and I agree that it needs to be obvious what the
semantics of the audit rules are.
Note that nobody is proposing getting rid of the inode based audit rules,
you'll need both to meet CAPP requirements. The device/inode pair based
rules are fine to meet the FDP_ACF.1 audit requirements, but they are not
sufficient to properly handle access to trusted databases.
Serge has suggested some more abstract user-space tool to make this less
confusing, something like:
auditfs add secrecy /etc/shadow (watch the inode)
auditfs add integrity /etc/shadow (watch the pathname)
and the combination of both would also preserve the secrecy of newly
created, renamed, or linked /etc/shadow files.
If someone has a different way to solve the integrity/pathname-based
audit problem (preferably without needing invasive changes to userspace
tools), please share that information.
-Klaus