Skip to main content
Blog|
How-to guides

Restrict WordPress Admin Access by IP Address

|
Mar 3, 2026|10 min read
HOW-TO GUIDESRestrict WordPress AdminAccess by IP AddressHOSTNEYhostney.comOctober 9, 2023

Your WordPress login page is public by default. Anyone on the internet can navigate to /wp-login.php or /wp-admin/ and start guessing passwords. Bots do this constantly. Automated scripts cycle through common username and password combinations thousands of times per day, probing every WordPress site they can find.

IP-based access control stops this dead. If your office IP is the only address allowed to reach the login page, it doesn’t matter how many bots try. They get a 403 Forbidden response before they even see a login form. No password prompt, no chance to brute force, no entry point at all.

This guide covers how to set up IP restrictions using both .htaccess (for Apache servers) and Nginx configuration (Hostney defaults to Nginx). We’ll also look at what automated bot detection can do for sites where strict IP whitelisting isn’t practical.

Why restrict access by IP#

WordPress admin is the most attacked part of any WordPress site. Restricting it by IP address:

Eliminates brute force attacks. Bots can’t attempt logins if they can’t reach the login page. Rate limiting and strong passwords help, but blocking access entirely is a level above.

Reduces server load. Every blocked request is a request your server doesn’t have to process through PHP and WordPress. On sites that get hammered by login bots, this can meaningfully reduce CPU usage.

Shrinks your attack surface. Even if a critical WordPress vulnerability is discovered tomorrow affecting the login or admin area, attackers can’t exploit it if they can’t reach those URLs from their IP address.

The trade-off is that you need a predictable IP address. If you work from home with a dynamic IP that changes regularly, or you frequently work from coffee shops and airports, strict IP restrictions can lock you out of your own site. We’ll cover alternatives later.

Method 1: Apache (.htaccess)#

If your site runs on Apache, you can restrict access by creating or editing an .htaccess file inside the wp-admin directory.

Step 1: Create the .htaccess file

WordPress ships with an .htaccess file in the root directory, but there isn’t one inside wp-admin by default. You need to create it:

nano /path/to/your/wordpress/wp-admin/.htaccess

This is a separate file from your main WordPress .htaccess . Rules here only apply to the wp-admin directory.

Step 2: Add IP restrictions

Add the following, replacing 1.2.3.4 with your actual IP address:

<Limit GET POST>
    order deny,allow
    deny from all
    allow from 1.2.3.4
</Limit>

This blocks every IP address except the one you specified. Both GET and POST requests are covered, which means the login form itself and the form submission are both restricted.

To find your current public IP address, search “what is my IP” on Google.

Adding multiple IP addresses

If several people need access, add a separate allow from line for each:

<Limit GET POST>
    order deny,allow
    deny from all
    allow from 1.2.3.4
    allow from 5.6.7.8
    allow from 9.10.11.12
</Limit>

You can also allow an entire IP range using CIDR notation. For example, to allow all addresses in the 10.0.0.0/24 subnet:

allow from 10.0.0.0/24

Protecting wp-login.php separately

The .htaccess file inside wp-admin doesn’t cover wp-login.php , which sits in the WordPress root directory. To restrict the login page as well, add this to your main .htaccess file (the one in the WordPress root):

<Files wp-login.php>
    order deny,allow
    deny from all
    allow from 1.2.3.4
</Files>

Without this, bots can still reach the login form at wp-login.php even though the admin dashboard is locked down.

Method 2: Nginx#

Hostney uses Nginx as its default web server. If your site runs on Nginx (whether with Hostney or another provider), .htaccess files don’t apply. Nginx uses its own configuration syntax.

Restricting wp-admin and wp-login.php

In your Nginx server block, add location rules for both the admin directory and login page:

location /wp-admin/ {
    allow 1.2.3.4;
    allow 5.6.7.8;
    deny all;

    try_files $uri $uri/ /index.php?$args;
}

location = /wp-login.php {
    allow 1.2.3.4;
    allow 5.6.7.8;
    deny all;

    include fastcgi_params;
    fastcgi_pass unix:/run/php-fpm/www.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Replace the IP addresses and adjust the fastcgi_pass path to match your PHP-FPM socket or TCP address.

After editing, test and reload the configuration:

nginx -t && systemctl reload nginx

Always run nginx -t first. A syntax error in the config will take your entire site down on reload if you skip the test.

Allowing AJAX for frontend functionality

Some WordPress plugins and WooCommerce use /wp-admin/admin-ajax.php for frontend AJAX requests. If you lock down the entire wp-admin directory, these requests break for regular visitors. Add an exception:

location = /wp-admin/admin-ajax.php {
    include fastcgi_params;
    fastcgi_pass unix:/run/php-fpm/www.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Place this location block before the wp-admin restriction so Nginx matches it first. Without this, WooCommerce add-to-cart buttons, contact forms, and other AJAX-dependent features will return 403 errors for your visitors.

Testing your configuration#

After setting up IP restrictions, verify they work from both sides.

From your allowed IP: Navigate to yourdomain.com/wp-admin/ . You should see the login page and be able to log in normally.

From a different IP: You should get a 403 Forbidden error. A few ways to test this:

  • Use your phone’s mobile data (disconnect from Wi-Fi). Your carrier assigns a different IP than your home or office network.
  • Use a VPN to connect from a different location.
  • Ask a colleague on a different network to try accessing the page.

If you get locked out, you can fix this by accessing your server via SSH or your hosting control panel’s file manager and editing the configuration file directly.

Adding password authentication as a second layer#

IP restrictions are strong on their own, but you can stack them with HTTP basic authentication for defense in depth. Even if someone gains access from an allowed IP, they face a username/password prompt before reaching WordPress login.

On Apache

First, create a password file (store it outside your web root):

htpasswd -c /home/yourusername/.htpasswd admin

Then add to your wp-admin/.htaccess :

AuthType Basic
AuthName "Restricted"
AuthUserFile /home/yourusername/.htpasswd
Require valid-user

<Limit GET POST>
    order deny,allow
    deny from all
    allow from 1.2.3.4
</Limit>

On Nginx

Create the password file the same way, then add to your location block:

location /wp-admin/ {
    allow 1.2.3.4;
    deny all;

    auth_basic "Restricted";
    auth_basic_user_file /home/yourusername/.htpasswd;

    try_files $uri $uri/ /index.php?$args;
}

Keep the .htpasswd file outside your document root. If it’s inside public_html or your web root, anyone could potentially download it and crack the password hashes offline.

When IP restrictions aren't practical#

IP-based access control is the strongest option, but it requires static, predictable IP addresses. That doesn’t work for everyone. Remote teams, freelancers, and anyone with a dynamic ISP address may find strict IP whitelisting more frustrating than helpful.

A few workarounds for the IP problem:

Use a CIDR range. If your IP typically stays within the same block, allow the entire /24 range. Less restrictive than a single IP, but still blocks 99.99% of the internet.

Use a VPN with a static IP. Services like WireGuard or a self-hosted VPN give you a fixed exit IP. Whitelist that one address and always connect through the VPN when accessing admin.

Rely on automated bot detection instead. If managing IP lists is impractical for your team, a good bot detection system can provide comparable protection without the maintenance overhead. This is where things get interesting.

How Hostney's bot detection protects WordPress login#

If you’re hosting with Hostney, your WordPress login page is already defended by multiple automated layers before you configure anything. These protections run at the server edge, meaning they intercept malicious traffic before it ever reaches PHP or WordPress.

Proof-of-work challenges

When the system identifies a suspicious IP, it serves a JavaScript challenge page instead of your login form. The visitor’s browser must solve a SHA-256 computational puzzle (takes about 1-5 seconds for a real browser) and submit the solution. On success, a signed cookie is issued for 15 minutes.

Why this works: legitimate visitors with a real browser solve the challenge automatically and barely notice it. Automated scripts, headless bots, and tools like curl or Python’s requests library can’t execute JavaScript at all. They never get past the challenge page, which means they never reach wp-login.php .

Real-time brute force detection

Two detection layers catch login attacks as they happen:

Rate detection monitors request volume in short time windows. As an IP makes increasingly aggressive requests, the system escalates its response, from issuing a challenge to temporary bans of increasing duration. These thresholds catch automated attacks within seconds.

Endpoint-specific detection tracks repeated hits to the same URL. An IP repeatedly requesting the same page in a short period triggers a challenge, regardless of overall request volume. This catches slower, more methodical brute force attempts that stay under the general rate limit.

Behavioral scoring

Behind the real-time detection, a scoring system builds a threat profile for every IP that interacts with your site. Login-specific behaviors carry significant weight:

  • Concentrated requests to login endpoints (wp-login.php, xmlrpc.php, /wp-admin/) add 15 points
  • Hitting multiple login paths across different applications (WordPress login plus phpMyAdmin plus generic /admin) adds another 15 points, since it indicates automated vulnerability scanning rather than a real user who forgot their password
  • Failing to solve proof-of-work challenges adds up to 20 points
  • Missing the sentinel cookie (a tracking security cookie set on every response that real browsers persist but scripts ignore) adds up to 15 points

As points accumulate, the system ratchets up its response. An IP scoring 21-50 gets rate-limited. Above 50, every request requires a proof-of-work challenge. Above 80, the IP is banned outright with a straight 403 response. The entire progression from first suspicious request to full ban typically takes under 10 minutes for an active brute force attack.

Legitimate users are never affected

This is the part that matters most. The system automatically detects WordPress login cookies ( wordpress_logged_in_* ) and exempts logged-in users from all bot detection. If you’re already authenticated, you can access wp-admin at full speed with no challenges, no rate limits, and no interference, even if you’re making hundreds of requests importing content or configuring plugins.

WooCommerce AJAX requests through /wp-admin/admin-ajax.php are also excluded from endpoint-specific detection, so shopping cart updates, product filters, and checkout flows work normally for all visitors.

Additional server-level controls

Beyond automated detection, Hostney provides toggleable security settings for WordPress:

  • Disable XML-RPC at the server level (returns 403 for  /xmlrpc.php ), eliminating a common brute force and DDoS amplification vector
  • Block user enumeration by restricting the  /wp-json/wp/v2/users  REST endpoint, preventing attackers from discovering valid usernames
  • Block PHP execution in uploads by returning 403 for  .php  files inside  /wp-content/uploads/ , which stops uploaded web shells from executing
  • IP whitelist per website for trusted addresses that should bypass all bot detection entirely (your office, monitoring services, payment webhooks)

IP restrictions vs. bot detection

Both approaches stop brute force attacks. The difference is operational:

IP restrictionsAutomated bot detection
SetupManual configurationWorks out of the box
MaintenanceUpdate IPs when they changeSelf-maintaining
Remote teamsDifficult with dynamic IPsTransparent to real users
False positivesLock yourself out if IP changesProof-of-work lets humans through
Protection scopeOnly covers configured pathsProtects entire site
Zero-day exploitsBlocks access to protected pathsBlocks suspicious behavior patterns

For maximum security, use both. Whitelist your known IPs through the Hostney dashboard and let the automated system handle everything else. Your team gets direct access, and everyone else goes through bot detection.

Maintenance and best practices#

Keep your IP list current. When team members leave or office locations change, update the allowed IPs promptly. An old IP address might be reassigned to someone else by the ISP.

Document your allowed IPs. Keep a simple record of which IPs are allowed and why. Six months from now, you won’t remember whether 192.168.0.1 is the office, a developer’s home, or something you should have removed.

Monitor your access logs. Blocked requests still show up in server logs. Periodically check how many 403 responses your login page is generating. A high volume confirms the restrictions are working and catching real attack traffic.

Don’t forget xmlrpc.php . The XML-RPC endpoint is another common brute force target. If you don’t use apps or services that require it (like the WordPress mobile app or Jetpack), block it entirely or apply the same IP restrictions.

For a deeper look at securing WordPress beyond IP restrictions, read our guide on how to protect WordPress.

Check out WordPress.org for additional resources.

Try Hostney web hosting free for 14 days. Every plan includes Nginx, free SSL, built-in caching, and automated bot detection for WordPress.

Related articles