How to Enable Wordfence Extended Protection on FreeBSD with Apache and mod_php
Wordfence can run its Web Application Firewall in either Basic Protection or Extended Protection mode.
Extended Protection loads the firewall before WordPress, plugins, and themes are initialized. This allows
malicious requests to be evaluated earlier in the request path and reduces the amount of WordPress and PHP
processing performed for blocked traffic.
This procedure documents the configuration used on a FreeBSD server running Apache 2.4, PHP through
mod_php, and Wordfence Premium.
Environment
- FreeBSD
- Apache 2.4
- PHP 8.2 through
mod_php - WordPress installed at
/usr/local/www/wordpress - Wordfence Premium
- Apache runtime user and group:
www:www
What Extended Protection Changes
In Basic Protection mode, WordPress begins loading before the Wordfence firewall is initialized.
Extended Protection adds an auto_prepend_file directive so that Wordfence loads before
the main WordPress bootstrap.
Internet request
|
Apache
|
Wordfence WAF
|
WordPress
|
Plugins and themes
On Apache with mod_php, Wordfence normally adds a firewall block to the WordPress
.htaccess file and creates a bootstrap file named wordfence-waf.php.
1. Confirm the Apache and PHP Configuration
Verify that Apache is using mod_php:
httpd -M | grep php
Example output:
php_module (shared)
Check the installed PHP version:
php -v
Confirm that Apache maps PHP files to the PHP handler:
grep -i SetHandler /usr/local/etc/apache24/httpd.conf
Typical output:
SetHandler application/x-httpd-php
SetHandler application/x-httpd-php-source
2. Confirm That Apache Allows .htaccess Overrides
The Apache directory configuration for the WordPress document root must permit the directives
Wordfence adds to .htaccess.
Example Apache configuration:
<Directory "/usr/local/www/wordpress/">
AllowOverride All
Options FollowSymLinks
DirectoryIndex index.php
<RequireAll>
Require all granted
<IfModule mod_setenvif.c>
Require not env bad_bot
</IfModule>
</RequireAll>
</Directory>
The important directive is:
AllowOverride All
Test the Apache configuration before continuing:
httpd -t
Expected result:
Syntax OK
3. Check File and Directory Permissions
Wordfence must be able to modify the existing .htaccess file and create or update
wordfence-waf.php.
cd /usr/local/www
ls -ld wordpress
ls -l wordpress/.htaccess
ls -l wordpress/wp-config.php
ls -l wordpress/index.php
In this installation, the WordPress directory was owned by root:wheel and had mode
755. Apache could read the directory but could not create a new file in it:
drwxr-xr-x 5 root wheel ... wordpress
This test confirmed that the Apache user could not create a file in the document root:
su -m www -c "touch /usr/local/www/wordpress/testfile"
Result:
touch: /usr/local/www/wordpress/testfile: Permission denied
This is why WordPress displayed the Filesystem Credentials Required dialog and asked
for FTP credentials.
4. Do Not Enable FTP
FTP is not required when the administrator already has shell access to the server. Enabling FTP solely
for this task would unnecessarily expose another network service.
Instead, pre-create the one file Wordfence needs and temporarily make the specific files writable by
the Apache user.
5. Back Up .htaccess
cd /usr/local/www/wordpress
cp -p .htaccess .htaccess.pre-wordfence
Confirm the backup:
ls -l .htaccess .htaccess.pre-wordfence
6. Temporarily Grant Access to the Required Files
Make the existing .htaccess file writable by Apache:
chown www:www .htaccess
chmod 640 .htaccess
Pre-create the Wordfence bootstrap file:
touch wordfence-waf.php
chown www:www wordfence-waf.php
chmod 640 wordfence-waf.php
Verify the result:
ls -l .htaccess wordfence-waf.php
This is safer than changing ownership or permissions on the entire WordPress directory.
7. Run the Wordfence Optimizer
- Sign in to the WordPress administration dashboard.
- Open Wordfence → Firewall.
- Open the firewall options or manage-firewall page.
- Click Optimize the Wordfence Firewall.
- Select the Apache and
mod_phpconfiguration detected by Wordfence. - Continue with the installation.
With the two files writable, Wordfence should complete the installation without FTP credentials and
display:
Installation Successful
Nice work! The firewall is now optimized.
8. Verify the .htaccess Changes
head -30 /usr/local/www/wordpress/.htaccess
The generated Wordfence section should resemble the following:
# Wordfence WAF
<IfModule mod_php5.c>
php_value auto_prepend_file '/usr/local/www/wordpress/wordfence-waf.php'
</IfModule>
<IfModule mod_php7.c>
php_value auto_prepend_file '/usr/local/www/wordpress/wordfence-waf.php'
</IfModule>
<IfModule mod_php.c>
php_value auto_prepend_file '/usr/local/www/wordpress/wordfence-waf.php'
</IfModule>
<Files ".user.ini">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>
</Files>
The multiple module checks are normal. Only the PHP module actually loaded by Apache will match.
9. Verify wordfence-waf.php
head -20 /usr/local/www/wordpress/wordfence-waf.php
The file should load the Wordfence firewall bootstrap, similar to:
<?php
// Before removing this file, please verify the PHP ini setting
// `auto_prepend_file` does not point to this.
if (file_exists(__DIR__.'/wp-content/plugins/wordfence/waf/bootstrap.php')) {
define("WFWAF_LOG_PATH", __DIR__.'/wp-content/wflogs/');
include_once __DIR__.'/wp-content/plugins/wordfence/waf/bootstrap.php';
}
10. Test Apache
httpd -t
Expected result:
Syntax OK
An Apache restart is normally not required because the change is in .htaccess, but the
website and WordPress administration dashboard should be tested immediately.
11. Restore Restrictive Ownership and Permissions
After Wordfence confirms that Extended Protection is active, return the files to the normal
root-controlled security posture:
cd /usr/local/www/wordpress
chown root:wheel .htaccess wordfence-waf.php
chmod 644 .htaccess wordfence-waf.php
Verify the final permissions:
ls -l .htaccess wordfence-waf.php
12. Confirm the Wordfence Status
Return to:
Wordfence → Firewall → Firewall Options
Confirm the following:
- Web Application Firewall: 100%
- Web Application Firewall Status: Enabled and Protecting
- Protection Level: Extended Protection
- Firewall Rules: Premium
- Real-Time IP Blocklist: Enabled
- Brute Force Protection: Enabled
Final Configuration
The completed installation causes Apache to load:
/usr/local/www/wordpress/wordfence-waf.php
before normal WordPress processing. The firewall can therefore inspect PHP requests before WordPress
core, plugins, or themes begin running.
Operational Notes
- Do not remove
wordfence-waf.phpwhileauto_prepend_filestill points to it. - Do not enable FTP solely for the Wordfence optimizer.
- Do not make the entire WordPress document root writable by Apache.
- Keep the pre-optimization copy of
.htaccessuntil the site has been fully tested. - Run a complete Wordfence scan after enabling Extended Protection.
- Test the front page, administrative dashboard, forms, scheduled tasks, and any e-commerce functions.
Rollback Procedure
Wordfence provides a Remove Extended Protection button in the firewall options.
If a manual rollback is required, first disable or remove Extended Protection from Wordfence, then
verify that no PHP auto_prepend_file setting points to wordfence-waf.php.
The original .htaccess can then be restored:
cd /usr/local/www/wordpress
cp -p .htaccess.pre-wordfence .htaccess
httpd -t
Do not delete wordfence-waf.php until the preload directive has been removed.