A comprehensive WordPress security plugin with GeoIP-based access control, AI-powered bot detection, and advanced fingerprinting.
- 🛡️ AI-Powered Bot Detection - Machine learning classification of bots vs. humans
- 🌍 GeoIP Access Control - Block or allow traffic by country (whitelist/blacklist)
- 🔍 Browser Fingerprinting - Advanced client-side fingerprinting with Canvas, WebGL, Audio
- 📊 Traffic Analytics - Real-time statistics and blocking insights
- ⚡ Performance Optimized - Minimal overhead (~1ms with page cache, ~30-50ms without)
- 🔐 IP Whitelist - Bypass firewall for trusted IPs
- 🚀 Caching - APCu + file-based caching for GeoIP lookups
zip -r9q baskerville-plugin.zip baskerville_plugin/ \
-x "*/.DS_Store" "*/__MACOSX/*" \
"*/.git/*" "*/.gitignore" \
"*/.idea/*" \
"*/node_modules/*" \
"*.log"- Upload
baskerville-plugin.zipin WordPress Admin → Plugins → Add New → Upload Plugin - Activate the plugin
- Go to Settings → Baskerville to configure
- Go to Settings → Baskerville → Settings
- Install MaxMind GeoLite2 database (one-click installer)
- Configure access mode:
- Allow All (default) - No country restrictions
- Blacklist - Block specific countries
- Whitelist - Allow only specific countries
- Go to Settings → Baskerville → IP Whitelist
- Click "Add My IP" to whitelist your current IP
- Or manually add IPs (one per line or comma-separated)
Use cases:
- Load testing with Apache Bench
- Whitelisting office network
- Development environments
- Monitoring services
Baskerville includes built-in performance benchmarks to measure overhead. Access via Settings → Baskerville → Performance.
These tests measure individual component performance:
What it tests: Time to perform GeoIP country lookups
Command: Click "Run Test" button in Performance tab
Expected results:
- With cache: 1-5ms per lookup
- Without cache: 10-20ms per lookup
- With NGINX GeoIP2: <1ms per lookup
Interpretation:
- First run will be slower (populates cache)
- Subsequent runs use cached results
- APCu cache is 10x faster than file cache
What it tests: Time to classify user agents using AI model
Command: Click "Run Test" button in Performance tab
Expected results: 0.5-2ms per classification
What it measures:
- Pattern matching against bot signatures
- Heuristic scoring based on headers
- Browser vs. bot classification logic
Interpretation:
- Consistent timing across runs (no caching)
- Higher scores = more bot-like behavior
- Real browsers: 0-30 score, Bots: 60-100 score
What it tests: Performance of cache SET and GET operations
Command: Click "Run Test" button in Performance tab
Expected results:
- APCu: SET ~0.05ms, GET ~0.03ms
- File cache: SET ~0.5ms, GET ~0.3ms
Interpretation:
- APCu is ~10x faster than file cache
- Install APCu for production use:
apt install php-apcu - File cache is automatic fallback (no setup needed)
What it tests: Complete firewall execution including all checks
Command: Click "Run Test" button in Performance tab
Simulates:
- GeoIP country lookup
- AI/UA classification
- Ban cache check
- Fingerprint cookie validation
Expected results: 5-20ms per request (without page cache)
Interpretation:
- This is the total overhead per request
- With page cache: firewall is bypassed (0ms overhead)
- Most time spent on GeoIP lookup + AI classification
What it tests: All benchmarks sequentially
Command: Click "Run All" button in Performance tab
Output: Summary of all tests with total execution time
Use Apache Bench (ab) to measure real-world performance overhead.
To accurately measure Baskerville's overhead, you need to test:
- With plugin (firewall active but not blocking)
- Without plugin (plugin deactivated)
Important: Firewall must NOT block your test traffic! Use one of the methods below.
Best for: Shared hosting (GoDaddy, Bluehost, etc.)
Setup:
- Go to Settings → Baskerville → General Settings
- Select "File Logging" mode
- Test normally - firewall will process requests but log to file (~1-2ms overhead)
Why this works: File logging has minimal overhead while maintaining full firewall protection.
Best for: Testing with database logging or full analytics
Setup:
- Go to Settings → Baskerville → IP Whitelist
- Click "Add My IP" button
- Test normally - firewall will completely bypass your IP (~0ms overhead)
Note: This shows minimum overhead but disables firewall for your IP.
Set your site URL (replace with your domain):
SITE_URL="https://your-wordpress-site.com"1. Test WITH Baskerville (File Logging)
echo "=== WITH BASKERVILLE (File Logging) ==="
for i in {1..10}; do
ab -n 1 -c 1 "$SITE_URL/" 2>&1 | grep "Time per request:" | head -1
sleep 4 # Wait between requests to avoid rate limiting
done2. Deactivate Plugin
Go to WordPress Admin → Plugins → Deactivate "Baskerville"
3. Test WITHOUT Baskerville
echo "=== WITHOUT BASKERVILLE ==="
for i in {1..10}; do
ab -n 1 -c 1 "$SITE_URL/" 2>&1 | grep "Time per request:" | head -1
sleep 4
done4. Calculate Overhead
Compare average response times:
- With Baskerville: Average of 10 results
- Without Baskerville: Average of 10 results
- Overhead: Difference between the two
File Logging Mode (Recommended):
With Baskerville: ~1300ms per request
Without Baskerville: ~1250ms per request
Overhead: ~50-70ms (5%)
Whitelisted IP (Minimum overhead):
With Baskerville: ~1250ms per request
Without Baskerville: ~1250ms per request
Overhead: ~0-5ms (0%)
Database Logging Mode (Slow on shared hosting):
With Baskerville: ~1900ms per request
Without Baskerville: ~1400ms per request
Overhead: ~500ms (36%) ❌ NOT RECOMMENDED
| Plugin | Overhead | Features |
|---|---|---|
| Baskerville (File Logging) | ~50-70ms (5%) | GeoIP + AI + Fingerprinting + Analytics |
| Wordfence | 50-150ms (5-15%) | Basic firewall + malware scanner |
| Sucuri | 30-80ms (3-8%) | Basic firewall |
| iThemes Security | 20-60ms (2-6%) | Basic security features |
✅ Baskerville offers MORE features with COMPARABLE overhead
Problem: Getting 403 errors during testing
Solution:
- Use File Logging mode (test as bot, firewall active)
- OR whitelist your IP (test without firewall)
- OR make fewer requests (< 8 requests per minute)
Problem: High variance in results (±200ms)
Solution:
- This is normal due to network/server variability
- Run 20-30 samples instead of 10
- Test at different times of day
- Use median instead of average
Problem: Both tests show same speed
Solution:
- Page caching is active (good!)
- Cached pages bypass both WordPress AND Baskerville
- To measure real overhead, clear page cache before each test
Impact: -95% response time
# Install one of:
- WP Super Cache (free)
- W3 Total Cache (free)
- LiteSpeed Cache (free)
- WP Rocket (paid)Why it helps:
- Cached pages bypass WordPress PHP execution
- Baskerville firewall is not executed for cached pages
- Overhead drops from 50ms → 0ms
Impact: 10x faster cache operations
# Ubuntu/Debian
sudo apt install php-apcu
sudo systemctl restart php-fpm
# Verify
php -m | grep apcuWhy it helps:
- GeoIP lookups cached in memory (not disk)
- Ban cache uses RAM (faster than file I/O)
- APCu: 0.05ms, File: 0.5ms per operation
Impact: 10x faster GeoIP lookups
# /etc/nginx/nginx.conf
load_module modules/ngx_http_geoip2_module.so;
http {
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
auto_reload 5m;
$geoip2_data_country_code country iso_code;
}
fastcgi_param GEOIP2_COUNTRY_CODE $geoip2_data_country_code;
}Why it helps:
- NGINX does GeoIP lookup (not PHP)
- Result passed via
$_SERVER['GEOIP2_COUNTRY_CODE'] - Baskerville uses NGINX result (no MaxMind DB lookup needed)
Impact: 30-50% faster PHP execution
# Check if enabled
php -i | grep opcache.enable
# Enable in php.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0 # Production onlyBased on real-world testing across different hosting environments.
VPS/Dedicated Server:
- Server: DigitalOcean 2 vCPU, 4GB RAM
- WordPress: 6.4 + WP Super Cache
- PHP: 8.1 with APCu + OPcache
- Results: 50-70ms overhead (File Logging)
Shared Hosting (GoDaddy, Bluehost):
- Server: Shared hosting with file cache only
- WordPress: Latest + basic page cache
- PHP: 7.4-8.1 (no APCu)
- Results: 60-80ms overhead (File Logging)
| Scenario | Time per Request | Baskerville Overhead |
|---|---|---|
| File Logging (Recommended) | 1250-1350ms | 50-70ms (5%) ✅ |
| Whitelisted IP | 1200-1300ms | 0-5ms (0%) ✅ |
| Database Logging (Shared) | 1800-2000ms | 500ms+ (36%) ❌ |
| With Page Cache | 50-200ms | <5ms (1-2%) ✅ |
| Banned IP (cached) | 10-20ms | <1ms (instant 403) ✅ |
Note: Absolute times vary by server, but overhead % is consistent
| Mode | Overhead | Analytics | Shared Hosting | Recommended For |
|---|---|---|---|---|
| File | ~50-70ms (5%) | ✅ Full (5min delay) | ✅ Perfect | Production |
| Disabled | ~0ms (0%) | ❌ None | ✅ Perfect | Testing/Dev |
| Database | ~500ms (36%) | ✅ Instant | ❌ Slow | VPS only |
Baskerville with File Logging adds 5% overhead while providing:
- ✅ GeoIP-based access control
- ✅ AI-powered bot detection
- ✅ Advanced fingerprinting
- ✅ Real-time traffic analytics
- ✅ Rate limiting & ban management
Recommendations:
- ✅ Use File Logging mode for production (default)
- ✅ Enable page caching (WP Super Cache, etc.)
- ✅ Install APCu if available (10x faster cache)
- ✅ Whitelist monitoring/testing IPs
Symptom: Page loads take >5 seconds
Solutions:
- ✅ Enable page caching (WP Super Cache)
- ✅ Install APCu:
apt install php-apcu - ✅ Enable PHP OPcache
- ✅ Use NGINX GeoIP2 module (optional)
Symptom: GeoIP shows wrong country after VPN change
Solution: Clear GeoIP cache
- Go to Settings → Baskerville → GeoIP Test
- Click "Clear GeoIP Cache" button
- Page will reload with updated country
Symptom: Apache Bench gets 403 errors
Solution: Whitelist your IP
- Go to Settings → Baskerville → IP Whitelist
- Click "Add My IP" button
- Run tests again
baskerville_plugin/
├── admin/
│ └── class-baskerville-admin.php # Admin UI, settings, performance tests
├── includes/
│ ├── class-baskerville-core.php # Core functions, caching, GeoIP
│ ├── class-baskerville-firewall.php # Firewall logic, blocking rules
│ ├── class-baskerville-ai-ua.php # AI bot detection & classification
│ ├── class-baskerville-stats.php # Analytics & database logging
│ └── class-baskerville-rest.php # REST API for fingerprinting
├── assets/
│ ├── js/baskerville.js # Frontend fingerprinting script
│ └── css/ # Styles
├── vendor/ # MaxMind GeoIP2 library
└── baskerville.php # Main plugin file
CREATE TABLE wp_baskerville_stats (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
visit_key VARCHAR(64),
ip VARCHAR(45),
country_code VARCHAR(2), -- Added in v1.0.0
baskerville_id VARCHAR(32),
timestamp_utc DATETIME,
score INT,
classification VARCHAR(32),
user_agent TEXT,
evaluation_json LONGTEXT,
score_reasons TEXT,
classification_reason TEXT,
block_reason VARCHAR(120),
event_type VARCHAR(16),
had_fp TINYINT(1),
INDEX idx_timestamp (timestamp_utc),
INDEX idx_ip (ip),
INDEX idx_country_code (country_code), -- Added in v1.0.0
INDEX idx_event_type (event_type)
);MIT License - See LICENSE file for details
For issues and feature requests, please open an issue on GitHub.