How to Audit SELinux Denials in Linux using the ausearch Command

The Enforcer of Mandatory Access Control

SELinux (Security-Enhanced Linux) is a mandatory access control (MAC) architecture heavily utilized in enterprise distributions like Red Hat (RHEL), CentOS, and Fedora. Unlike standard Linux file permissions (where a user can read a file if they have r permissions), SELinux utilizes complex cryptographic contexts. If the Apache web server daemon (running in the httpd_t context) attempts to read a database file (labeled with the mysqld_db_t context), SELinux will violently block the action, even if the Apache user mathematically has full 777 read/write permissions to that file on the hard drive.

When this happens, the application crashes, and standard error logs (like /var/log/messages or /var/log/apache2/error.log) often provide completely useless information, leading junior administrators to incorrectly assume the application itself is broken.

To determine if SELinux is actively assassinating your processes, you must query the central audit daemon using the ausearch command.

The Audit Log

Every time SELinux blocks an action, it writes an entry (a denial) to the central audit log located at /var/log/audit/audit.log. While you can open this massive text file with grep or cat, the raw logs are incredibly dense and difficult to read.

The ausearch utility is specifically designed to parse this database efficiently.

Searching for SELinux Denials (AVC)

In SELinux terminology, a denial is referred to as an AVC (Access Vector Cache) message.

To search the entire audit log specifically for SELinux denials, you must run ausearch with root privileges and specify the message type (-m AVC):

sudo ausearch -m AVC

This command will dump every historical denial to your screen. However, you are likely only interested in what happened in the last 10 minutes when your web server crashed.

Filtering by Time

You can dramatically narrow the search scope using the -ts (time start) flag. You can use absolute dates, or convenient relative keywords like recent (which defaults to the last 10 minutes) or today.

sudo ausearch -m AVC -ts recent

This will isolate the exact event that just caused your application to fail.

Interpreting the Output

A typical ausearch result will look somewhat like this:

time->Mon Aug 24 14:30:00 2026
type=AVC msg=audit(1692887400.123:456): avc:  denied  { read } for  pid=1234 comm="httpd" name="config.ini" dev="sda1" ino=987654 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0

This output tells you the entire story:

  • comm=”httpd”: The Apache web server was the program that attempted the action.
  • { read }: It attempted to read a file.
  • name=”config.ini”: It was trying to read a specific configuration file.
  • scontext (Source Context): The web server was operating inside the httpd_t security box.
  • tcontext (Target Context): The file it tried to read was labeled as user_home_t (a file located inside a standard user’s home directory).

SELinux correctly identified that a web server has no business reading personal files inside a user’s home directory and blocked the action.

Taking Action

Once ausearch reveals the specific denial, you know exactly how to fix the problem. You do not need to disable SELinux. Instead, you simply use the chcon or semanage fcontext commands to relabel the config.ini file with the correct httpd_sys_content_t context, allowing the web server to read it securely.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.