> ## Content Index
> Fetch the complete content index at: https://georgetasioulis.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Your "Deny from all" is doing nothing: LiteSpeed, AIOWPS and the 5G blacklist
- URL: https://georgetasioulis.com/your-deny-from-all-is-doing-nothing-litespeed-aiowps-and-the-5g-blacklist/
- Published: 2026-09-15T04:09:13.000Z
- Updated: 2026-09-15T04:09:13.000Z
- Description: A WordPress site kept serving requests despite a Deny from all rule. Tracing LiteSpeed's handling of AIOWPS's legacy blacklist revealed the conflict and a rewrite rule restored the intended restriction.
- Author: George Tasioulis
- Tags: LiteSpeed, WordPress, Security, .htaccess, AIOWPS, Troubleshooting, cPanel

I needed to lock a WordPress site down to a single IP for a few hours. The kind of thing you do without thinking:

```apache
Order deny,allow
Deny from all
Allow from 203.0.113.10

```

Saved it at the top of `public_html/.htaccess`, reloaded, and got the homepage. Fine, wrong IP maybe. Replaced the whole thing with a bare `Deny from all`. Still 200\. Meanwhile a customer was happily editing pages in wp-admin. This is the story of why, and what the fix is, because the answer wasn't where I expected it.

## Ruling out the boring stuff

The server is a cPanel/CloudLinux box running LiteSpeed Enterprise 6.3.7, behind Cloudflare. The usual suspects, in the order I eliminated them:

**Wrong docroot.** cPanel and `httpd.conf` agreed: `/home/<user>/public_html`. The file was there, `644`, named correctly, no BOM.

**Cache.** Not it. The customer's requests were `POST /wp-admin/admin-ajax.php` with 200s, nothing LSCache would ever serve.

**Not reaching the origin.** The domlog showed real client IPs (Cloudflare's "real IP" forwarding was working) and the requests were landing on this vhost.

**`AllowOverride`.** Confirmed the vhosts had `AllowOverride All` and no account-specific userdata includes were overriding it.

**`.htaccess` not parsed at all.** This is where I made my first mistake. I assumed dropping a garbage line into the file would trigger a 500 error. I tried it and got 200 instead. On Apache that proves the file isn't being read. On LiteSpeed it proves nothing: unknown directives in `.htaccess` are logged and ignored, never fatal. I lost fifteen minutes to that.

**The server itself.** Switched the box to Apache. Immediate 403\. Switched back to LiteSpeed. 200\. Tried LiteSpeed 6.3.6\. Same. Reproduced on a second account on the same server. At this point I was fairly sure I'd found a LiteSpeed bug.

## What the debug log actually said

I turned LiteSpeed's log level to DEBUG, sent one request, and grepped for the file:

```
[HTAccess] Updating configuration file [/home/<user>/public_html/.htaccess]
[.htaccess:1]  processing directive: Deny from all.
...
[.htaccess:73] processing directive: SetEnvIfNoCase User-Agent (binlar|casper|...|zmeu) keep_out.
[.htaccess:74] processing directive: <limit GET POST PUT>.
[.htaccess:75] processing directive: Order Allow,Deny.
[.htaccess:76] processing directive: Allow from all.
[.htaccess:77] processing directive: Deny from env=keep_out.
[.htaccess:78] processing directive: </limit>.

```

So the file *was* parsed, and my `Deny from all` on line 1 *was* processed. Seventy lines later, All In One WP Security's "5G Blacklist Firewall" block does `Order Allow,Deny` / `Allow from all` / `Deny from env=keep_out`. That block is a verbatim copy of Jeff Starr's 2013 5G blacklist, and it lives in every site that has that AIOWPS feature enabled. Both of my "other vhost" tests had it too.

## Why Apache and LiteSpeed disagree

Apache's `mod_access_compat` is explicit about how `Order`/`Allow`/`Deny` are evaluated: every `Allow` line in the context forms one group, every `Deny` line forms another, the order they appear in the file doesn't matter, and for `Order Allow,Deny` a match in the Deny group rejects the request regardless of what the Allow group matched. `<Limit>` only attaches a method mask to the directives inside it; it doesn't start a new context.

So on Apache my file collapsed to: Allow = `{all}`, Deny = `{all, env=keep_out}`. Deny matches, 403\. Position irrelevant, by design.

LiteSpeed doesn't document how it evaluates these directives at all, but the behaviour is consistent and old. There's a LiteSpeed support forum thread from 2009 where someone reports that `order allow,deny` \+ `deny from all` \+ `allow from all` still grants access, and staff reply that you shouldn't use both. That's this bug in three lines, seventeen years ago. A 2015 thread about a different access-control bypass got a staff response admitting that matching Apache's exact behaviour in every scenario is hard. The model that fits every observation: LiteSpeed treats each `Order`/`Allow`/`Deny` cluster as *the* access policy for the context, and the last cluster in the file wins. AIOWPS's `Allow from all` was the last one.

Two things make this worse than an ordinary incompatibility. LiteSpeed's own security docs recommend the identical `SetEnvIf` \+ `Order allow,deny` \+ `Allow from all` \+ `Deny from env=` pattern for bot blocking, so it's not a fringe construct. And third-party compatibility tables list `Order`/`Allow`/`Deny` as "Native" without qualification. The syntax is understood. The semantics are not Apache's.

## The fix

Don't fight for position in a file that a plugin rewrites. Use the rewrite engine, which runs in an earlier phase than access control and isn't affected by anything a later `Allow from all` says:

```apache
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^203\.0\.113\.10$
RewriteRule ^ - [F,L]

```

Behind Cloudflare this relies on LiteSpeed's "Use Client IP in Header" being on for Cloudflare's ranges, otherwise `REMOTE_ADDR` is a Cloudflare edge and you lock yourself out too. The domlog showing real visitor IPs is your confirmation.

It worked first try on LiteSpeed, and it works identically on Apache. Next time I need to restrict access to a site with 5G rules in its `.htaccess`, I’ll go straight to rewrites.

For the plugin side: 5G is legacy. AIOWPS moved 6G into its PHP firewall years ago and 6G doesn't touch `.htaccess`. Turn 5G off. Note that AIOWPS 5.4.1 (May 2025) fixed a bug where the 5G toggle was inverted, enabling it removed the rules and disabling it added them, so a customer who believes 5G is off may still be carrying the block.

## What I'd tell past me

1. On LiteSpeed, the garbage-line test is worthless. Test with a simple redirect and check whether it takes effect before concluding that the file isn’t being read.
2. Switching the server binary was the right instinct and gave the decisive signal in two minutes. Do it earlier.
3. `Deny from all` at the top of a WordPress `.htaccess` is not a safe assumption on LiteSpeed. Read the whole file, or use a rewrite.
4. LiteSpeed's DEBUG log lists every `.htaccess` directive it processes, with line numbers. It's the fastest way to see what the server actually loaded versus what you think you wrote.

The takeaway for anyone running LiteSpeed with WordPress security plugins: every legacy `Order`/`Allow`/`Deny` block in the file is competing for a single slot, and the plugin that wrote last gets it.