Security plugin for WordPress with support for fail2ban. Tested through WordPress 7.1.x, with PHP 7.4-8.4 compatibility checks.
- WordPress security controls with optional fail2ban and Cloudflare integration.
- fail2ban is optional.
- WordPress.org: Fail2WP.
- Plugin slug:
fail2wp.
Security features:
-
Disabling login with username (require e-mail address)
-
Preventing user enumeration (?author=nnn)
-
Less detailed error messages on login failures
-
Minimum username length
-
Blocking specific usernames from being used to register new users
-
Requiring e-mail address matching for new user registrations
-
Warning about new user role setting
-
Blocking of portions or all of WordPress REST API
-
Disabling of RSS and Atom feeds
-
Removal of "Generator" information from HTML and feeds
-
Detection of Cloudflare IP addresses for logging of actual IP addresses
-
Blocking/Allowing logins from IP addresses, IP ranges, and/or hostnames
-
Partially or fully disable XMLRPC access
-
Monitoring administrator accounts for unexpected role/account changes
-
fail2ban can dynamically block IP addresses after suspicious activity.
- Requires WordPress 6.2+ and PHP 7.4+.
- PHP compatibility checks: 7.4, 8.1, 8.2, 8.3, and 8.4.
- Uses
mb_PHP functions when available. - May write to the PHP error log when logging is enabled.
- Contains no JavaScript or tracking code.
- Optional IP blocking stores IP addresses and security-event timestamps. Administrator monitoring stores administrator IDs and login names.
- Available since
1.4.0. - Setting:
FAIL2WP_TRUSTED_PROXIESinwp-config.php, beforewp-settings.phploads. - Value: array of proxy IPv4/IPv6 addresses or CIDRs.
define( 'FAIL2WP_TRUSTED_PROXIES', [ '192.0.2.10', '2001:db8:1234::/48' ] );- Replace the examples with your actual proxy addresses.
- List directly connected proxy peers, identified by
REMOTE_ADDR. - Hostnames and wildcards: unsupported for this constant.
- Undefined or empty array:
X-Real-IPignored. - Accepted header: one valid IP from a listed proxy.
- Missing or invalid header: peer address used.
- Proxy requirement: overwrite client-supplied
X-Real-IP. - Multiple proxy hops: final proxy supplies the verified visitor IP.
X-Forwarded-Forand address chains: unsupported.- Proxy trust does not bypass login restrictions or IP bans.
- Scope: entire WordPress installation; excluded from settings exports.
- Server already supplies a verified
REMOTE_ADDR: usually no constant needed. - Cloudflare: enabled setting, matching source range, valid
CF-Connecting-IP; takes precedence. - Upgrade: configure trusted proxies before updating an existing
X-Real-IPdeployment. - Verify client addresses and login access on staging.
- Login/bypass hostname wildcards: separate feature; forward-confirmed reverse DNS required.
- Upload the
fail2wpfolder to/wp-content/plugins/, or install Fail2WP from the WordPress Plugins menu. - Activate Fail2WP from the Plugins menu.
- Configure the basic settings.
- For fail2ban integration, follow
FAIL2BAN.txtorFAIL2BAN.md.
-
Uses WordPress localization functions.
-
Default language: English.
-
Swedish translation by the author.
-
System log entries, including
php.logandauth.log, are in English.
- No known incompatibilities.
- Copy
fail2wp.confto/etc/fail2ban/filter.d. - Add a jail to
/etc/fail2ban/jail.localas shown infail2wp.conf. - In Fail2WP settings, enable logging for unsuccessful logins and any other triggers you need.
- Restart fail2ban.
- Fixed client-IP spoofing through X-Real-IP.
- Added FAIL2WP_TRUSTED_PROXIES for proxy IPs and CIDRs.
- Enforced Login IP rules before login processing.
- Extended REST blocks to child routes, trailing slashes, and case variants.
- Preserved REST discovery for authenticated and bypassed clients.
- Required forward-confirmed reverse DNS for hostname wildcards.
- Fixed hostname results on the first DNS lookup.
- Removed control characters from security log records.
- Restricted imports to registered settings; validated imported values.
- Escaped ignored import names.
- Fixed Cloudflare enablement and DNS-cache exports.
- Connected Login IP deny events to local ban accounting.
- Updated compatibility metadata for WordPress 7.1.
- Added security and WordPress regression checks.
- Documented fail2ban 1.0.x use with Fail2WP 1.3.0.
- Added explicit validation for checkbox values and role selections.
- Retained previous settings on invalid input; added validation notices.
- Preserved JSON settings during repeated sanitization.
- Removed duplicate translation calls from role renderers.
- Raised the minimum WordPress version to 6.2.
- Prepared IP-blocking table names with identifier placeholders.
- Rejected malformed settings exports before import.
- Escaped disabled-feed text and links; validated XML-RPC charset output.
- Removed a duplicate import nonce field.
- Added optional built-in IP blocking with configurable threshold, observation window, and ban duration
- Added exact-IP sitewide
403enforcement, cache-suppression headers, a self-contained block page, and Cloudflare client-IP handling - Added wp-admin active-ban management, exact-IP bypass entries, and import/export support for feature configuration and validated active-ban snapshots
- Added manual exact-IP ban creation and expanded trusted bypass entries to support IPs, CIDR ranges, hostnames, and hostname wildcards
- Added administrator baseline monitoring, immediate hook checks, hourly reconciliation, and syslog alerts
- Added a missing-object-cache notice; uncached ban checks use the database
- Fixed false REST block logs when REST blocking was disabled
- Fixed false REST namespace blocks with user-enumeration handling active
- Made blocked REST logs respect the
Log blocked requestssetting - Verified with WordPress 6.9
- Updated internal version metadata
- Added Cloudflare IPv4/IPv6 range refresh in wp-admin; changes require Save Changes
- Muted disabled Cloudflare range controls; editing and refresh remain available
- Changed disabled feed requests to return
404instead of redirecting to the home page - Extended user enumeration blocking/logging to cover unauthenticated REST users endpoints
- Fixed the REST
usersroute block so it also covers individual user endpoints - Fixed REST route blocking so route-only rules are activated correctly
- Fixed REST handling so logged in and authenticated requests bypass REST blocking
- Fixed override IP handling for security/fail2ban alert messages
- Fixed IPv6 CIDR validation for login allow and deny lists
- Removed PHP 8.2 and PHP 8.3 dynamic property deprecations
- Fixed PHP 8.4 syslog signature deprecation while keeping PHP 7.4 compatibility
- Refreshed the bundled
php-cidr-matchlibrary from current upstream - Updated translation assets, including the Cloudflare refresh flow and Swedish admin strings
- Updated internal version metadata
- Verified with WordPress 6.8 and WordPress 6.9
- Removed PHP 7.2 compatibility (PHP 7.4 or above is now required)
- Verified with WordPress 6.7
- Verified with Plugin Check (PCP)
- Fixed issue when requiring REST API authentication and IPv4/IPv6 bypass was configured
- Fixed issue with uninitialized variable in XML-RPC handling
- Fixed a json_decode() warning without changing behavior
- Corrected some Swedish translations
- Corrected some checks for
uninstall.phpand made it more WP-CLI compatible
- Verified with WordPress 6.6
- Improved code for role notification settings, PR#2
- Improved code for e-mail checking for new user registrations PR#1
- Thanks to philscott-rg and Edward Casbon
- Verified with WordPress 6.5.2
- Updated "About" information
- Verified with WordPress 6.2.2 and PHP 8.1.20
- Added support for allow/deny list for login (IP address, hostname with wildcard support)
- Added entry in
fail2wp.confexample fail2ban configuration for allow/deny login - Corrected typo in
fail2wp.confexample fail2ban configuration, CHECK AGAINST YOURS! - Added support for HTTP_X_REAL_IP (X-Real-IP) header to "decode" actual remote IP address
- Added support for partially or fully disabling XMLRPC
- Added entry in
fail2wp.confexample fail2ban configuration for XMLRPC access attempts
- Verified for WordPress 5.8
- Added minimum username length
- Added blocking of specific usernames (user registration)
- Added requiring e-mail address matching setting
- Added warning about new user role setting
- Added blocking of portions or all of WordPress REST API
- Added setting to disable RSS and Atom feeds
- Added setting to remove "Generator" information from HTML and feeds
- Minor corrections and general improvements
- Initial release
- Requires WordPress 6.2+.
- Before upgrading: set FAIL2WP_TRUSTED_PROXIES or supply a verified REMOTE_ADDR.
- Proxies must overwrite client-supplied X-Real-IP.
- Hostname wildcards require forward-confirmed reverse DNS.
- Add trusted administrative IP addresses to the IP-blocking bypass list before enabling enforcement.
- Install the new version.
- Install the new version.
- Install the new version, no changes have been made to settings.
- Install the new version and walk through the settings.
- Check your fail2ban configuration against the supplied sample
fail2wp.conf!
- Install the new version, no changes have been made to settings.
- Install the new version and walk through the settings.
- Initial release
Please see LICENSE for a full copy of GPLv2
Copyright (C) 2020-2026 Joaquim Homrighausen; all rights reserved.
This file is part of Fail2WP. Fail2WP is free software.
You may redistribute it and/or modify it under the terms of the GNU General Public License version 2, as published by the Free Software Foundation.
Fail2WP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with the Fail2WP package. If not, write to:
The Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA.
The Fail2WP WordPress Plugin was written by Joaquim Homrighausen while converting β into code.
Fail2WP is sponsored by WebbPlatsen i Sverige AB πΈπͺ
Commercial support and customizations for this plugin is available from WebbPlatsen i Sverige AB in πΈπͺ
If you find this plugin useful, the author is happy to receive a donation, good review, or just a kind word.
If there is something you feel to be missing from this plugin, or if you have found a problem with the code or a feature, please do not hesitate to reach out to support@webbplatsen.se.
This plugin can also be downloaded from code.webbplatsen.net and WordPress.org
More detailed documentation is available at code.webbplatsen.net/documentation/fail2wp/
Kudos to Vincent Le Moign and Webalys and Thomas Lutz
These links are not here for any sort of endorsement or marketing, they're purely for informational purposes.
- me; π https://joho.se and https://code.joho.se
- WebbPlatsen; https://webbplatsen.se and https://code.webbplatsen.net