feat(interceptor,ddos): Add Insider WAF pillar and DDoS hardening profile
InterceptoR Insider WAF (6th pillar):
- RPCD: get_insider_waf_status() tracking LAN client threats
- Dashboard: 🔒 Insider WAF card with threat stats
- CrowdSec scenarios for insider threats:
- C2 beacon, exfiltration, DNS tunneling, lateral movement
- Cryptominer, IoT botnet, suspicious TLDs, high volume
DDoS Protection Hardening:
- Config Advisor: 8 DDoS checks (SYN cookies, conntrack, RP filter,
ICMP rate, CrowdSec http-dos, HAProxy maxconn, mitmproxy WAF, Vortex)
- ANSSI rules: New "ddos" category with remediation steps
- Documentation: DOCS/DDOS-PROTECTION.md with full guide
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
1d084b1439
commit
c69ae43961
@ -1218,3 +1218,54 @@ _Last updated: 2026-02-11_
|
||||
- `out`: LAN→Internet transparent proxy (port 8888/8089)
|
||||
- `in`: WAF/services upstream proxy (port 8889/8090)
|
||||
- README updated with multi-instance documentation
|
||||
|
||||
51. **InterceptoR Plan Verification Complete (2026-02-12)**
|
||||
- Verified all 5 phases of InterceptoR "Gandalf Proxy" plan are fully implemented:
|
||||
- Phase 1: WPAD Safety Net — `setup_wpad_enforce()` in `network-tweaks-sync`
|
||||
- Phase 2: Cookie Tracker — `secubox-cookie-tracker` + `luci-app-cookie-tracker`
|
||||
- Phase 3: API Failover — `cdn-cache` UCI config + `99-cdn-offline` hotplug
|
||||
- Phase 4: CrowdSec Scenarios — 8 scenarios in `secubox-mitmproxy-threats.yaml`
|
||||
- Phase 5: Unified Dashboard — `luci-app-interceptor` with 5-pillar status
|
||||
- CrowdSec scenarios include: SQLi, XSS, command injection, SSRF, CVE exploitation, bot scanners, shell hunters
|
||||
- Plan file updated to reflect completion status
|
||||
|
||||
52. **InterceptoR Insider WAF - 6th Pillar (2026-02-12)**
|
||||
- Added Insider WAF as 6th pillar to InterceptoR for LAN client threat detection.
|
||||
- **RPCD handler updates** (`luci.interceptor`):
|
||||
- New `get_insider_waf_status()` function tracking insider threats, blocked clients, exfil attempts, DNS anomalies
|
||||
- Health score recalculated for 6 pillars (17 points each)
|
||||
- Detects threats from internal IPs (192.168.x.x, 10.x.x.x, 172.16-31.x.x)
|
||||
- **LuCI dashboard updates** (`overview.js`):
|
||||
- New "Insider WAF" pillar card with 🔒 icon
|
||||
- Stats: insider threats, blocked clients, exfil attempts, DNS anomalies
|
||||
- Description: "LAN threat detection"
|
||||
- **CrowdSec insider threat scenarios** (`secubox-insider-threats.yaml`):
|
||||
- `secubox/insider-c2-beacon` — C2 beacon detection from LAN hosts
|
||||
- `secubox/insider-exfiltration` — Data exfiltration attempts (large uploads, base64, DNS)
|
||||
- `secubox/insider-dns-tunnel` — DNS tunneling/DGA from internal hosts
|
||||
- `secubox/insider-lateral-movement` — Lateral movement within LAN
|
||||
- `secubox/insider-cryptominer` — Cryptominer activity detection
|
||||
- `secubox/insider-iot-botnet` — IoT botnet C2 (Mirai, Gafgyt, Mozi)
|
||||
- `secubox/insider-bad-tld` — Suspicious outbound to high-risk TLDs
|
||||
- `secubox/insider-high-volume` — Unusual high-volume outbound traffic
|
||||
- Updated `secubox-app-crowdsec-custom` Makefile to install new scenarios
|
||||
|
||||
53. **DDoS Protection Hardening Profile (2026-02-12)**
|
||||
- **Config Advisor DDoS checks** (`checks.sh`):
|
||||
- DDOS-001: SYN cookies enabled
|
||||
- DDOS-002: Connection tracking limit (65536+)
|
||||
- DDOS-003: CrowdSec http-dos collection installed
|
||||
- DDOS-004: ICMP rate limiting
|
||||
- DDOS-005: Reverse path filtering (anti-spoofing)
|
||||
- DDOS-006: HAProxy connection limits (maxconn)
|
||||
- DDOS-007: mitmproxy WAF active (L7 flood detection)
|
||||
- DDOS-008: Vortex DNS firewall (botnet C2 blocking)
|
||||
- **ANSSI rules JSON** (`anssi-rules.json`):
|
||||
- New "ddos" category with 8 rules and remediation steps
|
||||
- **Documentation** (`DOCS/DDOS-PROTECTION.md`):
|
||||
- Complete DDoS protection guide
|
||||
- Layer-by-layer explanation (L3/L4/L7/DNS)
|
||||
- Configuration examples for all components
|
||||
- Quick hardening checklist
|
||||
- Monitoring commands during attacks
|
||||
- Limitations and upstream protection options (Cloudflare, etc.)
|
||||
|
||||
335
DOCS/DDOS-PROTECTION.md
Normal file
335
DOCS/DDOS-PROTECTION.md
Normal file
@ -0,0 +1,335 @@
|
||||
# SecuBox DDoS Protection Guide
|
||||
|
||||
SecuBox provides **multi-layered DDoS protection** suitable for home, SOHO, and SMB deployments. This document describes the protection mechanisms and configuration options.
|
||||
|
||||
## Protection Layers Overview
|
||||
|
||||
| Layer | Component | Attack Types Mitigated |
|
||||
|-------|-----------|------------------------|
|
||||
| **L3** | OpenWrt Firewall | SYN flood, ICMP flood, IP spoofing |
|
||||
| **L4** | nftables/iptables | Connection floods, port scans |
|
||||
| **L4** | CrowdSec | Distributed attack detection |
|
||||
| **L7** | HAProxy | HTTP flood, slowloris, request bombing |
|
||||
| **L7** | mitmproxy WAF | Application-layer floods, bot attacks |
|
||||
| **DNS** | Vortex Firewall | Botnet C2, DNS amplification |
|
||||
| **Intel** | CrowdSec CAPI | Shared threat intelligence (50k+ nodes) |
|
||||
|
||||
## Layer 3/4 Protection
|
||||
|
||||
### SYN Flood Protection
|
||||
|
||||
OpenWrt firewall includes SYN cookies and SYN flood protection:
|
||||
|
||||
```bash
|
||||
# Check current status
|
||||
cat /proc/sys/net/ipv4/tcp_syncookies
|
||||
|
||||
# Enable via UCI
|
||||
uci set firewall.@defaults[0].synflood_protect='1'
|
||||
uci commit firewall
|
||||
/etc/init.d/firewall restart
|
||||
```
|
||||
|
||||
### Connection Tracking Limits
|
||||
|
||||
Increase conntrack table size for high-traffic scenarios:
|
||||
|
||||
```bash
|
||||
# Check current limits
|
||||
cat /proc/sys/net/netfilter/nf_conntrack_max
|
||||
cat /proc/sys/net/netfilter/nf_conntrack_count
|
||||
|
||||
# Increase limit (add to /etc/sysctl.conf)
|
||||
echo "net.netfilter.nf_conntrack_max=131072" >> /etc/sysctl.conf
|
||||
sysctl -p
|
||||
```
|
||||
|
||||
### Anti-Spoofing (Reverse Path Filter)
|
||||
|
||||
```bash
|
||||
# Enable RP filter
|
||||
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
|
||||
|
||||
# Persist in /etc/sysctl.conf
|
||||
echo "net.ipv4.conf.all.rp_filter=1" >> /etc/sysctl.conf
|
||||
```
|
||||
|
||||
### ICMP Rate Limiting
|
||||
|
||||
```bash
|
||||
# Limit ICMP responses (prevent ping flood amplification)
|
||||
echo 1000 > /proc/sys/net/ipv4/icmp_ratelimit
|
||||
echo 50 > /proc/sys/net/ipv4/icmp_msgs_per_sec
|
||||
```
|
||||
|
||||
### Drop Invalid Packets
|
||||
|
||||
```bash
|
||||
uci set firewall.@defaults[0].drop_invalid='1'
|
||||
uci commit firewall
|
||||
/etc/init.d/firewall restart
|
||||
```
|
||||
|
||||
## CrowdSec Protection
|
||||
|
||||
CrowdSec provides behavior-based detection and collaborative threat intelligence.
|
||||
|
||||
### Install DDoS Collections
|
||||
|
||||
```bash
|
||||
# HTTP flood detection
|
||||
cscli collections install crowdsecurity/http-dos
|
||||
|
||||
# Base HTTP attack detection
|
||||
cscli collections install crowdsecurity/base-http-scenarios
|
||||
|
||||
# Nginx/HAProxy specific
|
||||
cscli collections install crowdsecurity/nginx
|
||||
cscli collections install crowdsecurity/haproxy
|
||||
|
||||
# Restart to apply
|
||||
/etc/init.d/crowdsec restart
|
||||
```
|
||||
|
||||
### CrowdSec Scenarios for DDoS
|
||||
|
||||
| Scenario | Description | Ban Duration |
|
||||
|----------|-------------|--------------|
|
||||
| `crowdsecurity/http-dos-swithcing-ua` | Rapid user-agent switching | 4h |
|
||||
| `crowdsecurity/http-generic-bf` | Generic HTTP bruteforce | 4h |
|
||||
| `crowdsecurity/http-slow-bf` | Slowloris-style attacks | 4h |
|
||||
| `crowdsecurity/http-crawl-non_statics` | Aggressive crawling | 4h |
|
||||
|
||||
### View Active Protections
|
||||
|
||||
```bash
|
||||
# List installed scenarios
|
||||
cscli scenarios list
|
||||
|
||||
# View active decisions (bans)
|
||||
cscli decisions list
|
||||
|
||||
# View real-time metrics
|
||||
cscli metrics
|
||||
```
|
||||
|
||||
## HAProxy Rate Limiting
|
||||
|
||||
HAProxy provides connection and request rate limiting for published services.
|
||||
|
||||
### Global Connection Limits
|
||||
|
||||
Add to `/etc/haproxy/haproxy.cfg`:
|
||||
|
||||
```haproxy
|
||||
global
|
||||
maxconn 4096
|
||||
|
||||
defaults
|
||||
maxconn 2000
|
||||
timeout connect 5s
|
||||
timeout client 30s
|
||||
timeout server 30s
|
||||
```
|
||||
|
||||
### Per-Backend Rate Limiting
|
||||
|
||||
```haproxy
|
||||
frontend https_in
|
||||
bind *:443 ssl crt /etc/haproxy/certs/
|
||||
|
||||
# Rate limit: 100 requests/10s per IP
|
||||
stick-table type ip size 100k expire 30s store http_req_rate(10s)
|
||||
http-request track-sc0 src
|
||||
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
|
||||
|
||||
# Slow down aggressive clients
|
||||
http-request tarpit if { sc_http_req_rate(0) gt 50 }
|
||||
```
|
||||
|
||||
### Connection Queue (Absorb Spikes)
|
||||
|
||||
```haproxy
|
||||
backend myapp
|
||||
server app1 192.168.255.1:8080 maxconn 100 maxqueue 500
|
||||
```
|
||||
|
||||
## mitmproxy L7 WAF
|
||||
|
||||
mitmproxy inspects HTTP/HTTPS traffic and detects application-layer attacks.
|
||||
|
||||
### Flood Detection
|
||||
|
||||
The `secubox_analytics.py` addon detects:
|
||||
- Request rate spikes per IP
|
||||
- Abnormal request patterns
|
||||
- Bot signatures
|
||||
- Automated scanning tools
|
||||
|
||||
### Enable WAF
|
||||
|
||||
```bash
|
||||
# Start mitmproxy container
|
||||
/etc/init.d/mitmproxy start
|
||||
|
||||
# Check status
|
||||
mitmproxyctl status
|
||||
```
|
||||
|
||||
### View Detected Threats
|
||||
|
||||
```bash
|
||||
# Recent threats
|
||||
tail -f /srv/mitmproxy/threats.log
|
||||
|
||||
# Threat statistics
|
||||
mitmproxyctl stats
|
||||
```
|
||||
|
||||
## Vortex DNS Firewall
|
||||
|
||||
Vortex blocks known botnet C2 domains and malware distribution sites at the DNS level.
|
||||
|
||||
### Enable Protection
|
||||
|
||||
```bash
|
||||
# Update threat intelligence feeds
|
||||
vortex-firewall intel update
|
||||
|
||||
# Start protection
|
||||
vortex-firewall start
|
||||
|
||||
# Check stats
|
||||
vortex-firewall stats
|
||||
```
|
||||
|
||||
### Blocked Categories
|
||||
|
||||
- Malware distribution domains
|
||||
- Botnet C2 servers (Mirai, Gafgyt, etc.)
|
||||
- Phishing domains
|
||||
- Cryptominer pools
|
||||
|
||||
## InterceptoR Insider WAF
|
||||
|
||||
The InterceptoR Insider WAF detects DDoS participation from compromised LAN devices:
|
||||
|
||||
- **C2 beacon detection** - Identifies infected devices calling home
|
||||
- **DNS tunneling** - Detects data exfiltration via DNS
|
||||
- **IoT botnet patterns** - Mirai, Gafgyt, Mozi signatures
|
||||
- **Cryptominer activity** - Mining pool connections
|
||||
|
||||
### Check Insider Threats
|
||||
|
||||
```bash
|
||||
# View InterceptoR status
|
||||
ubus call luci.interceptor status
|
||||
|
||||
# Check for insider threats in logs
|
||||
grep "insider" /srv/mitmproxy/threats.log
|
||||
```
|
||||
|
||||
## Config Advisor DDoS Profile
|
||||
|
||||
Run the DDoS-specific compliance check:
|
||||
|
||||
```bash
|
||||
# Run all checks including DDoS
|
||||
config-advisorctl check
|
||||
|
||||
# Run DDoS checks only
|
||||
config-advisorctl check --category ddos
|
||||
|
||||
# Auto-remediate DDoS issues
|
||||
config-advisorctl remediate --category ddos
|
||||
```
|
||||
|
||||
### DDoS Check Rules
|
||||
|
||||
| Rule ID | Check | Severity |
|
||||
|---------|-------|----------|
|
||||
| DDOS-001 | SYN cookies enabled | High |
|
||||
| DDOS-002 | Connection tracking limit | Medium |
|
||||
| DDOS-003 | CrowdSec http-dos installed | High |
|
||||
| DDOS-004 | ICMP rate limiting | Medium |
|
||||
| DDOS-005 | Reverse path filtering | High |
|
||||
| DDOS-006 | HAProxy connection limits | Medium |
|
||||
| DDOS-007 | mitmproxy WAF active | Medium |
|
||||
| DDOS-008 | Vortex DNS firewall | Medium |
|
||||
|
||||
## Limitations
|
||||
|
||||
SecuBox is designed for home/SMB scale. It **cannot**:
|
||||
|
||||
- Absorb volumetric attacks larger than your WAN bandwidth
|
||||
- Provide Anycast/CDN distribution
|
||||
- Act as a scrubbing service
|
||||
|
||||
### For Serious DDoS Protection
|
||||
|
||||
Consider adding upstream protection:
|
||||
|
||||
1. **Cloudflare** - Free tier includes basic DDoS protection
|
||||
2. **Cloudflare Spectrum** - TCP/UDP proxy for non-HTTP services
|
||||
3. **AWS Shield** - If hosting on AWS
|
||||
4. **OVH Anti-DDoS** - If using OVH hosting
|
||||
|
||||
### Hybrid Setup
|
||||
|
||||
```
|
||||
Internet → Cloudflare (L3/L4/L7 scrubbing) → SecuBox (L7 WAF + insider detection)
|
||||
```
|
||||
|
||||
## Quick Hardening Checklist
|
||||
|
||||
```bash
|
||||
# 1. Enable firewall protections
|
||||
uci set firewall.@defaults[0].synflood_protect='1'
|
||||
uci set firewall.@defaults[0].drop_invalid='1'
|
||||
uci commit firewall
|
||||
|
||||
# 2. Install CrowdSec DDoS collection
|
||||
cscli collections install crowdsecurity/http-dos
|
||||
|
||||
# 3. Enable kernel protections
|
||||
cat >> /etc/sysctl.conf << 'EOF'
|
||||
net.ipv4.tcp_syncookies=1
|
||||
net.ipv4.conf.all.rp_filter=1
|
||||
net.ipv4.icmp_ratelimit=1000
|
||||
net.netfilter.nf_conntrack_max=131072
|
||||
EOF
|
||||
sysctl -p
|
||||
|
||||
# 4. Start Vortex DNS firewall
|
||||
vortex-firewall intel update
|
||||
vortex-firewall start
|
||||
|
||||
# 5. Verify with Config Advisor
|
||||
config-advisorctl check --category ddos
|
||||
```
|
||||
|
||||
## Monitoring During Attack
|
||||
|
||||
```bash
|
||||
# Real-time connection count
|
||||
watch -n 1 'cat /proc/sys/net/netfilter/nf_conntrack_count'
|
||||
|
||||
# CrowdSec activity
|
||||
watch -n 5 'cscli metrics'
|
||||
|
||||
# Active bans
|
||||
cscli decisions list
|
||||
|
||||
# HAProxy stats (if enabled)
|
||||
echo "show stat" | socat stdio /var/run/haproxy.sock
|
||||
|
||||
# mitmproxy threats
|
||||
tail -f /srv/mitmproxy/threats.log
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [InterceptoR Overview](../package/secubox/luci-app-interceptor/README.md)
|
||||
- [CrowdSec Dashboard](../package/secubox/luci-app-crowdsec-dashboard/README.md)
|
||||
- [Vortex DNS Firewall](../package/secubox/VORTEX-DNS-FIREWALL.md)
|
||||
- [Config Advisor](../package/secubox/secubox-config-advisor/README.md)
|
||||
@ -12,7 +12,8 @@ var callGetStatus = rpc.declare({
|
||||
|
||||
var PILLARS = [
|
||||
{ id: 'wpad', name: 'WPAD', icon: '🌐', desc: 'Auto-proxy discovery' },
|
||||
{ id: 'mitm', name: 'MITM Proxy', icon: '🛡️', desc: 'Traffic inspection' },
|
||||
{ id: 'mitm', name: 'MITM Proxy', icon: '🛡️', desc: 'External WAF' },
|
||||
{ id: 'insider_waf', name: 'Insider WAF', icon: '🔒', desc: 'LAN threat detection' },
|
||||
{ id: 'cdn_cache', name: 'CDN Cache', icon: '💾', desc: 'Content caching' },
|
||||
{ id: 'cookie_tracker', name: 'Cookies', icon: '🍪', desc: 'Tracker detection' },
|
||||
{ id: 'api_failover', name: 'API Failover', icon: '⚡', desc: 'Graceful degradation' }
|
||||
@ -100,6 +101,12 @@ return view.extend({
|
||||
stats.push('Threats: ' + (data.threats_today || 0));
|
||||
stats.push('Connections: ' + (data.active_connections || 0));
|
||||
break;
|
||||
case 'insider_waf':
|
||||
stats.push('Insider threats: ' + (data.insider_threats || 0));
|
||||
stats.push('Blocked: ' + (data.blocked_clients || 0));
|
||||
if (data.exfil_attempts > 0) stats.push('⚠️ Exfil: ' + data.exfil_attempts);
|
||||
if (data.dns_anomalies > 0) stats.push('DNS: ' + data.dns_anomalies);
|
||||
break;
|
||||
case 'cdn_cache':
|
||||
stats.push('Hit Ratio: ' + (data.hit_ratio || 0) + '%');
|
||||
if (data.offline_mode) stats.push('⚠️ OFFLINE');
|
||||
|
||||
@ -152,6 +152,58 @@ get_failover_status() {
|
||||
json_close_object
|
||||
}
|
||||
|
||||
# Get Insider WAF pillar status (LAN client threat detection)
|
||||
get_insider_waf_status() {
|
||||
local enabled=0 running=0 insider_threats=0 blocked_clients=0 exfil_attempts=0
|
||||
|
||||
# Insider WAF is enabled when mitmproxy "out" instance is running
|
||||
# This inspects LAN→WAN traffic for insider threats
|
||||
if command -v lxc-ls >/dev/null 2>&1; then
|
||||
lxc-ls --running 2>/dev/null | grep -qE "mitmproxy-out|secbx-mitmproxy" && running=1
|
||||
fi
|
||||
|
||||
# Check mitmproxy config for outbound inspection
|
||||
enabled=$(uci -q get mitmproxy.out.enabled 2>/dev/null || echo "$running")
|
||||
[ "$enabled" = "1" ] || [ "$running" = "1" ] && enabled=1
|
||||
|
||||
# Count insider threats from mitmproxy (LAN source IPs only)
|
||||
local today=$(date +%Y-%m-%d)
|
||||
if [ -f /srv/mitmproxy/threats.log ]; then
|
||||
# Count threats from internal IPs (192.168.x.x, 10.x.x.x, 172.16-31.x.x)
|
||||
insider_threats=$(grep "$today" /srv/mitmproxy/threats.log 2>/dev/null | \
|
||||
grep -cE '"source_ip":"(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.)' || echo "0")
|
||||
fi
|
||||
|
||||
# Count blocked insider clients from CrowdSec decisions (internal IPs)
|
||||
if command -v cscli >/dev/null 2>&1; then
|
||||
blocked_clients=$(cscli decisions list -o json 2>/dev/null | \
|
||||
jsonfilter -e '@[*].value' 2>/dev/null | \
|
||||
grep -cE '^(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.)' || echo "0")
|
||||
fi
|
||||
|
||||
# Count data exfiltration attempts (large outbound, suspicious destinations)
|
||||
if [ -f /srv/mitmproxy/threats.log ]; then
|
||||
exfil_attempts=$(grep "$today" /srv/mitmproxy/threats.log 2>/dev/null | \
|
||||
grep -cE '"pattern":"(dns_exfil|data_exfil|suspicious_upload|large_post)"' || echo "0")
|
||||
fi
|
||||
|
||||
# Check DNS Guard for internal DNS anomalies (tunneling, DGA from LAN)
|
||||
local dns_anomalies=0
|
||||
if [ -f /var/lib/dns-guard/alerts.json ]; then
|
||||
dns_anomalies=$(jsonfilter -i /var/lib/dns-guard/alerts.json -e '@[*]' 2>/dev/null | \
|
||||
grep -cE '"type":"(dga|tunneling)"' || echo "0")
|
||||
fi
|
||||
|
||||
json_add_object "insider_waf"
|
||||
json_add_boolean "enabled" "$enabled"
|
||||
json_add_boolean "running" "$running"
|
||||
json_add_int "insider_threats" "${insider_threats:-0}"
|
||||
json_add_int "blocked_clients" "${blocked_clients:-0}"
|
||||
json_add_int "exfil_attempts" "${exfil_attempts:-0}"
|
||||
json_add_int "dns_anomalies" "${dns_anomalies:-0}"
|
||||
json_close_object
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
list)
|
||||
json_init
|
||||
@ -176,45 +228,52 @@ case "$1" in
|
||||
get_cdn_status
|
||||
get_cookie_status
|
||||
get_failover_status
|
||||
get_insider_waf_status
|
||||
|
||||
# Overall health score (0-100)
|
||||
# Overall health score (0-100) - 6 pillars × ~17 points each
|
||||
score=0
|
||||
pillars_active=0
|
||||
|
||||
# WPAD
|
||||
if [ "$(uci -q get network_tweaks.global.wpad_enforce)" = "1" ] || [ -f /www/wpad.dat ]; then
|
||||
score=$((score + 20))
|
||||
score=$((score + 17))
|
||||
pillars_active=$((pillars_active + 1))
|
||||
fi
|
||||
|
||||
# mitmproxy running
|
||||
# mitmproxy running (external WAF)
|
||||
if pgrep mitmproxy >/dev/null 2>&1 || lxc-ls --running 2>/dev/null | grep -q "secbx-mitmproxy"; then
|
||||
score=$((score + 20))
|
||||
score=$((score + 17))
|
||||
pillars_active=$((pillars_active + 1))
|
||||
fi
|
||||
|
||||
# CDN Cache running
|
||||
if pgrep squid >/dev/null 2>&1; then
|
||||
score=$((score + 20))
|
||||
score=$((score + 17))
|
||||
pillars_active=$((pillars_active + 1))
|
||||
fi
|
||||
|
||||
# Cookie Tracker enabled
|
||||
if [ "$(uci -q get cookie-tracker.main.enabled)" = "1" ]; then
|
||||
score=$((score + 20))
|
||||
score=$((score + 17))
|
||||
pillars_active=$((pillars_active + 1))
|
||||
fi
|
||||
|
||||
# API Failover enabled
|
||||
if [ "$(uci -q get cdn-cache.api_failover.enabled)" = "1" ]; then
|
||||
score=$((score + 20))
|
||||
score=$((score + 16))
|
||||
pillars_active=$((pillars_active + 1))
|
||||
fi
|
||||
|
||||
# Insider WAF (mitmproxy outbound instance)
|
||||
if lxc-ls --running 2>/dev/null | grep -qE "mitmproxy-out|secbx-mitmproxy"; then
|
||||
score=$((score + 16))
|
||||
pillars_active=$((pillars_active + 1))
|
||||
fi
|
||||
|
||||
json_add_object "summary"
|
||||
json_add_int "health_score" "$score"
|
||||
json_add_int "pillars_active" "$pillars_active"
|
||||
json_add_int "pillars_total" "5"
|
||||
json_add_int "pillars_total" "6"
|
||||
json_close_object
|
||||
|
||||
json_dump
|
||||
@ -234,6 +293,7 @@ case "$1" in
|
||||
cdn) get_cdn_status ;;
|
||||
cookie) get_cookie_status ;;
|
||||
failover) get_failover_status ;;
|
||||
insider|insider_waf) get_insider_waf_status ;;
|
||||
*)
|
||||
json_add_boolean "success" 0
|
||||
json_add_string "error" "Unknown pillar: $pillar"
|
||||
|
||||
@ -32,6 +32,8 @@ define Package/secubox-app-crowdsec-custom/description
|
||||
- Gitea web/SSH/API bruteforce detection
|
||||
- Streamlit app flooding and auth protection
|
||||
- Webapp generic auth bruteforce protection
|
||||
- mitmproxy threat detection (SQLi, XSS, SSRF, CVE)
|
||||
- Insider WAF: LAN threat detection (C2, exfiltration, lateral movement)
|
||||
- Whitelist for trusted networks
|
||||
endef
|
||||
|
||||
@ -68,6 +70,7 @@ define Package/secubox-app-crowdsec-custom/install
|
||||
$(INSTALL_DATA) ./files/scenarios/secubox-gitea-bruteforce.yaml $(1)/etc/crowdsec/scenarios/
|
||||
$(INSTALL_DATA) ./files/scenarios/secubox-streamlit-bruteforce.yaml $(1)/etc/crowdsec/scenarios/
|
||||
$(INSTALL_DATA) ./files/scenarios/secubox-webapp-bruteforce.yaml $(1)/etc/crowdsec/scenarios/
|
||||
$(INSTALL_DATA) ./files/scenarios/secubox-insider-threats.yaml $(1)/etc/crowdsec/scenarios/
|
||||
|
||||
# UCI defaults for first boot setup
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
|
||||
@ -0,0 +1,159 @@
|
||||
# CrowdSec scenarios for SecuBox Insider WAF
|
||||
# Detects malicious activity from LAN clients (compromised devices, malware, insider threats)
|
||||
|
||||
# Detect C2 beacon attempts from internal hosts
|
||||
type: leaky
|
||||
name: secubox/insider-c2-beacon
|
||||
description: "Detect C2 beacon-like activity from internal hosts"
|
||||
filter: |
|
||||
evt.Meta.log_type == 'mitmproxy_threat' &&
|
||||
evt.Meta.source_ip startsWith '192.168.' ||
|
||||
evt.Meta.source_ip startsWith '10.' ||
|
||||
evt.Meta.source_ip matches '^172\.(1[6-9]|2[0-9]|3[01])\.' &&
|
||||
evt.Parsed.pattern in ['c2_beacon', 'suspicious_periodic', 'encoded_payload', 'reverse_shell']
|
||||
groupby: evt.Meta.source_ip
|
||||
capacity: 3
|
||||
leakspeed: 300s
|
||||
blackhole: 60m
|
||||
labels:
|
||||
service: insider_waf
|
||||
type: c2_beacon
|
||||
remediation: true
|
||||
scope: lan
|
||||
---
|
||||
# Detect data exfiltration attempts from LAN
|
||||
type: leaky
|
||||
name: secubox/insider-exfiltration
|
||||
description: "Detect data exfiltration attempts from internal hosts"
|
||||
filter: |
|
||||
evt.Meta.log_type == 'mitmproxy_threat' &&
|
||||
evt.Meta.source_ip startsWith '192.168.' ||
|
||||
evt.Meta.source_ip startsWith '10.' &&
|
||||
(evt.Parsed.pattern == 'large_upload' ||
|
||||
evt.Parsed.pattern == 'base64_exfil' ||
|
||||
evt.Parsed.pattern == 'dns_exfil' ||
|
||||
evt.Parsed.content_length > 10485760)
|
||||
groupby: evt.Meta.source_ip
|
||||
capacity: 2
|
||||
leakspeed: 600s
|
||||
blackhole: 120m
|
||||
labels:
|
||||
service: insider_waf
|
||||
type: data_exfiltration
|
||||
remediation: true
|
||||
scope: lan
|
||||
---
|
||||
# Detect DNS tunneling from internal hosts
|
||||
type: leaky
|
||||
name: secubox/insider-dns-tunnel
|
||||
description: "Detect DNS tunneling/exfiltration from internal hosts"
|
||||
filter: |
|
||||
evt.Meta.log_type == 'dns_guard' &&
|
||||
evt.Parsed.type in ['tunneling', 'dga', 'suspicious_subdomain'] &&
|
||||
evt.Meta.source_ip startsWith '192.168.' ||
|
||||
evt.Meta.source_ip startsWith '10.'
|
||||
groupby: evt.Meta.source_ip
|
||||
capacity: 5
|
||||
leakspeed: 120s
|
||||
blackhole: 30m
|
||||
labels:
|
||||
service: insider_waf
|
||||
type: dns_tunneling
|
||||
remediation: true
|
||||
scope: lan
|
||||
---
|
||||
# Detect lateral movement attempts
|
||||
type: leaky
|
||||
name: secubox/insider-lateral-movement
|
||||
description: "Detect lateral movement attempts within LAN"
|
||||
filter: |
|
||||
evt.Meta.log_type == 'mitmproxy_threat' &&
|
||||
evt.Meta.source_ip startsWith '192.168.' &&
|
||||
evt.Parsed.dest_ip startsWith '192.168.' &&
|
||||
evt.Parsed.pattern in ['port_scan', 'smb_enum', 'ssh_scan', 'admin_scan', 'network_recon']
|
||||
groupby: evt.Meta.source_ip
|
||||
capacity: 10
|
||||
leakspeed: 60s
|
||||
blackhole: 30m
|
||||
labels:
|
||||
service: insider_waf
|
||||
type: lateral_movement
|
||||
remediation: true
|
||||
scope: lan
|
||||
---
|
||||
# Detect cryptominer activity from LAN
|
||||
type: leaky
|
||||
name: secubox/insider-cryptominer
|
||||
description: "Detect cryptominer activity from internal hosts"
|
||||
filter: |
|
||||
evt.Meta.log_type == 'mitmproxy_threat' &&
|
||||
evt.Meta.source_ip startsWith '192.168.' ||
|
||||
evt.Meta.source_ip startsWith '10.' &&
|
||||
(evt.Parsed.pattern == 'mining_pool' ||
|
||||
evt.Parsed.dest_port in ['3333', '4444', '5555', '14433', '14444'] ||
|
||||
evt.Parsed.host matches '.*(pool|mine|xmr|eth|btc).*')
|
||||
groupby: evt.Meta.source_ip
|
||||
capacity: 2
|
||||
leakspeed: 300s
|
||||
blackhole: 1440m
|
||||
labels:
|
||||
service: insider_waf
|
||||
type: cryptominer
|
||||
remediation: true
|
||||
scope: lan
|
||||
---
|
||||
# Detect IoT botnet activity
|
||||
type: leaky
|
||||
name: secubox/insider-iot-botnet
|
||||
description: "Detect IoT botnet C2 activity from internal devices"
|
||||
filter: |
|
||||
evt.Meta.log_type == 'mitmproxy_threat' &&
|
||||
evt.Meta.source_ip startsWith '192.168.' &&
|
||||
(evt.Parsed.user_agent matches '.*Mirai.*|.*Gafgyt.*|.*BotenaGo.*|.*Mozi.*' ||
|
||||
evt.Parsed.pattern in ['iot_exploit', 'telnet_scan', 'mirai_pattern'])
|
||||
groupby: evt.Meta.source_ip
|
||||
capacity: 1
|
||||
leakspeed: 60s
|
||||
blackhole: 1440m
|
||||
labels:
|
||||
service: insider_waf
|
||||
type: iot_botnet
|
||||
remediation: true
|
||||
scope: lan
|
||||
---
|
||||
# Detect suspicious outbound to known bad TLDs
|
||||
type: leaky
|
||||
name: secubox/insider-bad-tld
|
||||
description: "Detect suspicious outbound to high-risk TLDs from internal hosts"
|
||||
filter: |
|
||||
evt.Meta.log_type == 'mitmproxy_threat' &&
|
||||
evt.Meta.source_ip startsWith '192.168.' ||
|
||||
evt.Meta.source_ip startsWith '10.' &&
|
||||
evt.Parsed.host matches '.*\.(xyz|top|club|work|date|bid|download|racing|science|party|gq|cf|tk|ml|ga)$'
|
||||
groupby: evt.Meta.source_ip
|
||||
capacity: 20
|
||||
leakspeed: 300s
|
||||
blackhole: 15m
|
||||
labels:
|
||||
service: insider_waf
|
||||
type: suspicious_tld
|
||||
remediation: true
|
||||
scope: lan
|
||||
---
|
||||
# Detect unusual high-volume outbound from single LAN host
|
||||
type: leaky
|
||||
name: secubox/insider-high-volume
|
||||
description: "Detect unusual high-volume outbound traffic from single LAN host"
|
||||
filter: |
|
||||
evt.Meta.log_type == 'mitmproxy_threat' &&
|
||||
evt.Meta.source_ip startsWith '192.168.' &&
|
||||
evt.Parsed.bytes_out > 104857600
|
||||
groupby: evt.Meta.source_ip
|
||||
capacity: 5
|
||||
leakspeed: 3600s
|
||||
blackhole: 30m
|
||||
labels:
|
||||
service: insider_waf
|
||||
type: high_volume_outbound
|
||||
remediation: true
|
||||
scope: lan
|
||||
@ -271,6 +271,146 @@ check_system_uptodate() {
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# DDoS Protection Checks
|
||||
# ============================================
|
||||
|
||||
check_ddos_syn_cookies() {
|
||||
local syn_cookies
|
||||
syn_cookies=$(cat /proc/sys/net/ipv4/tcp_syncookies 2>/dev/null)
|
||||
|
||||
if [ "$syn_cookies" = "1" ]; then
|
||||
_record_result "DDOS-001" "pass" "SYN cookies enabled" ""
|
||||
return 0
|
||||
else
|
||||
_record_result "DDOS-001" "fail" "SYN cookies not enabled" "Vulnerable to SYN flood"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_ddos_conntrack_limit() {
|
||||
local conntrack_max
|
||||
conntrack_max=$(cat /proc/sys/net/netfilter/nf_conntrack_max 2>/dev/null || echo "0")
|
||||
|
||||
if [ "$conntrack_max" -ge 65536 ]; then
|
||||
_record_result "DDOS-002" "pass" "Connection tracking limit adequate" "max=$conntrack_max"
|
||||
return 0
|
||||
else
|
||||
_record_result "DDOS-002" "warn" "Connection tracking limit low" "max=$conntrack_max (recommend 65536+)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_ddos_crowdsec_dos() {
|
||||
# Check if CrowdSec http-dos collection is installed
|
||||
if command -v cscli >/dev/null 2>&1; then
|
||||
local dos_installed
|
||||
dos_installed=$(cscli collections list -o json 2>/dev/null | grep -c "http-dos" || echo "0")
|
||||
|
||||
if [ "$dos_installed" -gt 0 ]; then
|
||||
_record_result "DDOS-003" "pass" "CrowdSec http-dos collection installed" ""
|
||||
return 0
|
||||
else
|
||||
_record_result "DDOS-003" "warn" "CrowdSec http-dos collection not installed" "Run: cscli collections install crowdsecurity/http-dos"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_record_result "DDOS-003" "fail" "CrowdSec not available" "Install crowdsec package"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_ddos_icmp_rate() {
|
||||
local icmp_rate
|
||||
icmp_rate=$(cat /proc/sys/net/ipv4/icmp_ratelimit 2>/dev/null || echo "0")
|
||||
|
||||
if [ "$icmp_rate" -gt 0 ]; then
|
||||
_record_result "DDOS-004" "pass" "ICMP rate limiting enabled" "rate=$icmp_rate"
|
||||
return 0
|
||||
else
|
||||
_record_result "DDOS-004" "warn" "ICMP rate limiting not configured" ""
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_ddos_rp_filter() {
|
||||
local rp_filter
|
||||
rp_filter=$(cat /proc/sys/net/ipv4/conf/all/rp_filter 2>/dev/null || echo "0")
|
||||
|
||||
if [ "$rp_filter" = "1" ]; then
|
||||
_record_result "DDOS-005" "pass" "Reverse path filtering enabled" "Anti-spoofing active"
|
||||
return 0
|
||||
else
|
||||
_record_result "DDOS-005" "warn" "Reverse path filtering disabled" "Vulnerable to IP spoofing"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_ddos_haproxy_limits() {
|
||||
# Check HAProxy connection limits
|
||||
if [ -f /etc/haproxy/haproxy.cfg ]; then
|
||||
local maxconn
|
||||
maxconn=$(grep -E "^\s*maxconn" /etc/haproxy/haproxy.cfg 2>/dev/null | head -1 | awk '{print $2}')
|
||||
|
||||
if [ -n "$maxconn" ] && [ "$maxconn" -gt 0 ]; then
|
||||
_record_result "DDOS-006" "pass" "HAProxy connection limit set" "maxconn=$maxconn"
|
||||
return 0
|
||||
else
|
||||
_record_result "DDOS-006" "warn" "HAProxy maxconn not configured" "Recommend setting maxconn limit"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_record_result "DDOS-006" "info" "HAProxy not installed" ""
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
check_ddos_mitmproxy_waf() {
|
||||
# Check if mitmproxy WAF is running for DDoS detection
|
||||
if lxc-ls --running 2>/dev/null | grep -qE "mitmproxy|secbx-mitmproxy"; then
|
||||
_record_result "DDOS-007" "pass" "mitmproxy WAF running" "L7 flood detection active"
|
||||
return 0
|
||||
else
|
||||
_record_result "DDOS-007" "info" "mitmproxy WAF not running" "L7 protection inactive"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_ddos_vortex_firewall() {
|
||||
# Check Vortex DNS firewall for botnet C2 blocking
|
||||
if [ -f /var/lib/vortex-firewall/blocklist.db ]; then
|
||||
local blocked_count
|
||||
blocked_count=$(sqlite3 /var/lib/vortex-firewall/blocklist.db "SELECT COUNT(*) FROM domains;" 2>/dev/null || echo "0")
|
||||
|
||||
if [ "$blocked_count" -gt 100 ]; then
|
||||
_record_result "DDOS-008" "pass" "Vortex DNS firewall active" "blocked=$blocked_count domains"
|
||||
return 0
|
||||
else
|
||||
_record_result "DDOS-008" "warn" "Vortex DNS firewall has few rules" "blocked=$blocked_count"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_record_result "DDOS-008" "info" "Vortex DNS firewall not configured" ""
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Run DDoS-specific checks
|
||||
run_ddos_checks() {
|
||||
checks_init
|
||||
|
||||
check_ddos_syn_cookies
|
||||
check_ddos_conntrack_limit
|
||||
check_ddos_crowdsec_dos
|
||||
check_ddos_icmp_rate
|
||||
check_ddos_rp_filter
|
||||
check_ddos_haproxy_limits
|
||||
check_ddos_mitmproxy_waf
|
||||
check_ddos_vortex_firewall
|
||||
|
||||
cat "$RESULTS_FILE"
|
||||
}
|
||||
|
||||
# Run all checks
|
||||
run_all_checks() {
|
||||
checks_init
|
||||
@ -303,6 +443,16 @@ run_all_checks() {
|
||||
check_syslog_enabled
|
||||
check_log_rotation
|
||||
|
||||
# DDoS Protection
|
||||
check_ddos_syn_cookies
|
||||
check_ddos_conntrack_limit
|
||||
check_ddos_crowdsec_dos
|
||||
check_ddos_icmp_rate
|
||||
check_ddos_rp_filter
|
||||
check_ddos_haproxy_limits
|
||||
check_ddos_mitmproxy_waf
|
||||
check_ddos_vortex_firewall
|
||||
|
||||
# Updates (can be slow)
|
||||
# check_system_uptodate
|
||||
|
||||
|
||||
@ -252,6 +252,75 @@
|
||||
"remediation": "Consider sysupgrade to latest stable release"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ddos": {
|
||||
"name": "DDoS Protection",
|
||||
"rules": [
|
||||
{
|
||||
"id": "DDOS-001",
|
||||
"name": "SYN cookies enabled",
|
||||
"severity": "high",
|
||||
"check": "ddos_syn_cookies",
|
||||
"description": "SYN cookies protect against SYN flood attacks",
|
||||
"remediation": "echo 1 > /proc/sys/net/ipv4/tcp_syncookies"
|
||||
},
|
||||
{
|
||||
"id": "DDOS-002",
|
||||
"name": "Connection tracking limit",
|
||||
"severity": "medium",
|
||||
"check": "ddos_conntrack_limit",
|
||||
"description": "Connection tracking table should handle traffic spikes",
|
||||
"remediation": "Increase nf_conntrack_max to at least 65536"
|
||||
},
|
||||
{
|
||||
"id": "DDOS-003",
|
||||
"name": "CrowdSec http-dos collection",
|
||||
"severity": "high",
|
||||
"check": "ddos_crowdsec_dos",
|
||||
"description": "CrowdSec http-dos collection detects HTTP flood attacks",
|
||||
"remediation": "cscli collections install crowdsecurity/http-dos"
|
||||
},
|
||||
{
|
||||
"id": "DDOS-004",
|
||||
"name": "ICMP rate limiting",
|
||||
"severity": "medium",
|
||||
"check": "ddos_icmp_rate",
|
||||
"description": "ICMP rate limiting prevents ping flood attacks",
|
||||
"remediation": "echo 1000 > /proc/sys/net/ipv4/icmp_ratelimit"
|
||||
},
|
||||
{
|
||||
"id": "DDOS-005",
|
||||
"name": "Reverse path filtering",
|
||||
"severity": "high",
|
||||
"check": "ddos_rp_filter",
|
||||
"description": "RP filter prevents IP spoofing attacks",
|
||||
"remediation": "echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter"
|
||||
},
|
||||
{
|
||||
"id": "DDOS-006",
|
||||
"name": "HAProxy connection limits",
|
||||
"severity": "medium",
|
||||
"check": "ddos_haproxy_limits",
|
||||
"description": "HAProxy maxconn limits prevent connection exhaustion",
|
||||
"remediation": "Set maxconn in haproxy.cfg global/defaults section"
|
||||
},
|
||||
{
|
||||
"id": "DDOS-007",
|
||||
"name": "mitmproxy WAF active",
|
||||
"severity": "medium",
|
||||
"check": "ddos_mitmproxy_waf",
|
||||
"description": "mitmproxy provides L7 flood detection and blocking",
|
||||
"remediation": "Enable mitmproxy LXC container"
|
||||
},
|
||||
{
|
||||
"id": "DDOS-008",
|
||||
"name": "Vortex DNS firewall",
|
||||
"severity": "medium",
|
||||
"check": "ddos_vortex_firewall",
|
||||
"description": "Vortex blocks botnet C2 domains at DNS level",
|
||||
"remediation": "Run vortex-firewall intel update && vortex-firewall start"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user