The safest way to limit WordPress logins by IP address is to enforce an allowlist at the web-server, reverse-proxy, WAF, or hosting layer and scope it to /wp-login.php. Add the stable public IP addresses (or supported CIDR ranges) used by administrators, deny everything else, and test from both an allowed and a blocked connection before enabling the rule on production. A rule on /wp-admin/ alone does not cover every login request: logged-out requests to that directory normally redirect to the root-level /wp-login.php.
What the restriction should cover
WordPress presents its browser login form at /wp-login.php. A visitor who requests /wp-admin/ while logged out is redirected to that script, so protect the login script explicitly. Decide separately whether you also need restrictions on administrative paths after authentication.
- Login form: restrict
/wp-login.phpat minimum. - Administrative area: consider additional controls for
/wp-admin/, but validate dashboard navigation, AJAX requests, uploads, and other workflows before restricting the whole directory. - XML-RPC: evaluate
/xmlrpc.phpseparately. It can accept authentication-related requests even when the browser login form is protected.
Before enabling an IP allowlist
- Identify the web server or edge service you can actually configure: Apache, Nginx, Caddy, IIS, a managed WAF, CDN, or hosting control panel.
- Record the public address the server sees, not a private LAN address such as
192.168.x.x. If your ISP changes your address, a fixed allowlist can eventually lock you out. - If a CDN or reverse proxy is in front of WordPress, establish how it passes the client address. Trust only a client-IP header supplied by a trusted proxy; accepting arbitrary forwarded headers lets an attacker spoof an allowed address.
- Keep an out-of-band recovery route, such as a hosting console or support procedure, before adding a deny-all rule.
- Use staging first. WordPress’s official brute-force guidance warns that server and proxy examples vary by environment and should be tested before production deployment.
Apache 2.4: allow selected addresses for the login script
Apache 2.4 uses authorization requirements such as Require ip. WordPress documents an allow-list pattern with RequireAny; this means any one listed address is sufficient. Replace the documentation addresses below with your own stable public addresses or an appropriate CIDR range.
<Files "wp-login.php">
<RequireAny>
Require ip 192.0.2.123
Require ip 2001:0DB8:1111:2222:3333:4444:5555:6666
</RequireAny>
</Files>
Put the rule where your host permits it, such as the virtual-host configuration or an allowed .htaccess context. Ask the host which directives are enabled; many managed plans do not permit arbitrary authorization changes. Do not use RequireAll for this allowlist pattern, because that would require a request to satisfy every address requirement rather than any one of them.
Recommended Free Tools
#1 Best Overall
Nginx: exact-match the login location
Nginx’s access module supports individual addresses and CIDR ranges with allow, followed by deny all. An exact location limits the rule to the login script.
location = /wp-login.php {
allow 203.0.113.15;
allow 203.0.113.16;
deny all;
# Keep the site's existing PHP/upstream directives here.
}
The addresses in this example are documentation values; substitute your administrators’ real public addresses. Merge the access directives into the existing PHP configuration rather than replacing a working location block with this partial example. Removing the site’s FastCGI or upstream settings can make the login script fail even for an allowed user. If Nginx is managed by your host, request an allowlist for the exact route instead of editing a file you cannot safely control.
Rank #2
Caddy and IIS alternatives
Caddy
WordPress’s brute-force guidance includes a Caddy v2 client-IP matcher scoped to /wp-login.php that returns HTTP 403 when the request is not from a trusted address. Adapt the matcher to the current Caddy syntax and your proxy chain; do not assume the apparent client address is reliable until the proxy configuration is verified.
IIS
On IIS, use the server’s IP Address and Domain Restrictions feature or the corresponding web.config rule to permit the administrator addresses and deny unspecified clients. Apply it to the login path, test in staging, and confirm that your hosting plan permits the required configuration.
If you cannot edit the server
Ask the host or CDN whether it offers an edge firewall, WAF rule, or path-specific IP access policy. An edge rule can reject unwanted requests before they reach PHP. Make sure the policy can target /wp-login.php and, if needed, /xmlrpc.php independently. Feature names and plan limits change, so verify the provider’s current behavior rather than relying on a generic promise of “IP blocking.”
IP restriction is not rate limiting
An allowlist answers “which networks may reach this route?” Rate limiting answers “how frequently may requests arrive?” They are complementary controls, not substitutes.
Rank #4
| Control | Where it runs | What it does | Main trade-off |
|---|---|---|---|
| Server or proxy allowlist | Apache, Nginx, Caddy, IIS, CDN, WAF, or host edge | Rejects clients outside approved addresses before WordPress handles the request | Can lock out administrators when their public address changes |
| Server or edge rate limit | Web server, CDN, or WAF | Slows or rejects repeated requests while preserving access for changing addresses | Needs careful thresholds to avoid affecting legitimate users |
| WordPress plugin throttling | PHP/application layer | Adds login controls when infrastructure controls are unavailable | Attack traffic still consumes PHP and WordPress resources |
Prefer host, CDN, or server-level throttling when available. Use a plugin as a fallback when you cannot obtain an infrastructure rule, and configure it alongside—not as a replacement for—an IP policy where appropriate.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Handle XML-RPC and other authentication routes
Protecting wp-login.php does not protect xmlrpc.php. If XML-RPC is not needed, disable it using a method supported by your hosting and integration setup. If it is required by services such as Jetpack or mobile applications, keep it available only as necessary and apply separate access and rate-limit controls. Check any single-sign-on, application-password, or custom authentication endpoint your site exposes; each route needs its own policy.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Best Value
Verification checklist
- From an approved network, open
https://your-domain.example/wp-login.phpand confirm the form loads and a normal login succeeds. - From a different network, such as a phone hotspot, request the same URL and confirm the server or proxy returns the intended denial response (commonly HTTP 403).
- From the approved network, request
/wp-admin/while logged out and verify the redirect to/wp-login.phpstill works. - After logging in, test dashboard pages, media uploads, editor saves, AJAX-driven screens, and logout.
- Test
/xmlrpc.phpaccording to your chosen policy and verify that required integrations still function. - Review web-server, WAF, and WordPress logs for the test requests, confirming that the server identified the client address you intended to allow.
- Document the rule, the permitted networks, the recovery route, and the process for updating addresses before deploying it to production.
Common failure modes and recovery
Every administrator is blocked
Use the host console or another out-of-band route to remove or correct the rule. Check whether the server saw a proxy address instead of the administrator’s address, and verify IPv4 and IPv6 entries separately.
The rule appears ineffective
Confirm that the request reaches the server where the rule was installed, that the path is exactly /wp-login.php, and that a CDN or reverse proxy is not serving or forwarding it under a different policy. Inspect logs rather than trusting a browser’s cached response.
The login page returns a server error
On Nginx, restore the location’s original PHP/upstream directives and retain only the access lines. On Apache, check syntax and whether the host allows the authorization directives in the file where you placed them.
Legitimate access stops after an ISP or network change
Update the allowlist through the documented recovery route, then retest from both the new approved network and a disallowed one. If administrators move frequently, combine edge rate limiting with stronger authentication instead of relying on a narrow fixed-IP list alone.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

