Troubleshooting a WordPress .htaccess File That Keeps Getting Overwritten Using Linux Auditd
While troubleshooting my WordPress installation running on Ubuntu and Apache, I encountered a rather annoying issue: the .htaccess file in the WordPress document root was repeatedly overwritten and occasionally ended up completely empty.
My first thought was: What the hell? Has my WordPress blog been hacked?
Especially since a PHP security vulnerability had recently made the headlines, the timing wasn’t exactly reassuring. Fortunately, my PHP installation was already updated, but that didn’t immediately explain what was happening.
Whenever this happened, WordPress permalinks stopped working because the Apache rewrite rules were missing.
Restoring the file from a backup fixed the issue temporarily, but the problem kept returning. The interesting question was: Which process was modifying the file?
Monitoring the .htaccess File Using Linux Auditd
To identify the responsible process, we can install and enable the Linux Audit Framework (auditd).
apt update apt install auditd audispd-plugins systemctl enable --now auditd
Next, we need to configure audit rules to monitor modifications to the WordPress .htaccess file and its parent directory.
auditctl -w /var/www/blog/html/.htaccess -p wa -k htaccess_changes auditctl -w /var/www/blog/html -p wa -k wordpress_directory_changes
The -p wa parameter monitors write operations (w) and attribute changes (a), while -k assigns a searchable key to the audit events.
These rules take effect immediately but are not persistent across reboots.
Identifying the Process Modifying .htaccess
To examine the recorded events, we can use:
ausearch -k htaccess_changes -i
To focus on operations that opened the file for truncation:
ausearch -k htaccess_changes -ts recent -i | grep 'O_TRUNC'
The audit logs revealed repeated events similar to the following:
type=SYSCALL msg=audit(10/31/2026 13:53:00.597:47209) syscall=openat success=yes a2=O_WRONLY|O_CREAT|O_TRUNC pid=416960 uid=www-data comm=apache2 exe=/usr/sbin/apache2 key=htaccess_changes
The important fields are:
comm=apache2andexe=/usr/sbin/apache2: The operation was performed by an Apache worker process.uid=www-data: The process was running under the Apache service account.O_WRONLY|O_CREAT|O_TRUNC: The file was opened for writing, with its existing contents truncated.success=yes: The operation succeeded.
This explained why the file could temporarily become empty. Multiple Apache worker processes were repeatedly opening it with truncation enabled.
However, Apache itself was not necessarily the root cause. Since WordPress PHP code runs within Apache worker processes in this installation, a WordPress plugin could have triggered these operations.
Investigating WordPress Plugins
Further investigation identified plugins containing code capable of modifying .htaccess, including LiteSpeed Cache and ThirstyAffiliates.
Both plugins were no longer needed, so I deactivated and removed them.
Afterward, the .htaccess file contained only the remaining WordPress rewrite rules and custom PHP settings, with its size reduced from approximately 3.4 KB to 746 bytes.
I checked its modification timestamp:
stat -c 'Size: %s bytes | Modified: %y' /var/www/blog/html/.htaccess
And searched for further truncation operations after the last recorded modification:
The command returned:
<no matches>
ausearch -k htaccess_changes -ts 13:53:01 -i | grep 'O_TRUNC'

The file also remained unchanged during subsequent checks.
Although this strongly suggested that one of the removed plugins had been responsible for the repeated rewrites, the investigation did not conclusively establish which one.
Conclusion
Linux auditd proved extremely useful for troubleshooting an application-level issue that initially appeared to be an Apache or WordPress configuration problem.
By monitoring file operations at the operating system level, I could identify the responsible process, its user account, and the exact system call used to modify .htaccess.
After removing two unnecessary WordPress plugins, the repeated file modifications stopped during the observation period.
The audit rules were left enabled temporarily to monitor for any recurrence.
Links
Linux Audit architecture, configuration, rules, and event logging
https://github.com/linux-audit/audit-userspaceConfiguring audit rules and monitoring file operations.
https://github.com/linux-audit/audit-userspace/blob/master/docs/auditctl.8Searching and filtering recorded audit events
https://github.com/linux-audit/audit-userspace/blob/master/docs/ausearch.8Apache HTTPD / .htaccess
https://developer.wordpress.org/advanced-administration/server/web-server/httpd
