Every WordPress site has the same front door: /wp-login.php and the /wp-admin/ area behind it. Anyone on the internet can reach that door, and on most sites, thousands of bots knock on it every day. Strong passwords, login rate limiting and two-factor authentication make sure they can’t get in. But there’s another option that many site owners never consider: making sure most people can’t even reach the door. When you restrict wp-admin access at the server level, the login page simply doesn’t exist for anyone who isn’t supposed to see it.
It’s a powerful technique, and on the right sites it removes almost all login-related attack traffic overnight. On the wrong sites, it causes confusing breakages, locks out legitimate users and creates support headaches. This article explains both approaches, IP allowlisting and HTTP authentication, when each one makes sense and how to avoid the classic mistakes.
Why add another layer
If your passwords are strong and you use two-factor authentication, you might wonder why this matters. There are three good reasons.
First, defence in depth. Login protections are WordPress plugins or features running inside PHP. If a vulnerability is ever found in the login process itself, or in a plugin that hooks into it, a server-level restriction still blocks attackers before WordPress loads.
Second, server load. Brute-force bots don’t stop just because they fail. Every attempt to load wp-login.php starts PHP, loads WordPress and often queries the database. On small servers, that traffic adds up. Blocking it at the web server costs almost nothing.
Third, noise. Security logs full of failed login attempts make it harder to spot the attempts that matter. When the login page is unreachable for the world, the logs become quiet and anything unusual stands out.
Option 1: IP allowlisting
An IP allowlist tells the web server to only allow requests to the admin area from specific IP addresses. Everyone else receives a 403 Forbidden error.
When it works well
IP allowlisting is ideal when the people who log in work from a small number of fixed locations: an office with a static IP address, a VPN that everyone connects through or a single developer with a fixed home connection.
When it causes problems
It’s a poor fit when administrators work from many places, use mobile data, travel often or have home connections with changing IP addresses. Most residential broadband connections in India and many other countries use dynamic IPs that change periodically. The day an editor’s address changes, they’re locked out, usually at the worst possible moment.
It’s also a poor fit for sites where customers log in through wp-login.php, such as membership sites and some WooCommerce stores. You can’t allowlist every customer.
Setting it up on Nginx
Restrict the login page and the admin area, but leave admin-ajax.php open, because the front end of many sites depends on it:
The exact PHP lines will depend on your configuration, so copy them from your existing PHP location block. The important part is the structure: admin-ajax.php is handled before the allow and deny rules apply.
Setting it up on Apache
In a .htaccess file placed inside the wp-admin folder:
And in the root .htaccess, for the login page:
Behind Cloudflare or a proxy
If your site sits behind Cloudflare or another proxy, the web server sees the proxy’s IP address, not the visitor’s. Your allowlist will either block everyone or allow everyone, depending on the rules. Make sure the server is configured to read the real visitor IP from the proxy’s header, or do the allowlisting in the proxy itself. In Cloudflare, a custom WAF rule that blocks /wp-login.php and /wp-admin/ for everyone except listed IPs, with an exception for admin-ajax.php, does the same job before traffic reaches your server.
Option 2: HTTP authentication
HTTP authentication, often called basic auth, adds a browser login prompt before the WordPress login page. Visitors must enter a separate username and password just to see wp-login.php.
When it works well
HTTP authentication suits teams that work from varying locations. It doesn’t care about IP addresses, so travelling editors and dynamic home connections aren’t a problem. It’s also a good choice for staging sites, where the whole site should be hidden.
When it causes problems
It adds friction: two logins instead of one. Password managers handle it, but some people find it confusing. Like IP allowlisting, it doesn’t suit sites where customers log in through wp-login.php.
Basic auth sends credentials with every request, encoded but not encrypted, so it must only be used over HTTPS. On any site with a valid certificate and HTTPS enforced, that’s not an issue.
Setting it up on Nginx
Create a password file with the htpasswd tool:
Then protect the login page:
Protecting wp-login.php alone is often enough, because the admin area redirects to the login page when you’re not logged in. Protecting the whole /wp-admin/ folder adds a prompt every time, and you’d again need an exception for admin-ajax.php.
Setting it up on Apache
Keep the password file outside the web root, so it can never be downloaded.
The admin-ajax.php trap
This deserves its own section, because it’s the single most common way these restrictions break sites. The file wp-admin/admin-ajax.php lives inside the admin folder, but it isn’t only for administrators. Plugins use it to handle front-end requests: contact forms, search filters, add-to-cart actions, load-more buttons, live chat, voting widgets and much more.
If you restrict the entire /wp-admin/ folder without an exception, those features break for every visitor. Often they break silently. A form appears to submit but nothing arrives. A filter spins forever. A cart doesn’t update. Nobody notices until a customer complains or sales drop.
Always exclude admin-ajax.php, and after setting up any restriction, test the front end while logged out from a different network, such as your phone on mobile data.
Some plugins also load CSS, JavaScript or images from inside the wp-admin folder on the front end. If something looks broken after you add restrictions, check your browser’s developer tools for files from /wp-admin/ returning 403 errors.
Other things that may need access
Before restricting access, think about what else talks to your admin area:
- Jetpack and the WordPress mobile apps may need access to login or admin endpoints, depending on configuration.
- Uptime monitors that check the login page will start reporting errors. Point them at a public page instead.
- Site management dashboards such as MainWP or ManageWP usually communicate through their own endpoints, but test after enabling restrictions.
- Payment gateways and webhooks normally use the REST API or front-end URLs, not wp-admin, but confirm with test transactions.
- WooCommerce customers who log in through My Account use a front-end form, which is fine, but if your theme sends them to wp-login.php for password resets, they’ll hit the restriction.
Changing the login URL instead
Some security plugins offer to move the login page to a custom URL, such as /team-login/. This hides it from bots that only try the default address. It’s a reasonable, low-effort measure that reduces noise, but it isn’t real access control. Anyone who discovers the custom URL can reach it, and some plugins leak it through redirects or links. Think of it as camouflage rather than a lock. Server-level restrictions are stronger, and the two can be combined.
Keeping yourself from getting locked out
Lockouts happen. A new office connection, a changed VPN address, a forgotten basic auth password. Plan for them:
- Keep server access, such as SSH or the hosting control panel, separate from the WordPress admin, so you can always edit the rules.
- Document where the rules live: which file, which server block.
- Allow a secondary address, such as a VPN, as a fallback.
- Tell the team how to request access when their IP changes.
If you manage sites for clients, write the restriction into your handover documentation. A client who changes broadband provider and suddenly can’t log in will call you first, and you’ll want to remember instantly what you set up two years ago.
Which should you choose?
For most small businesses with one or two people editing from changing locations, HTTP authentication on wp-login.php is the better fit. It blocks bots completely and doesn’t care where the editor is sitting.
For organisations with an office network or VPN, IP allowlisting is cleaner, because there’s no second password to manage.
For membership sites and stores where customers use wp-login.php, neither is suitable for the whole login page. In those cases, rely on rate limiting, two-factor authentication for staff and firewall rules, or move customer logins to a front-end form and restrict wp-login.php for staff only.
Whichever you choose, when you restrict wp-admin access you’re adding a layer, not replacing one. Keep strong passwords and two-factor authentication in place as well.
Frequently asked questions
Will restricting wp-admin break my site for visitors?
Not if you exclude admin-ajax.php and test the front end afterwards. Most problems come from forgetting that exception.
Can I restrict access with a plugin instead?
Some security plugins can block the login page by IP or add extra login challenges. They work inside WordPress, so they don’t save as much server load as web server rules, but they’re a reasonable option when you don’t have server access.
What if my IP address changes often?
Use HTTP authentication instead of an IP allowlist, or connect through a VPN with a fixed address and allowlist that.
Does this replace two-factor authentication?
No. It reduces exposure, but if an attacker gets past it, for example from an allowed network, two-factor authentication is still your strongest protection.




