Enable Wordfence Extended Protection

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

  1. Sign in to the WordPress administration dashboard.
  2. Open Wordfence → Firewall.
  3. Open the firewall options or manage-firewall page.
  4. Click Optimize the Wordfence Firewall.
  5. Select the Apache and mod_php configuration detected by Wordfence.
  6. 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.php while auto_prepend_file still 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 .htaccess until 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.