Short answer: WordPress can block IP addresses at three different layers and the right one depends on what you are trying to stop. Block at the WordPress plugin layer (Wordfence, Solid Security) when you want visibility into who hit your login form and why. Block at the server layer (Nginx
deny
, Apache
Require not ip
, or your host’s panel) when you want the request to never reach PHP. Block at the edge layer (your host’s bot detection, Cloudflare firewall rules) when you want to stop traffic before it touches your server at all. IP blocking is one tool, not a complete defense – rotated addresses, residential proxies, and bot nets make pure IP bans a holding action.
WordPress IP blocking is one of those tasks where the question “how do I block an IP” hides a more important question: where in the stack should the block live, and how long should it last. The wrong answer is “in the plugin, forever.” That worked in 2014 when a single IP could be reasonably attributed to a single attacker. Today, attackers rotate IPs across cloud regions, use residential proxy pools, and recycle compromised devices. A block-list of 1,200 IPs that you have been adding to for three years is mostly stale, while the IPs that actually matter today are not on it yet.
This guide covers every layer where you can block IPs – plugins,
.htaccess
, Nginx, hosting control panels, edge networks – the operational tradeoffs between them, and when IP blocking is the right tool versus when behavior-based detection serves you better.
Where to block: the four layers at a glance#
| Layer | Where it runs | What it stops | Performance cost | Visibility | When to use |
|---|---|---|---|---|---|
| Plugin (Wordfence, Solid Security) | Inside PHP/WordPress | Requests that already hit WordPress | High – request still loads WP | High – per-request log with reason | You need to see who is attacking and why |
.htaccess
(Apache) | Apache before PHP | All HTTP requests to the site | Low | None unless you tail Apache logs | Apache-only hosts without panel control |
Nginx
deny
directive | Nginx before PHP-FPM | All HTTP requests to the site | Very low | None unless you tail Nginx logs | Nginx hosts with shell access |
| Hosting panel block list | Server config managed by host | All HTTP requests at the front door | Very low | Panel UI + audit log | Default choice on managed hosting |
| Edge network (Cloudflare, host bot detection) | Outside your origin | Traffic before it reaches your server | None – blocked upstream | Edge dashboard | High-volume attacks, geographic blocks |
The layer that fits depends on your access. If your host gives you a panel block list, use that – it writes a single deny line that runs before WordPress and you keep an audit trail. If you only have WordPress access, use a plugin. If you have shell access and no panel, edit Nginx or
.htaccess
directly.
Method 1: Block IPs from a hosting control panel#
This is the cleanest option when your host supports it. The panel writes the block directly into the web server config, so the request is rejected before it ever reaches PHP, but you still have a UI to review, edit, and remove entries.
On Hostney, the Blocked IPs page under the Security section handles both manual IP/CIDR blocks and full country blocks. Each entry is bound to a specific subdomain under the domain you are managing, so you can block
203.0.113.42
on
wp.example.com
without affecting
staging.example.com
. The page supports:
- Single IPv4 or IPv6 addresses –
203.0.113.42or2001:db8::1 - CIDR ranges –
203.0.113.0/24to block an entire /24,203.0.113.0/16for a /16, any standard mask - Country blocks – select a country, blocks all visitors from that origin via Nginx GeoIP2
The panel writes a
deny
directive into the Nginx config for the matching
server
block, the request is rejected with
403 Forbidden
at the front door, and PHP never starts. Removing a block is one click and the audit log records the change against your account so you can see who added or removed which entry and when.
The same approach works on cPanel via the IP Blocker tool, on Plesk via Tools & Settings > IP Access, and on DirectAdmin via Admin Tools > IP Manager. Each writes the block into the appropriate server config behind the scenes.
Method 2: Block IPs from a WordPress plugin#
Plugin-level blocking runs inside WordPress, which means the request has already passed Nginx, started a PHP-FPM worker, and loaded WordPress core before the plugin gets a chance to reject it. The upside is per-request visibility – you see exactly who hit which URL with which user agent and why the plugin chose to block. The downside is that an attacker hammering
/wp-login.php
with 200 requests per second still costs you 200 PHP-FPM workers per second, even if all 200 are then blocked.
Wordfence#
Wordfence is the most widely used WordPress security plugin and has a robust IP blocking UI:
- Install and activate Wordfence
- Go to Wordfence > Blocking
- Add an IP address or range under “Block by IP Address Range”
- Optionally set a reason for the block (for your own records)
Wordfence also offers automatic blocking based on failed login attempts, 404 patterns, and known-bad signatures via its premium tier. The free tier covers manual blocks and basic auto-blocking. Wordfence Live Traffic (Premium) lets you watch requests in real time and one-click block anything suspicious – this is the unique value of plugin-layer blocking over server-layer.
Solid Security (formerly iThemes Security)#
Solid Security takes a similar approach with its Banned Users feature:
- Install Solid Security
- Go to Security > Settings > Banned Users
- Add IPs under “Ban Hosts” – one per line
- Save changes
Solid Security writes blocks into
.htaccess
when possible (so they run at the Apache layer rather than PHP), which is more efficient than Wordfence’s PHP-level blocking. On Nginx hosts the
.htaccess
write is a no-op and the block falls back to PHP-level handling.
When plugin blocking is the right call#
- You want to see attack patterns in real time before deciding what to block
- You need per-request visibility (URL, user agent, referer) for forensics
- Your host does not give you panel-level IP blocking
- You are already running the plugin for other reasons and the marginal cost is zero
The wrong reason to use plugin-layer blocking is “because it is what I know.” If you are blocking the same 50 known-bad IPs that have been static for two years, moving them to your hosting panel or to
.htaccess
/Nginx removes the PHP-FPM cost.
Method 3: Block IPs in .htaccess (Apache)#
If you have FTP/SFTP access and your site runs on Apache, you can block IPs directly in
.htaccess
. Add this block at the top of your
.htaccess
file (or in a separate file included before WordPress’s own rules):
<RequireAll>
Require all granted
Require not ip 203.0.113.42
Require not ip 198.51.100.0/24
</RequireAll>
The legacy syntax (still supported in Apache 2.4 with
mod_access_compat
) is:
order allow,deny
allow from all
deny from 203.0.113.42
deny from 198.51.100.0/24
Place the block before WordPress’s
# BEGIN WordPress
section so it runs before WordPress’s URL rewriting. The request is rejected with
403 Forbidden
before PHP starts.
.htaccess gotchas#
- Don’t put it inside the WordPress block. WordPress’s
# BEGIN WordPress/# END WordPresssection is rewritten automatically by core, so your blocks will get overwritten on the next permalink save. - CIDR notation matters.
/24blocks 256 addresses (203.0.113.0through203.0.113.255)./32blocks one address./16blocks 65,536. Use a CIDR calculator if you are unsure. - IPv6 works the same way.
Require not ip 2001:db8::/32blocks an IPv6 /32 range. -
.htaccessonly works on Apache. On Nginx hosts the file is ignored; use Method 4 instead.
Method 4: Block IPs with Nginx deny#
If your site runs on Nginx and you have shell access, add
deny
directives inside your
server
block (or inside a specific
location
block if you only want to block requests to a particular path):
server {
server_name example.com;
# ... other config ...
deny 203.0.113.42;
deny 198.51.100.0/24;
deny 2001:db8::/32;
allow all;
# ... rest of config ...
}
The
deny
directives are evaluated top to bottom; the first match wins. Always end with
allow all;
so unmatched IPs are permitted. Nginx returns
403 Forbidden
for blocked IPs at the connection-handling layer before any FastCGI work happens.
Reload Nginx after editing:
nginx -t # test the config
nginx -s reload # reload if test passes
Block only
/wp-login.php
for a specific IP by nesting inside a
location
block:
location = /wp-login.php {
deny 203.0.113.42;
allow all;
# ... existing fastcgi config ...
}
This is useful when you want to permit an IP to read the site but stop it from hitting the login form specifically.
Method 5: Block at the edge with Cloudflare or host bot detection#
When attacks scale past what your origin can absorb, IP blocking needs to happen before the traffic reaches you at all. This is the edge layer.
Cloudflare Firewall Rules. If you proxy through Cloudflare, the Firewall Rules dashboard lets you block by IP, country, ASN, or behavioral patterns. Blocks happen at Cloudflare’s edge nodes, so the request never touches your server. This is the right place for high-volume attacks where the PHP-FPM or even Nginx cost of rejecting them would still saturate your machine.
Host edge bot detection. Some hosting providers run their own edge layer that detects and blocks abusive traffic before it reaches the origin. On Hostney this is the Lua bot detection layer inside the front-line Nginx servers – it scores incoming IPs based on behavior (hitting honeypot URLs, hammering the login form, scanning for known WordPress paths) and automatically challenges or bans the worst offenders. Manual IP blocks in the panel are the customer-controlled layer that sits alongside the automatic edge detection.
The edge layer is the right tool when you are seeing sustained attack volume that costs real resources, when the source is geographically concentrated and you can block a whole country or ASN, or when behavior-based detection catches what static IP lists cannot.
Blocking by country#
Country-level blocks are useful when you have no business in a particular region and the traffic from there is overwhelmingly malicious. Examples: a small US-only law firm seeing constant login attempts from offshore IP ranges, a European e-commerce site with no shipping outside the EU.
Methods:
- Hosting panel. On Hostney the Blocked IPs page has a country blocks tab that uses Nginx GeoIP2 – select countries from a dropdown, blocks apply at the Nginx layer. Other hosts (cPanel, Plesk) typically offer this as a paid GeoIP add-on or via security plugins.
- Plugin. Wordfence Premium and iQ Block Country handle WordPress-layer country blocking. Free tiers usually do not include this.
- Cloudflare. Free plan supports country-block firewall rules.
The honest catch with country blocks#
Country blocks affect every visitor from that origin, not just bots. Don’t block your own country by accident. And remember:
- VPNs bypass country blocks trivially. A sophisticated attacker uses a VPN exit node in the country you allow. Country blocks stop low-effort attacks, not motivated ones.
- Mobile carriers route through unexpected geographies. A US mobile user roaming or on certain carriers may appear to come from another country.
- Search engine crawlers don’t all come from where you think. Bing crawlers, for example, run from multiple regions.
Country blocking is a coarse filter. Layer it with behavioral detection rather than relying on it alone.
Blocking single IPs vs ranges (CIDR)#
A single IP block (
203.0.113.42
) stops one address. A CIDR block (
203.0.113.0/24
) stops a contiguous range. Use ranges when:
- The attack source is a hosting provider’s address pool (e.g. AWS, OVH, DigitalOcean abuse reports often list the entire owning subnet)
- You see a pattern of attacks from IPs in the same /24 (likely the same operator on different IPs in their pool)
- A specific ASN or data center range is the source
CIDR sizes at a glance:
| Notation | Addresses | Typical use |
|---|---|---|
| /32 | 1 | Single IPv4 address |
| /29 | 8 | Small office subnet |
| /24 | 256 | Most common – typical hosting provider sub-allocation |
| /16 | 65,536 | Entire ISP allocation |
| /8 | 16.7M | Almost never appropriate |
Be careful with large CIDR blocks. Blocking a /16 because you got hit by three IPs in it can cut off 65,000 legitimate users. When in doubt, start narrow.
When IP blocking is the wrong tool#
IP blocking has been the default WordPress security answer for fifteen years, but it has gotten weaker every year as attackers got better at IP rotation. Cases where pure IP blocking will not solve your problem:
The attacker uses residential proxies. Services like BrightData and Smartproxy rotate through millions of real residential IPs. Each request comes from a different home internet connection. Blocking one IP gets you a different one next request. Behavioral detection (rate limits, request fingerprinting, challenge pages) handles this; IP lists do not.
The attack is distributed across cloud regions. Botnets running on compromised cloud instances cycle through AWS, GCP, OVH, Hetzner, and dozens of smaller providers. By the time you have blocked one source, the operator has moved.
The attacker is fast enough that detection cannot keep up. You can manually block IPs faster than humans, but slower than the attacker’s rotation. Reactive blocking is a treadmill.
Your audience is global and you cannot afford false positives. Aggressive IP blocking eventually catches a legitimate user behind a corporate NAT, a mobile carrier CGNAT pool, or a shared VPN exit node. The complaints add up.
The complement to IP blocking is behavior-based detection – rate limiting per IP regardless of identity, challenges (CAPTCHAs, proof-of-work) for traffic that looks automated, and blocking based on what a request does rather than who sent it. Hostney’s bot detection layer scores IPs by behavior (hitting honeypot URLs, hammering login forms, scanning for known WordPress paths) so the worst actors get caught regardless of how often they rotate, and our server-level approach complements Wordfence rather than replacing it. Combine the two: manual IP blocks for known persistent abusers, behavioral detection for everything else.
Three layers of IP control: what is the difference#
WordPress administrators frequently conflate three different things that all involve IP addresses. They behave differently:
| Layer | Purpose | Permanent? | What it does |
|---|---|---|---|
| Manual block list (panel, plugin, Nginx) | Customer-controlled bans | Yes, until removed | Rejects requests from listed IPs |
| Automatic edge bans (fail2ban, host bot detection) | Reactive bans triggered by behavior | No – auto-expires | Temporary deny based on attack patterns |
| Allow list / whitelist | Bypass for trusted IPs | Yes, until removed | Exempts IPs from rate limits, challenges, or detection |
When you say “unblock this IP,” check all three. If a customer service rep says “I added the office IP to the block list” and you cannot find it on your block-list page, it might be in the temporary fail2ban list (which expires on its own) or in the allow list (which would override blocks anyway). On Hostney these are three separate pages under Security so the distinction stays clear; on hosts that mix them you will need to look in three places.
Common mistakes#
Blocking your own IP. Easy to do, hard to recover from if you locked yourself out of
/wp-admin
. Always test the block from a separate connection (mobile data, a VPN) before assuming it works correctly.
Blocking search engine crawler IPs. Googlebot, Bingbot, and others come from massive IP ranges that change. If you block one and it turns out to be Googlebot, your SEO takes a hit. Use verified-bot detection rather than blocking ranges that might overlap with crawlers.
Blocking entire cloud providers because of one abuser. Blocking all of AWS or all of OVH cuts off a meaningful slice of the legitimate internet (uptime monitors, RSS readers, link-preview services, headless browser-based research tools). Be narrower.
Adding to the block list and never removing. A block list of 800 entries that you have been adding to since 2019 is mostly stale. Periodically prune it – the original abuser has moved IPs many times, and current legitimate users may be hitting addresses you blocked years ago.
Treating IP blocks as the primary defense. They are a layer, not a fortress. Combine with rate limiting, two-factor authentication, behavioral detection, and a hardened login flow.
Forgetting to back up
.htaccess
or your Nginx config before editing. A bad
deny
directive or syntax error can take the whole site offline. Keep a backup so you can restore quickly.
How long does each method take#
| Action | Time |
|---|---|
| Block one IP via hosting panel | Under 30 seconds |
| Block one IP via Wordfence | Under a minute |
Block one IP via
.htaccess
| 2-3 minutes (find file, edit, save) |
| Block one IP via Nginx + reload | 2-3 minutes (edit config, test, reload) |
| Block a country via panel | Under a minute |
| Add 50 IPs from an abuse report | 10-20 minutes manually, faster with bulk-import if your panel supports it |
| Prune a stale 500-entry block list | 1-2 hours (worth doing annually) |
Blocking IPs on Hostney#
The Blocked IPs page under Security handles manual blocks for both IPs and countries. The shape is:
- Domain-scoped page, FQDN-scoped rows. You manage blocks under a specific domain, but each entry binds to one subdomain under that domain. Blocks on
wp.example.comdo not affectstaging.example.com. - Single IPv4, IPv6, and CIDR all supported. Type
203.0.113.42for one address,203.0.113.0/24for a /24 range,2001:db8::/32for an IPv6 range. The page validates the format before submission. - Country tab. Select a country code (US, GB, DE, etc.) and the block applies via Nginx GeoIP2. Includes a warning when the country selected is one of your account’s billing or signup origins, so you do not accidentally block yourself.
- Audit log. Every add or remove is recorded against your account, so delegate access users can see the history of who changed what.
- No-op detection. If you block an IP that is already on your account-wide bot detection whitelist, the page warns you – the whitelist wins at the edge, so the block does not actually do anything.
Alongside the customer-controlled block list, Hostney runs an edge bot detection layer that scores IPs by behavior in real time and bans abusive ones automatically. Those reactive bans live in a separate table and expire on their own. The combination – your manual permanent blocks plus the platform’s automatic reactive blocks – covers both the “stop this one persistent abuser forever” case and the “stop today’s attack wave” case without you having to manage both lists.
For login-page specific protection, see the rate-limiting and challenge layers covered in how to secure WordPress login and the behavioral detection angle in Wordfence and server-level security: why you need both.
Quick checklist#
- [ ] Decide which layer fits: plugin (visibility), server (efficiency), edge (volume)
- [ ] Start with a single IP test from a separate connection before blocking ranges
- [ ] Use CIDR for known hosting-provider abuse pools, single IPs for one-off attackers
- [ ] Block countries only when you have no legitimate traffic from them
- [ ] Layer IP blocks with rate limiting and 2FA, not as the sole defense
- [ ] Prune the block list at least annually – stale entries cost legitimate users
- [ ] Back up
.htaccessor Nginx config before editing - [ ] Distinguish manual blocks from automatic edge bans (different lifetimes) and from whitelist entries (different intent)
- [ ] Verify search-engine crawlers are not caught in CIDR ranges you block
- [ ] Keep an audit trail – panel block lists do this automatically, manual config edits do not
Summary#
IP blocking in WordPress is a layer, not a complete defense. The right place to block is determined by what you are trying to stop and what visibility you need: plugin-layer when you want per-request forensics, server or panel layer when efficiency matters, edge layer when volume is the problem. Block single IPs for one-off persistent abusers, use CIDR ranges for known abuse pools, and reach for country blocks when an entire region produces no legitimate traffic. Pair IP blocking with behavioral detection – rate limiting, challenges, and edge bot detection – because pure IP lists cannot keep up with rotating attackers. And prune the list. A block list that grew unchecked for five years is mostly archaeology, not security.