Guides/Restrict wp-admin by IP

WordPress security guide

How to restrict wp-admin to your IP address

Most WordPress sites have one or a few people who ever log in. Letting the rest of the internet reach the login page and wp-admin is a choice, not a requirement.

Today, on most WordPress sites GET/wp-admin/open to all

Anyone anywhere can reach the login form and every admin page.


After this guide GET/wp-admin/403 Forbidden

Only your own addresses get past the door; admin-ajax stays open.

Why it matters

One doorPassword guessing, stolen sessions and admin-side plugin bugs all stop at the door.
Few editorsMost sites have a handful of people who ever log in.
CheapA few lines of server config, no plugin.

Before you start: find your address by searching "what is my IP" from the network you work on. Home connections often change address, so allow a range or keep another way in (a VPN with a fixed address, or SSH to the server). And /wp-admin/admin-ajax.php must stay open: themes and plugins call it from public pages for every visitor.

Check your site

From a phone on mobile data, so not your usual address:

curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-login.php

A 200 means the login page is open to everyone. After the fix it should be 403 from anywhere but your own addresses.

Fix it

nginx

# admin-ajax.php stays open to everyone (exact match wins).
location = /wp-admin/admin-ajax.php {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/run/php-fpm/www.sock;
}

location ~ ^/(wp-admin|wp-login\.php) {
    allow 203.0.113.10;      # your address
    allow 198.51.100.0/24;   # an office range
    deny  all;

    try_files $uri $uri/ /index.php?$args;
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/run/php-fpm/www.sock;
    }
}

Catch: put this block before the general PHP block, and use the same fastcgi_pass as your existing one. Behind a CDN or proxy, set up the real_ip module first, or nginx sees the proxy's address and lets everyone in or nobody.

Apache

Create wp-admin/.htaccess:

Require ip 203.0.113.10 198.51.100.0/24

<Files admin-ajax.php>
    Require all granted
</Files>

And in the main .htaccess, for the login page:

<Files wp-login.php>
    Require ip 203.0.113.10 198.51.100.0/24
</Files>

Catch: behind a proxy, Apache needs mod_remoteip configured for the same reason.

If you lock yourself out

Edit or rename the .htaccess file, or remove the allow lines and reload nginx, over SFTP or SSH. That is why a second way in matters before you start.

Questions

Will this break my site for visitors?

No, as long as admin-ajax.php stays open. Visitors never need wp-admin or the login page, unless your site has member logins; then restrict wp-admin only.

My address changes every day. What then?

Allow your provider's range, use a VPN with a fixed address, or rely on a login rate limit and two-factor login instead.

Does this replace two-factor login?

They protect different things. The address lock keeps strangers away from the login form; two-factor login protects you if a password leaks while you are on an allowed address.

More guides

Last reviewed 2026-10-08