⚠️ Status: untested. This extension is provided as-is and has not been tested in production. Please feel free to fork, modify, improve, and open pull requests.Licensed under GNU GPLv3 (see LICENSE).
Two install-ready approaches to consult the ip-block.com decision API and block matching IPs.
- Tested against: Apache httpd 2.4 (current stable 2.4.x, 2026).
- Approach A (recommended):
mod_luaaccess hook —ip_block.lua. - Approach B (LuaSec-free):
mod_rewrite+ externalRewriteMapprogram —checker_map.php.
Pick one. Both honour the same shared contract (POST /v1/check, api_key in the
body, block only on action == "block", 1s timeout, fail-open, per-IP cache,
whitelist).
| File | Approach | Purpose |
|---|---|---|
ip_block.lua |
A | mod_lua access checker hook. |
checker_map.php |
B | Persistent RewriteMap prg: decision program (PHP). |
ip-block.conf |
A+B | httpd config for both (enable one). |
- Ensure
mod_luais available (LoadModule lua_module modules/mod_lua.so). - Install LuaSec (
ssl.https) and LuaSocket (ltn12) for the Lua that mod_lua uses — e.g.luarocks install luasec luasocket. If they are missing the hook fails open and logs a warning; use Approach B instead. - Copy
ip_block.luato e.g./etc/httpd/ip-block/ip_block.lua. - Add the
SetEnv IPB_*lines and theLuaHookAccessCheckerdirective fromip-block.conf(globally or inside a<Location>). apachectl configtest && apachectl graceful.
Real client IP comes from r.useragent_ip, which respects mod_remoteip when you
configure RemoteIPHeader / RemoteIPTrustedProxy for your CDN/LB.
LoadModule rewrite_module modules/mod_rewrite.so.- Copy
checker_map.phpto/etc/httpd/ip-block/checker_map.php, make it executable (chmod +x), and confirm thephpCLI is installed. - Export config to Apache's environment (systemd unit /
/etc/sysconfig/httpd):IPB_SITE_ID,IPB_API_KEY, etc. - Uncomment the Approach B block in
ip-block.conf(and comment out A). apachectl configtest && apachectl restart(a full restart is needed so Apache launches the persistent map program).
The RewriteMap prg: program is started once and kept running; it caches decisions
in memory. The composite lookup key IP|USER_AGENT|REFERER is built in the config
so the checker can forward all three fields to the API.
| Env var | Default | Meaning |
|---|---|---|
IPB_ENABLED |
1 |
(A) Master switch. |
IPB_SITE_ID |
— | Site id. |
IPB_API_KEY |
— | API key (JSON body). |
IPB_API_URL |
https://api.ip-block.com/v1/check |
Endpoint. |
IPB_FAIL_OPEN |
1 |
1 allow on error, 0 fail closed. |
IPB_TIMEOUT_MS |
1000 |
(B) API timeout (ms). |
IPB_TIMEOUT_S |
1 |
(A) API timeout (s). |
IPB_CACHE_TTL |
300 |
Per-IP cache seconds. |
IPB_CACHE_DIR |
/tmp/ip-block-cache |
(A) disk cache dir. |
IPB_BLOCK_ACTION |
403 |
(A) 403 or redirect. |
IPB_BLOCK_REDIRECT |
https://www.ip-block.com/blocked.php |
(A) redirect target. |
IPB_BLOCK_MESSAGE |
Access denied. |
(A) 403 body. |
IPB_WHITELIST |
— | Comma-separated IPs never checked. |
- Only
{"action":"block"}blocks; anything else allows (subject tofail_open). - Infrastructure errors are never cached, so an API blip does not pin an IP.
- Whitelisted IPs are short-circuited before the cache/API.
- Approach A caches to disk (survives across processes/reloads); safe for a prefork/worker/event MPM.
- Approach B caches in the single long-lived map process's memory (fast, but reset on Apache restart). Both use a 300s default TTL.