shieldapp / laravel-shield
A Laravel package for website health monitoring, IP threat detection, traffic analysis and auto-banning.
Requires
- php: ^8.1
- guzzlehttp/guzzle: ^7.0
- illuminate/bus: ^10.0|^11.0
- illuminate/console: ^10.0|^11.0
- illuminate/database: ^10.0|^11.0
- illuminate/http: ^10.0|^11.0
- illuminate/notifications: ^10.0|^11.0
- illuminate/queue: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
Requires (Dev)
- orchestra/testbench: ^8.0
- phpunit/phpunit: ^10.0
This package is not auto-updated.
Last update: 2026-05-09 10:25:30 UTC
README
A production-grade Laravel package for IP threat detection & auto-banning, external health monitoring, real-time traffic analysis, and multi-channel alerting โ with a beautiful live dashboard.
Features
- ๐ซ IP auto-banning โ sliding-window rate limiting; automatically blocks IPs that exceed configurable RPM thresholds
- ๐ก External health checks โ uptime, SSL certificate expiry, DNS, response time, security headers, domain expiry
- ๐ Live dashboard โ real-time traffic map, threat level meter, audit log, ban management, and site monitors in one glassmorphism UI
- ๐ Multi-channel alerts โ Email, Slack (Block Kit), and WhatsApp (via Twilio) with per-channel cooldowns to prevent flooding
- ๐๏ธ Audit log โ full trail of every DETECT, WARN, AUTO-BAN, BAN, UNBAN, and BLOCKED event
- โก Redis-first architecture โ all per-request counting stays in Redis; DB writes only for significant events
- ๐ Async logging โ optional queue-based DB writes to keep your request cycle fast
- ๐ค Agent mode โ report CPU, RAM, disk, and queue stats from any server back to a central Shield instance
- ๐งน Auto-pruning โ configurable retention windows automatically keep your tables lean
- ๐ Security hardened โ timing-safe API key comparison, cache-key injection prevention, SSL verification configurable
Requirements
- PHP 8.1+
- Laravel 10 or 11
- A cache driver (Redis recommended for production;
arrayworks for testing)
Installation
composer require shieldapp/laravel-shield php artisan shield:install
shield:install publishes the config, runs migrations, and prints a setup checklist.
Configuration
Publish the config file independently if needed:
php artisan vendor:publish --tag=shield-config
Core .env variables
# --- Core --- SHIELD_ENABLED=true SHIELD_DASHBOARD_PATH=shield # URL path, e.g. "admin/shield" SHIELD_WHITELIST=127.0.0.1,::1 # Comma-separated IPs never blocked # --- Thresholds --- SHIELD_AUTO_BAN_RPM=500 # Auto-ban above this req/min SHIELD_WARN_RPM=200 # Log WARN event above this req/min SHIELD_BAN_DURATION= # null = permanent; or minutes # --- External checks --- SHIELD_SSL_WARN_DAYS=14 # Alert when SSL expires within N days SHIELD_DOMAIN_WARN_DAYS=30 # Alert when domain expires within N days SHIELD_RESPONSE_WARN_MS=1500 # Alert when response time exceeds N ms SHIELD_VERIFY_SSL=true # Set false only in local dev # --- Async logging (optional, requires a queue worker) --- SHIELD_ASYNC_LOGGING=false # true = DB writes happen on a queue SHIELD_QUEUE=shield # Queue name for async log jobs # --- Data retention --- SHIELD_LOG_RETENTION_DAYS=30 SHIELD_CHECK_RETENTION_DAYS=7 SHIELD_BAN_RETENTION_DAYS=90
Dashboard
Visit /shield in your browser (protected by web + auth middleware by default).
https://yourapp.com/shield
Customise the path and middleware in config/shield.php:
'dashboard_path' => 'admin/shield', 'dashboard_middleware' => ['web', 'auth', 'role:admin'],
Dashboard features
| Feature | Description |
|---|---|
| Threat level meter | Live LOW / MEDIUM / HIGH / CRITICAL indicator based on peak RPM vs your ban threshold |
| Live traffic table | Per-IP request counts, user agents, last-seen timestamps โ updates every 4 s |
| Risk badges | Colour-coded LOW / MEDIUM / HIGH / CRITICAL per IP row |
| Stat cards | Active bans, auto-bans, log entries, and monitor count at a glance |
| Site monitors | Add any URL and see uptime, SSL, response time, and individual check badges |
| Audit log | Filterable full event trail with action colours |
| Ban / unban | Modal to add manual bans; one-click unban from the bans table |
| Toast notifications | In-browser alerts when new auto-bans are detected between polls |
Multi-Channel Alerts
Alerts fire for: IP auto-ban, site down, SSL expiry.
All channels are optional and independent โ configure only the ones you need.
SHIELD_ALERT_EMAIL=admin@yoursite.com
Slack
Create an Incoming Webhook in your Slack workspace:
- Go to api.slack.com/apps โ Create App โ Incoming Webhooks
- Activate Incoming Webhooks โ Add to channel
- Copy the webhook URL
SHIELD_SLACK_WEBHOOK=https://hooks.slack.com/services/T.../B.../xxx
Alerts arrive as rich Block Kit messages with colour-coded headers, IP/URL detail fields, and a View Dashboard button.
WhatsApp (via Twilio)
- Sign up at twilio.com
- Enable the WhatsApp Sandbox (or a dedicated WhatsApp sender) in your Twilio console
- Note your Account SID and Auth Token
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx TWILIO_AUTH_TOKEN=your_auth_token SHIELD_WHATSAPP_FROM=whatsapp:+14155238886 # Twilio sandbox number (or your approved number) SHIELD_WHATSAPP_TO=whatsapp:+447700000000 # The number that receives alerts
Alert cooldown
To prevent flooding, the same alert for the same IP/URL won't re-fire until the cooldown window expires:
// config/shield.php 'alert_cooldown_minutes' => 15,
Async Logging (Queue)
By default every significant event (WARN, BAN, BLOCKED) is written to the database synchronously. Enable async mode to push DB writes onto a queue worker:
SHIELD_ASYNC_LOGGING=true SHIELD_QUEUE=shield
Start a queue worker on the shield queue:
php artisan queue:work --queue=shield
Note: The
shield:active_ipsRedis map used by the live dashboard is always updated synchronously regardless of this setting โ async mode only affects DB writes.
Artisan Commands
# Run all health checks now (also prunes old data) php artisan shield:check # Check a specific URL php artisan shield:check --url=https://example.com # Print daily traffic + health summary report php artisan shield:report
Scheduler
Add the Laravel scheduler to your crontab and Shield registers itself automatically:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
Shield registers:
| Command | Frequency |
|---|---|
shield:check |
Every 5 minutes |
shield:report |
Daily at 08:00 |
Pruning of old traffic logs, check results, and expired bans runs inside shield:check.
Middleware
The IpShield middleware is registered automatically for all HTTP routes via the service provider.
You can also apply it selectively:
// routes/web.php Route::middleware(['shield'])->group(function () { // ... });
Or exclude specific routes from Shield checks by IP-whitelisting in your config.
Agent Mode
Install Shield on any client server. It will POST CPU, RAM, disk, queue, and error stats back to your central Shield dashboard every 5 minutes.
# On the remote (agent) server SHIELD_AGENT_ENABLED=true SHIELD_AGENT_ENDPOINT=https://your-shield-saas.com/shield/agent/report SHIELD_AGENT_KEY=your-secret-api-key
On the receiving (hub) server, set the same key:
SHIELD_AGENT_API_KEY=your-secret-api-key
What can be monitored?
| Check | URL-only | With agent |
|---|---|---|
| Uptime | โ | โ |
| Response time | โ | โ |
| SSL certificate | โ | โ |
| DNS records | โ | โ |
| Security headers | โ | โ |
| Domain expiry | โ | โ |
| CPU / RAM / disk | โ | โ |
| Queue depth | โ | โ |
| Error log count | โ | โ |
| IP traffic & bans | Own server only | โ |
Data Retention
Shield automatically prunes old records during every shield:check run:
| Table | Default retention | Config key |
|---|---|---|
shield_traffic_logs |
30 days | shield.log_retention_days |
shield_check_results |
7 days | shield.check_retention_days |
shield_ip_bans (expired) |
90 days | shield.ban_retention_days |
Override in .env:
SHIELD_LOG_RETENTION_DAYS=14 SHIELD_CHECK_RETENTION_DAYS=3 SHIELD_BAN_RETENTION_DAYS=60
Testing
composer test
The test suite uses Orchestra Testbench with an in-memory SQLite database and the array cache driver โ no Redis or MySQL required.
Security
If you discover a security vulnerability please email sunilluhanaa@gmail.com rather than opening a public issue.
License
The MIT License (MIT). See LICENSE.md for details.