luci-app-authshield
Multi-service login intrusion prevention for OpenWrt (LuCI + Dropbear)
Author: iv7777 hongba@rocketmail.com
Version: 1.17
Date: 2025-11-08
License: MIT
📦 Overview
AuthShield enhances OpenWrt's security by automatically banning IPs that repeatedly fail login attempts within a short window — covering both LuCI web interface and Dropbear SSH.
- Works without modifying LuCI itself.
- Lightweight: pure shell + nftables.
- Auto-unbans IPs after timeout.
- Supports IPv4 and IPv6.
- Optional: ignore private IPs (LAN, loopback, link-local).
- Circuit Breaker: Blocks WAN access to management ports when distributed attacks are detected.
⚙️ Default Configuration
| Option | Default | Description |
|---|---|---|
enabled |
1 | Enable or disable AuthShield |
threshold |
5 | Number of failed attempts before ban |
window |
10 | Time window (seconds) to count failures |
penalty |
60 | Ban duration (seconds) |
ports |
80 443 | Protected ports |
watch_dropbear |
0 | Also monitor SSH login failures |
ignore_private_ip |
1 | Skip bans for private/local IPs |
| Escalation | ||
escalate_enable |
1 | Enable escalation for repeat offenders |
escalate_threshold |
5 | Bans within window to trigger escalation |
escalate_window |
3600 | Escalation tracking window (1 hour) |
escalate_penalty |
86400 | Escalation ban duration (24 hours) |
| Global Rule | ||
global_enable |
1 | Enable long-term ban tracking |
global_threshold |
60 | Failures within window for global ban |
global_window |
43200 | Global tracking window (12 hours) |
global_penalty |
86400 | Global ban duration (24 hours) |
| Circuit Breaker | ||
circuit_enable |
1 | Enable circuit breaker protection |
circuit_threshold |
120 | Total failures to trigger WAN lockdown |
circuit_window |
43200 | Circuit breaker memory window (12 hours) |
circuit_penalty |
3600 | WAN block duration (1 hour) |
Configuration file: /etc/config/authshield
🔒 Circuit Breaker Feature
What It Does
The circuit breaker provides defense against distributed attacks where multiple IPs coordinate to probe your system, each staying under individual ban thresholds.
Example scenario:
- IP A: 60 failures over 6 hours (under 5/10s threshold - not banned)
- IP B: 30 failures over 3 hours (under threshold - not banned)
- IP C: 40 failures over 2 hours (under threshold - not banned)
- Total: 130 failures → Circuit breaker triggers at 120 → All WAN access blocked
How It Works
- Monitors total failures across all attacking IPs
- Triggers at threshold (default: 120 failures in 12 hours)
- Blocks WAN ports for the penalty duration (default: 1 hour)
- Auto-unlocks via nftables timeout after penalty expires
Important Behavior: "Memory Effect"
The circuit breaker has a 12-hour sliding window (default) that creates a "memory effect":
Attack starts → 120 failures → CIRCUIT LOCKS
After 1 hour → nftables timeout → CIRCUIT UNLOCKS
Attacker tries again → Count still ~120 in memory → IMMEDIATE RE-LOCK
Cycle repeats every hour until...
12 hours pass → Memory clears → System fully reset
This is intentional and beneficial:
- Immediate defense: 1-hour hard block
- Persistent defense: Re-locks on any attempt for up to 12 hours
- Effective result: Distributed attackers face extended lockout without manual intervention
Tuning Recommendations
High Security (Strict):
circuit_threshold = 60 # Trigger faster
circuit_window = 86400 (24h) # Longer memory
circuit_penalty = 7200 (2h) # Longer blocks
Balanced (Default):
circuit_threshold = 120 # Moderate sensitivity
circuit_window = 43200 (12h) # 12-hour memory
circuit_penalty = 3600 (1h) # 1-hour blocks
Permissive (Public Services):
circuit_threshold = 300 # More tolerant
circuit_window = 21600 (6h) # Shorter memory
circuit_penalty = 1800 (30m) # Quick recovery
🧩 LuCI Web UI
Menu path: System → AuthShield
Displays the following options:
General Tab
- Enable / Disable
- Failures threshold
- Window (seconds)
- Penalty (seconds)
- Protected ports
- Monitor Dropbear SSH
- Ignore private IP ranges
- Currently banned IPs (with live countdown)
Advanced Tab
- Escalation settings (repeat offenders get 24h bans)
- Global rule settings (long-term tracking)
Circuit Breaker Tab
- Enable circuit breaker
- Circuit threshold (total failures across all IPs)
- Circuit window (memory duration)
- Circuit block duration (WAN lockout time)
- Current circuit breaker status (locked/unlocked with countdown)
🔧 Installation
1. Copy manually
# Copy contents to router
scp -r root/ root@router:/
scp -r luasrc/ root@router:/usr/lib/lua/
scp -r po/ root@router:/usr/lib/lua/luci/i18n/
# Apply setup
ssh root@router '/etc/uci-defaults/99-authshield-setup'
2. Build with OpenWrt SDK
Copy this folder into package/feeds/luci/ and build with:
make package/luci-app-authshield/compile V=s
🧠 Verification
To see current banned IPs:
nft list set inet fw4 authshield_penalty_v4
nft list set inet fw4 authshield_penalty_v6
To check circuit breaker status:
cat /var/run/authshield.circuit
# Format: <locked> <expires_timestamp> <failure_count>
# Example: 1 1699459200 125 (locked, expires at timestamp, 125 failures)
To check service status:
/etc/init.d/authshield status
To reload firewall rules:
/etc/init.d/firewall reload
🔍 Understanding Log Patterns
Multiple Ban Messages
You may see multiple ban messages for the same IP within seconds:
03:14:24 authshield: Banned IP 99.229.69.95 for 60s
03:14:25 authshield: Banned IP 99.229.69.95 for 60s
03:14:25 authshield: Banned IP 99.229.69.95 for 60s
This is normal and provides intelligence:
- Each ban message represents ~5 failed login attempts
- Multiple messages = attacker using parallel connections
- 3 bans = ~15 parallel connections (sophisticated attack)
- 1 ban = single-threaded script (simple attack)
The IP is still blocked - the firewall is working correctly. The duplicate messages are due to packets that were already in the TCP buffer before the ban took effect. This actually helps you identify the sophistication of the attack.
🌐 Translation
Simplified Chinese (简体中文) translation is included:
po/zh_Hans/luci-app-authshield.po
LuCI will automatically display the Chinese interface if your browser locale is Simplified Chinese.
🧱 Technical Notes
Architecture
- Log monitoring:
logread -fprovides efficient, non-blocking live log monitoring - Sliding windows: awk-based in-memory counters for precise threshold detection
- Ban enforcement: nftables sets with automatic timeout - no cron jobs needed
- Circuit breaker: Port-based blocking using nftables timeout feature
- Zero LuCI modifications: Works with standard rpcd/uhttpd authentication
Performance
- Memory usage: ~2MB (monitoring daemon + awk)
- CPU impact: Negligible (event-driven, not polling)
- Log throughput: Can handle 1000+ events/second
- Scalability: Tested with 100+ concurrent attackers
Compatibility
- OpenWrt 22.03+ (nftables/fw4)
- Works with both
rpcdanduhttpdauthentication - Does not interfere with normal LuCI sessions
- Ideal for snapshot or modern OpenWrt builds with nftables
📊 Attack Pattern Analysis
AuthShield logs reveal attack characteristics:
| Pattern | Indicator | Threat Level |
|---|---|---|
| Single ban | 1 ban message | Low - script kiddie |
| 3-5 bans | Multiple parallel connections | Medium - semi-sophisticated |
| 10+ bans | High parallelism | High - professional tool (Hydra/Medusa) |
| Circuit breaker trigger | Distributed attack | Critical - coordinated threat |
Use this information to:
- Identify serious threats requiring investigation
- Adjust thresholds for your environment
- Document attack patterns for security analysis
🐛 Troubleshooting
Circuit breaker not triggering
- Check
/var/run/authshield.circuitexists - Verify
circuit_enable = 1in config - Ensure failures are from WAN IPs (not private/local)
- Review
logread | grep authshieldfor circuit activation messages
Too many false positives
- Increase
circuit_threshold(e.g., 200 instead of 120) - Decrease
circuit_windowfor faster memory clearance - Check for legitimate traffic patterns in logs
Circuit stays locked
- Check remaining time:
cat /var/run/authshield.circuit - Verify nftables timeout:
nft list set inet fw4 authshield_circuit_ports - Manual unlock:
nft flush set inet fw4 authshield_circuit_ports
📜 License
This project is licensed under the MIT License.
© 2025 iv7777 hongba@rocketmail.com
🔄 Changelog
v1.17 (2025-11-08)
- Removed non-functional auto-unlock threshold feature
- Documented circuit breaker "memory effect" behavior
- Enhanced circuit breaker status display
- Improved Chinese translations
- Added attack pattern analysis documentation
v1.16 (2025-10-30)
- Added circuit breaker feature for distributed attack protection
- Improved circuit breaker with port-based nftables timeout
- Added live countdown display for banned IPs
- Enhanced LuCI interface with circuit breaker status
v1.0-1.15
- Initial releases with basic ban functionality
- Added escalation and global rule features