Skip to content
mxmsmnvPublic

About

Advanced Traffic Firewall for ProcessWire CMS

Resources

Stars

14 stars

Watchers

2 watching

Forks

Repository files navigation

WireWall — Advanced Security & Firewall Module for ProcessWire

Author: Maxim Semenov
Website: smnv.org
Email: maxim@smnv.org

WireWall

If this project helps your work, consider supporting future development: GitHub Sponsors or smnv.org/sponsor.

Version: 1.14.0 | Requires: ProcessWire 3.0.200+, PHP 8.1+

Apple Private Relay

Allow verified Apple Private Relay is disabled by default. When explicitly enabled, only an address in Apple's official egress-IP feed is exempt from automatic proxy/VPN and datacenter classification. A browser name, ASN label, forwarded header or login URL does not grant this exception. Explicit IP/ASN blocks, emergency rules, temporary bans, rate limits, geographic restrictions, request challenges, global rules and application authentication still apply.

The feed is fetched over verified HTTPS from one fixed URL, with no redirects, a 24 MB response limit and a ten-second total timeout. No visitor IP is sent to Apple. The validated index is stored outside the document root under the existing private WireWall directory, refreshed at most once daily, and searched locally. A failed refresh is retried no more than once per hour; a verified index may remain usable for seven days, after which the normal proxy policy applies. Concurrent requests do not wait for a refresh lock. PHP cURL and a writable private directory are required. Before enabling this on a production site, prewarm and verify the index from an authorized ProcessWire CLI bootstrap:

$result = $modules->get('WireWall')->refreshAppleRelayRanges();
// Require available=true, a recent fetched_at and a nonzero range_count.

The first request after a daily refresh becomes due can spend up to ten seconds fetching the feed; the protected last-good index remains available to concurrent requests. Refresh failure never creates an allow-all fallback. The feature follows Apple's documented IP-range identification.

Enterprise-grade firewall for ProcessWire CMS with geo-blocking, bot protection, rate limiting, VPN/Proxy/Tor detection, JS challenge, and a real-time admin dashboard.


Features

Geographic Control

  • Country blocking — blacklist or whitelist entire countries (200+)
  • City blocking — block specific cities (requires GeoLite2-City)
  • Subdivision / region blocking — block states, provinces, oblasts (requires GeoLite2-City)
  • MaxMind GeoLite2 — fast local geolocation (Country, ASN, City databases)
  • HTTP API fallback — automatic fallback to ip-api.com when MaxMind unavailable
  • IPv4 / IPv6 — full support with CIDR notation

Bot Protection

  • Bad bot blocking — scrapers, scanners, vulnerability tools (wget, curl, sqlmap, nikto…)
  • AI bot blocking — GPTBot, ClaudeBot, GrokBot, Perplexity, Google-Extended…
  • Search engine control — block or allow Googlebot, Bingbot, Yandex, Baidu
  • Custom bot patterns — define your own User-Agent block list
  • Fake browser detection — advanced UA analysis, missing header checks, Chrome version heuristics
  • Headless browser detection — Puppeteer, Playwright, Selenium, PhantomJS

Security

  • Rate limiting — requests per minute per IP, configurable ban duration
  • Local-first IP intelligence — MaxMind/ASN baseline, optional IP2Proxy LITE BIN, and optional cached HTTP enrichment
  • Risk-class policies — separate allow/challenge/block actions for privacy relay, consumer VPN, datacenter proxy, Tor, unknown proxy, and residential proxy signals
  • Sensitive-route escalation — tighten classified traffic on login, checkout, forms, and API paths
  • Datacenter blocking — AWS, Google Cloud, DigitalOcean, Azure, OVH, Hetzner, Akamai…
  • ASN blocking — block entire networks by autonomous system number
  • JavaScript challenge — transparent challenge for suspicious requests
  • URL / User-Agent trigger rules — add strikes or immediately ban IPs when request URLs, query strings, or User-Agents match suspicious patterns
  • Scanner trigger preset — optional immediate bans for obvious .env, .git, wp-config, backup, and phpinfo probes
  • Bare block responses — minimal 404/410 responses that cannot execute site analytics
  • Scoped exceptions — known bots and browser compatibility rules no longer bypass unrelated protections
  • Verified search crawlers — configured Googlebot/Bingbot identities use cached forward-confirmed reverse DNS before network heuristics are relaxed
  • Verified monitor providers — configured UptimeRobot, Pingdom, StatusCake, Datadog Synthetics, and New Relic Synthetics requests are checked against official IP feeds before network heuristics are relaxed
  • IP whitelist / blacklist — exact, wildcard, and CIDR support
  • IP spoofing protection — proxy headers (CF-Connecting-IP, Incap, Sucuri) only trusted when REMOTE_ADDR belongs to the CDN's published IP ranges

Dashboard

  • Real-time statistics — blocked/allowed counts, block rate, unique IPs, active bans, cache size
  • Traffic history for AI analysis — daily JSONL files with allowed/blocked requests, URL, referer, UA, country, ASN, and decision reason
  • Protected report downloads — individual JSONL files, date-range ZIPs, last-24-hours export, and AI incident bundles from the dashboard
  • Redacted settings export — download active settings for AI-assisted review without exposing secret-like values
  • Hourly chart — blocked requests over last 24 hours (Chart.js)
  • Top reasons, countries, IPs — bar charts with counts
  • Emergency actions — reversible TTL blocks for IPs, ASNs, countries, and datacenter traffic
  • Profiles and snapshots — preview protection presets, audit changes, download/diff/restore snapshots, and import/export rules
  • Rule simulator — explain allow/block/challenge decisions without sending a real request
  • False-positive and analytics guard — review browser-like broad-rule blocks and warn about analytics-capable 404 responses
  • Crawler policy helper — generate advisory robots.txt rules while keeping firewall controls explicit
  • Optional Squad analysis — send redacted incident context to the installed Squad module and show review-only recommendations
  • Active bans — live list with TTL countdown
  • Recent events — last 50 log entries, sticky header, newest first
  • Light / dark theme — reads PW CSS variables, adapts automatically
  • Installed as separate Process module — Admin → Setup → WireWall

Management

  • 16-level priority system — precise rule ordering
  • File-based cache — scales to 1M+ IPs, no database overhead
  • Cache management UI — per-type stats, clear buttons
  • Dedicated settings storage — canonical wirewall_settings table with automatic migration and ProcessWire config fallback
  • Module-owned API integrations — installed modules can opt authenticated public routes into a namespaced WireWall exception without overwriting administrator-managed paths
  • Detailed logging — country, city, region, ASN, UA in every log entry
  • Retention and alerts — gzip rotation, retention/disk caps, rate-limited email/webhook notifications, and hookable alert payloads

Requirements

ProcessWire 3.0.200 or higher
PHP 8.1 or higher
MaxMind GeoLite2 Optional but strongly recommended
Composer Optional (required for MaxMind)
IP2Proxy LITE + SDK Optional for local proxy/privacy classification
Squad Optional for in-dashboard AI recommendations

Installation

# 1. Clone into site/modules/
git clone https://github.com/mxmsmnv/WireWall.git /path/to/site/modules/WireWall

# 2. Install in admin
Admin → Modules → Refresh → WireWall → Install

# 3. Install dashboard module
Admin → Modules → Refresh → WireWall Dashboard → Install

# 4. Configure
Admin → Modules → WireWall → Configure

See INSTALL.md for full installation instructions including MaxMind setup.


Quick Configuration

✅ Enable WireWall
✅ Enable Logging
Block Action: Bare 404 (recommended for bot/scanner protection)

Rate Limiting: 10 req/min, 60 min ban
✅ Block Bad Bots
✅ Block AI Bots
✅ Enable per-class proxy/privacy policy
Privacy Relay: Allow
Consumer VPN: Allow
Datacenter Proxy: Block
Tor: Block
IP Intelligence Mode: Local only

Exceptions → Known Bot User-Agents: Googlebot, Chrome-Lighthouse, Bingbot, UptimeRobot, Pingdom, StatusCake, DatadogSynthetics, NewRelicSynthetics (default)
Exceptions → Known Bot ASNs: 15169 (Google), 8075 (Microsoft)
Custom Block Rules → Scanner Trigger Preset: Standard
IP Control → Whitelist: only explicitly trusted office/home/service IPs

Priority System

Level Check
0 Admin area — always allowed
0.5 Trusted ProcessWire AJAX
0.7 Logged-in users — always allowed
1 IP whitelist
1.5 Emergency IP/ASN/country/datacenter TTL rule
2 Active temporary ban
2.5 URL / User-Agent trigger rules
3 Rate limiting (fixed 60-second window)
4 IP blacklist
4.5 Verify and classify scoped known-bot / compatibility exceptions
5 JS challenge (except scoped compatibility clients)
6 Local-first proxy/privacy risk class policy
7 Datacenter
8 ASN blocking
9 Global rules (known bots skip bot heuristics, not explicit rules)
10 Country blocking
10.5 City blocking
10.6 Subdivision blocking
11 Country-specific rules

MaxMind GeoLite2

WireWall works without MaxMind, but MaxMind is strongly recommended for production. Optional HTTP enrichment is disabled by default so public requests do not depend on third-party APIs.

With MaxMind Without MaxMind
Speed 0.5–2ms 100–500ms
Rate limits None Applies
City/region blocking ✅ ❌
Offline operation ✅ ❌
# Download from maxmind.com (free account)
mkdir -p /path/to/site/assets/WireWall/geoip/
cp GeoLite2-Country.mmdb GeoLite2-ASN.mmdb /path/to/site/assets/WireWall/geoip/

cd /path/to/site/assets/WireWall/
composer require geoip2/geoip2

File Structure

/site/modules/WireWall/
├── WireWall.module.php          Main firewall module
├── ProcessWireWall.module.php   Dashboard module
├── src/                         Internal service classes
│   ├── Dashboard/
│   │   └── WireWallDashboardStats.php
│   ├── WireWallMonitorProviderVerifier.php
│   ├── Storage/
│   │   ├── WireWallCacheInspector.php
│   │   ├── WireWallOperationsStore.php
│   │   ├── WireWallTrafficMaintenance.php
│   │   ├── WireWallTrafficHistoryStore.php
│   │   └── WireWallTrafficReportService.php
│   ├── Intelligence/
│   │   └── WireWallIpIntelligenceService.php
│   └── Support/
│       ├── WireWallIpMatcher.php
│       └── WireWallRuleMatcher.php
├── assets/                      Module artwork and packaged UI assets
│   ├── dashboard.css
│   ├── dashboard.js
│   └── WireWall.png
├── README.md
├── INSTALL.md
├── CONFIGURATIONS.md
└── CHANGELOG.md

/site/assets/WireWall/           Public-root data — GeoIP/vendor only
├── geoip/
│   ├── GeoLite2-Country.mmdb
│   ├── GeoLite2-ASN.mmdb
│   ├── GeoLite2-City.mmdb       optional
│   └── IP2PROXY-LITE.BIN        optional
├── vendor/                      Composer dependencies
├── composer.json
└── composer.lock

../SITE-DIRECTORY-wirewall-private/  Private data outside document root
└── traffic/
    ├── traffic-YYYY-MM-DD.jsonl    AI-friendly request history
    └── traffic-YYYY-MM-DD.jsonl.gz rotated history

Traffic History

Enable Save Traffic History in Admin → Modules → WireWall → Configure.

WireWall writes one JSON object per request to daily files:

../SITE-DIRECTORY-wirewall-private/traffic/traffic-YYYY-MM-DD.jsonl

This is separate from the ProcessWire log and is designed for later traffic analysis. Each row includes time, allow/block status, reason, IP, country, city/region when available, ASN, method, URL path/query, referer, User-Agent, and selected browser headers. Admin pages, logged-in users, CLI requests, and trusted module/API bypasses are not recorded.

Authorized users can open Admin → Setup → WireWall to:

  • download today, yesterday, the last 24 hours, or any individual daily JSONL file;
  • create a ZIP for a selected date range;
  • create an AI incident bundle containing redacted settings, traffic, a summary, and handling notes.

The traffic directory is outside the document root and its files use private filesystem permissions. Report routes require the wirewall-dashboard permission. Set $config->wireWallPrivateDataPath to an absolute path when the default sibling directory is not suitable for the host.

Settings Storage and Export

WireWall stores its canonical configuration in the wirewall_settings database table. Existing ProcessWire module configuration is imported automatically and kept synchronized as a fallback. The firewall runtime and dashboard both read through WireWall::getWireWallSettings().

Use Download settings for AI from the settings screen or dashboard for a redacted JSON snapshot. Keys that look like tokens, passwords, credentials, private keys, secrets, or API keys are replaced automatically.


Troubleshooting

Admin area blocked — WireWall never blocks the admin by design. If you cannot access admin, check server-level firewall rules, not WireWall.

Legitimate traffic blocked — use IP Whitelist only for a tightly controlled full bypass. For bots, add the UA/IP/ASN to the scoped Known Bot fields. For browser-header quirks, use Browser / Client Compatibility Exceptions. Review Admin → Setup → Logs → wirewall.

Search engines blocked — add Googlebot / Bingbot to Known Bot User-Agents and AS15169 / AS8075 to Known Bot ASNs. These rules do not bypass rate limits, triggers, network checks, geo policy, or explicit blocks.

PageSpeed Insights blocked by network rules — add Chrome-Lighthouse to Known Bot User-Agents and AS15169 to Known Bot ASNs. WireWall requires forward-confirmed reverse DNS under *.google.com before the scoped exception can skip proxy, datacenter, and ASN checks.

Synthetic monitor blocked by datacenter rules — add the service UA to Known Bot User-Agents. WireWall verifies UptimeRobot, Pingdom, StatusCake, Datadog Synthetics, and New Relic Synthetics requests against official IP feeds before letting them skip datacenter/proxy/ASN heuristics.

MaxMind not detected — verify .mmdb files are in /site/assets/WireWall/geoip/ and composer autoload exists at /site/assets/WireWall/vendor/autoload.php.

AJAX broken — add the path to Custom Trusted AJAX Paths, or use Custom API Paths for REST endpoints. Last resort: enable "Disable AJAX Protection Completely".

Behind Cloudflare / CDN — set $config->wireWallTrustProxy = true and $config->wireWallProxyHeader = 'HTTP_CF_CONNECTING_IP' in config.php.


Security Notes

WireWall is one layer of a defence-in-depth strategy. It does not replace:

  • ProcessWire / PHP updates
  • HTTPS / SSL
  • Server hardening (SSH, OS firewall)
  • Application-level protections (SQL injection, XSS)
  • DDoS mitigation at network level

License

MIT License. See LICENSE for details.

See CHANGELOG.md for version history.

About

Advanced Traffic Firewall for ProcessWire CMS

Resources

Stars

14 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages