Monitoring Permission Denials in Linux: Where to Find File Access Rejection Logs


5 views

By default, standard Unix/Linux file permission denials (where users attempt to access files without proper rwx permissions) don't generate explicit log entries. The kernel simply returns EACCES (Error: Access denied) to the calling process without writing to system logs.

To track these events, you'll need to implement one of these solutions:

1. Using auditd (Linux Audit Framework)

The most robust solution is to configure the Linux audit subsystem:


# Install auditd if not present
sudo apt install auditd  # Debian/Ubuntu
sudo yum install audit   # RHEL/CentOS

# Add a watch rule for a specific directory
sudo auditctl -w /path/to/watch -p rwxa -k permission_denials

# Or monitor all filesystem access attempts
sudo auditctl -a exit,always -F arch=b64 -S open,openat,truncate,ftruncate \
  -F exit=-EACCES -k permission_denied

View the logs with:


sudo ausearch -k permission_denied -i

2. Custom syslog Solution with fanotify

For more granular control, you can create a custom monitoring tool:


#include <sys/fanotify.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    int fd = fanotify_init(FAN_CLASS_NOTIF, O_RDONLY);
    fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_MOUNT,
                  FAN_OPEN_PERM, AT_FDCWD, "/");
                  
    while (1) {
        struct fanotify_event_metadata *event;
        char buf[4096];
        ssize_t len = read(fd, buf, sizeof(buf));
        
        for (event = (void *)buf; FAN_EVENT_OK(event, len); 
             event = FAN_EVENT_NEXT(event, len)) {
            if (event->mask & FAN_OPEN_PERM) {
                printf("Access attempt by PID %d\n", event->pid);
                // Add your logging logic here
            }
        }
    }
}

When implementing permission denial logging:

  • Be mindful of performance impact when monitoring entire filesystems
  • Consider log rotation policies to prevent log files from growing too large
  • Filter for specific users/groups if you only need to monitor certain accounts
  • Combine with SELinux/AppArmor logs for comprehensive access control auditing

For advanced users, SystemTap can provide deeper visibility:


probe syscall.open.return {
    if ($return == -13) {  # EACCES
        printf("%s[%d] denied access to %s\n", execname(), pid(), user_string($filename))
    }
}

When users or processes attempt to access files without proper permissions, these events typically don't generate automatic system logs by default. Unlike SELinux denials which are prominently logged in /var/log/audit/audit.log, regular Unix file permission denials require explicit configuration to be recorded.

Here are several approaches to track permission-related access denials:

1. Auditd Framework (Recommended)

sudo auditctl -w /path/to/directory -p rwa -k file_access_denied

This configures the audit subsystem to watch a directory for read (r), write (w), and attribute changes (a). Failed attempts will appear in /var/log/audit/audit.log with "denied" in the message.

2. Syslog Configuration

Add this line to /etc/syslog.conf:

auth.*;authpriv.* /var/log/permission_denials.log

3. Inotify Tools (For Real-time Monitoring)

inotifywait -m -r --format '%w %f %e' -e access_denied /path/to/monitor

A typical denied access entry looks like:

type=SYSCALL msg=audit(1625097600.123:456): arch=c000003e syscall=2 
success=no exit=-13 a0=7ffd12345678 a1=0 a2=1 a3=7ffd12345678 items=1 
ppid=1234 pid=5678 auid=4294967295 uid=1001 gid=1001 euid=1001 suid=1001 
fsuid=1001 egid=1001 sgid=1001 fsgid=1001 tty=pts0 comm="cat" 
exe="/usr/bin/cat" key="file_access_denied"

This Bash script monitors permission denials in real-time:

#!/bin/bash
LOG_FILE="/var/log/permission_denials.log"
tail -Fn0 $LOG_FILE | while read line ; do
    if echo "$line" | grep -q "permission denied"; then
        echo "$(date) - Permission denied detected: $line" >> /var/log/permission_monitor.log
        # Add custom actions like email alerts here
    fi
done

For developers needing deeper visibility, consider using eBPF to trace permission checks:

sudo bpftrace -e 'kprobe:generic_permission {
    if (arg2 & MAY_READ) {
        printf("PID %d tried to read inode %d\n", pid, arg0->i_ino);
    }
}'
  • Audit logs can grow quickly - implement log rotation
  • Be mindful of privacy regulations when monitoring user activity
  • Test configurations in staging before production deployment
  • Combine with process accounting (pacct) for complete audit trails