Blocking and allowing addresses

One switch, one screen. What an entry may look like, which address is actually judged, and why the allowed list is a record rather than a key.

  • Intermediate
  • 7 min read
  • Applies to 2.0

Turning it on

User Access → Security → IP Blocking. With the switch off, the IP Manager screen is not in the menu.

Then User Access → IP Manager, which has two tabs: Blocked IPs and Allowed IPs.

The IP Manager screen, Blocked IPs tab, with its Add, Import, Export and Clean Up buttons.

What an entry can be

FormExample
A single IPv4 address192.168.1.1
A single IPv6 address2001:db8::1
An IPv4 range192.168.1.0/24
An IPv6 range2001:db8::/64

Ranges use CIDR notation — the number after the slash is how many leading bits must match. /24 on IPv4 means "the first three numbers", so 192.168.1.0/24 covers 192.168.1.0 through 192.168.1.255.

Anything else is refused, including wildcards like 192.168.1.* and dashed ranges like 192.168.1.1-50.

Only the blocked list turns anyone away

A blocked address is refused with a 403 — every page, not a login screen. That is the whole of the enforcement: there is no mode in which the plugin admits only the addresses you name and shuts out the rest.

Administrators are exempt from the check, and AJAX requests pass through untouched, so a mistyped entry cannot lock you out of your own dashboard.

What the allowed list is for

It is a record, not a key. Nothing on the site consults it to grant access, and adding an address grants that address nothing it did not already have — every visitor who is not blocked already gets in.

What it does do is answer a question you will ask sooner or later: have we seen this address before, and did we consider it legitimate? The lookup on the IP Manager screen reports an address as allowed when it is on that list, which is how a note you left months ago comes back to you at the moment it is useful.

It follows that the allowed list is not a way round a block. An address on both lists is blocked. To un-block someone, remove them from the blocked list.

Which address is judged

The address the connection arrives from, and only that one. Headers a visitor can write — X-Forwarded-For, Client-IP, CF-Connecting-IP — are ignored, because a list that read them would be a list anyone could talk their way onto or off.

That is the right default until your site sits behind a proxy, and then it is the wrong one: behind Cloudflare or a load balancer, every visitor arrives from the proxy, so one entry lets the whole internet in and the lists stop distinguishing anybody. On such a site, name the header the proxy sets and nothing else:

add_filter( 'attrua_pro_trusted_ip_headers', function () {
    return array( 'HTTP_CF_CONNECTING_IP' );
} );

add_filter( 'attrua_pro_trusted_proxies', function () {
    return array( '173.245.48.0/20', '103.21.244.0/22' ); // your proxy's ranges
} );

Name the proxy as well as the header. The second filter lists the addresses and CIDR ranges your proxy connects from, and a request that did not come from one of them has its header ignored no matter what it says.

That second filter is what makes the first one safe. A header is written by whoever sends the request, so trusting one on its own means trusting every visitor to be honest about who they are — enough to step around a block, or to write somebody else's address into your audit log. Naming the proxy turns the header into evidence: only the proxy is believed, and the proxy is the only one that can reach you from that address.

If you name a header but no proxy, the header is trusted on the caller's word. That is only safe when the proxy is genuinely the sole way in — no direct access by IP, no staging hostname answering separately, no firewall exception. It is easier to be wrong about that than it sounds, which is why naming the proxy is the better habit.

Expiry dates

Every entry can carry an expiry date, and the field is an exact date and time rather than a duration. Leave it empty for a permanent entry.

An expired entry stops applying immediately — the moment its time passes, the address is treated as though it were not on the list. It stays visible in the table, marked as expired, until it is cleared away. A daily task removes expired entries, and Clean Up Now does it at once if you would rather not wait.

Adding several at a time

Import IPs takes one address per line and applies the same expiry date and the same note to every line in the batch. Export IPs gives you the current tab as CSV; Export All gives you both lists.

The bulk actions under each table act on that tab's list only.

Coming from version 1.x? The blocked list was never consulted. The check that reads it was asked for at a moment that had already gone by, so it was never registered, and blocked addresses browsed the site like anyone else. It is enforced in 2.0 — which means an upgrade can suddenly start refusing entries that have sat there inert for months. Read the blocked list before you upgrade.

The same release removed Allowed Addresses Only, a switch that closed the site to every address not on the allowed list. It had never actually turned anyone away either. If it is on in your settings, it simply stops meaning anything; nothing else changes.

Coming from version 1.x? Three more things behaved badly enough to be worth re-checking. A bulk delete on the Blocked tab removed entries from the allowed list instead, while the rows on screen faded out as though it had worked — so compare both lists against what you expect. IPv6 addresses written the short way (2001:db8::1) were rejected by the form even though the help text offered them as an example. And expired entries were never cleared away automatically. All three are fixed in 2.0.

What this screen is not

Nothing here happens on its own. The plugin never adds an address to the blocked list by itself, however many times someone fails to sign in — that is login throttling, a separate mechanism that works on usernames and never touches these lists. A locked-out account will not appear here.

There is no country or region blocking in the plugin.

Something missing or out of date? Tell support.