Fix: Failed to access DBM file when using mod_ruid2 and mod_security

If you are using mod_ruid2 and mod_security on your cpanel server, you may come across a problem if one or more of your mod_security rules use the persistent storage (tracking user IP addresses, etc.). This can be seen in your apache error log file at /var/log/apache2/error_log containing the following lines:

ModSecurity: collection_store: Failed to access DBM file "/var/cpanel/secdatadir/ip": Permission denied

This happens when running apache under mod_ruid2, apache cannot access the ip.pag and ip.dir files located in /var/cpanel/secdatadir/ as the apache process runs as the user and not as nobody.

So far, there’s no proper fix for it, with cpanel saying that the fix has to come from mod_security itself.

Meanwhile to get your rules to work, you can change permissions of the the files, so its writeable by everyone.

# chmod 777 /var/cpanel/secdatadir/ip*

Another problem: Cpanel reverting the above changes

During the daily cpanel update process (upcp), the above files are flushed and regenerated causing the permissions to be reset to the original one. To fix this, you will need to create a cpanel hook that runs right after the daily cpanel update process.

Create a script called resetmodsecperm and store it in the /scripts/ folder.

#!/bin/bash
chmod 777 /var/cpanel/secdatadir/ip.*

Make the script executable

# chmod a+x /scripts/resetmodsecperm

Create a cpanel hook

# /usr/local/cpanel/bin/manage_hooks add script /scripts/resetmodsecperm --manual --category System --event upcp --stage post

What the above does is, you are creating a hook that runs the resetmodsecperm script after (–stage post) the cpanel update process (–event upcp).

So with that done, your mod_sec rules will run properly and not throw errors. I know this is a hacky way and chmodding the files 777 could be risky, but this seems to be the only way to make all mod_sec rules work.

UPDATE: With a recent cPanel update, I have noticed a new script has been added and is made to run every two hours. The script basically shrinks the ip.pag and ip.dir files, but this also reverts the permissions of the files and you get the same error as before.

New entry found in crontab:

0 */2 * * * /usr/local/cpanel/scripts/shrink_modsec_ip_database -x 2>&1

So, in your cron tab, have your script run after the above script.

2 */2 * * * /scripts/resetmodsecperm

This will run your script 2 minutes after every time the ip.pag and ip.dir files are recreated.