

In this guide you will learn how to install and protect WordPress with the Open Source Web Application Firewall (WAF) ModSecurity. We will also install the latest protection rules from the OWASP Core Rule Set (CRS). A WAF is a great addition to the Cyber Security protection for your WordPress blog or website and can stop many zero-day attacks and known attacks, or as the project describes itself:
The CRS aims to protect web applications from a wide range of attacks, including the OWASP Top Ten, with a minimum of false alerts.
This guide is written for the latest Ubuntu Linux LTS (Long Term Support) which is 20.04.3.
Installing ModSecurity and Core Rule Set
First step is to install modsecurtiy from the package repository:
sudo apt install libapache2-mod-security2
And it will look something like this if the above command is successfull:

sudo a2enmod security2
And also restart the Apache webserver:
sudo systemctl restart apache2
You can also verify that the module is loaded using this command: apache2ctl -M|grep security
Now we need to enable the blocking of Cyber Attacks in the ModSecurity module. This is not enabled by default so we need to change the SecRuleEngine config option:
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
And then edit the file /etc/modsecurity/modsecurity.conf using your favorite editor such as vim, emacs or nano. You need to change the line:
SecRuleEngine DetectionOnly
to
SecRuleEngine On
That’s it regarding Apache and ModSecurity. Now we need to download and enable the latest Core Rule Set:
cd git clone https://github.com/coreruleset/coreruleset.git cd coreruleset sudo mv crs-setup.conf.example /etc/modsecurity/crs-setup.conf sudo mv rules/ /etc/modsecurity/
And it it goes well it would look something like this screenshot:

After this we will enable the rules in the configuration file and remove the old CRS. So the next step is to edit the file /etc/apache2/mods-enabled/security2.conf so it will look like this:

And then as the last step of enabling ModSecurity and the Core Rule Set, restart apache:
sudo systemctl restart apache2
ModSecurity WordPress tweaks
In order to get WordPress to work better with ModSecurity and the OWASP Core Rule Set (CRS) we need to make a few small tweaks. CRS has a variable named tx.crs_exclusions_wordpress and can be enabled depending on the URL of your WordPress installation. Edit the file crs-setup.conf and change the following lines:
# SecRule RESecAction \ #SecAction \ # "id:900130,\ # phase:1,\ # nolog,\ # pass,\ # t:none,\ # setvar:tx.crs_exclusions_cpanel=1,\ # setvar:tx.crs_exclusions_dokuwiki=1,\ # setvar:tx.crs_exclusions_drupal=1,\ # setvar:tx.crs_exclusions_nextcloud=1,\ # setvar:tx.crs_exclusions_phpbb=1,\ # setvar:tx.crs_exclusions_phpmyadmin=1,\ # setvar:tx.crs_exclusions_wordpress=1,\ # setvar:tx.crs_exclusions_xenforo=1"
So it will look like this:
SecAction \ "id:900130,\ phase:1,\ nolog,\ pass,\ t:none,\ setvar:tx.crs_exclusions_wordpress=1 # setvar:tx.crs_exclusions_cpanel=1,\ # setvar:tx.crs_exclusions_dokuwiki=1,\ # setvar:tx.crs_exclusions_drupal=1,\ # setvar:tx.crs_exclusions_nextcloud=1,\ # setvar:tx.crs_exclusions_phpbb=1,\ # setvar:tx.crs_exclusions_phpmyadmin=1,\ # setvar:tx.crs_exclusions_wordpress=1,\ # setvar:tx.crs_exclusions_xenforo=1"
Remember to reload the new rules by issuing a reload to the apache webserver:
sudo service apache2 reload
Important: Always remember to save more just than 14 days of logs. We recommend to save at least one year of logs, and this can be changed in the file: /etc/logrotate.d/apache2 and in this case we are saving weekly and 52 weeks (one year):

Problems and fixes
First problem we will run into is the following error:
Execution error - PCRE limits exceeded (-8)
And this error can be fixed by raising the following configuration option: SecPcreMatchLimit and SecPcreMatchLimitRecursion in the /etc/modsecurity/modsecurity.conf file. Set them to:
SecPcreMatchLimit 1000000
SecPcreMatchLimitRecursion 1000000
And the next error that will show up is when a file is being uploaded:
Access denied with code 403 (phase 2). Match of "eq 0" against "MULTIPART_UNMATCHED_BOUNDARY" required
This can be fixed by commeting out line 86 in the modsecurity.conf file, like this:

Also the following error is displayed in the logfile when the Theme Editor in WordPress is used:
Request body no files data length is larger than the configured limit
Update the file modsecurity.conf and change SecRequestBodyLimit to the value 6000000.
Also we need to whitelist a few IDs. Create the following file:
/etc/apache2/conf-enabled/whitelist.conf
Add the following lines:
<LocationMatch "/wp-admin/theme-editor.php"> SecRuleRemoveById 300015 300016 300017 950907 950005 950006 960008 960011 960904 959006 980130 </LocationMatch> <LocationMatch "/wp-admin/admin-ajax.php"> SecRuleRemoveById 300015 300016 300017 950907 950005 950006 960008 960011 960904 959006 981173 980130 </LocationMatch>
Also remember to always run reload when changing the ModSecurity configuration and rules:
sudo systemctl reload apache2
Thats it! If you find any other error please comment below so we can help each other to make WordPress even more secure.