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)
|
- `out`: LAN→Internet transparent proxy (port 8888/8089)
|
||||||
- `in`: WAF/services upstream proxy (port 8889/8090)
|
- `in`: WAF/services upstream proxy (port 8889/8090)
|
||||||
- README updated with multi-instance documentation
|
- 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 = [
|
var PILLARS = [
|
||||||
{ id: 'wpad', name: 'WPAD', icon: '🌐', desc: 'Auto-proxy discovery' },
|
{ 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: 'cdn_cache', name: 'CDN Cache', icon: '💾', desc: 'Content caching' },
|
||||||
{ id: 'cookie_tracker', name: 'Cookies', icon: '🍪', desc: 'Tracker detection' },
|
{ id: 'cookie_tracker', name: 'Cookies', icon: '🍪', desc: 'Tracker detection' },
|
||||||
{ id: 'api_failover', name: 'API Failover', icon: '⚡', desc: 'Graceful degradation' }
|
{ 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('Threats: ' + (data.threats_today || 0));
|
||||||
stats.push('Connections: ' + (data.active_connections || 0));
|
stats.push('Connections: ' + (data.active_connections || 0));
|
||||||
break;
|
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':
|
case 'cdn_cache':
|
||||||
stats.push('Hit Ratio: ' + (data.hit_ratio || 0) + '%');
|
stats.push('Hit Ratio: ' + (data.hit_ratio || 0) + '%');
|
||||||
if (data.offline_mode) stats.push('⚠️ OFFLINE');
|
if (data.offline_mode) stats.push('⚠️ OFFLINE');
|
||||||
|
|||||||
@ -152,6 +152,58 @@ get_failover_status() {
|
|||||||
json_close_object
|
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
|
case "$1" in
|
||||||
list)
|
list)
|
||||||
json_init
|
json_init
|
||||||
@ -176,45 +228,52 @@ case "$1" in
|
|||||||
get_cdn_status
|
get_cdn_status
|
||||||
get_cookie_status
|
get_cookie_status
|
||||||
get_failover_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
|
score=0
|
||||||
pillars_active=0
|
pillars_active=0
|
||||||
|
|
||||||
# WPAD
|
# WPAD
|
||||||
if [ "$(uci -q get network_tweaks.global.wpad_enforce)" = "1" ] || [ -f /www/wpad.dat ]; then
|
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))
|
pillars_active=$((pillars_active + 1))
|
||||||
fi
|
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
|
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))
|
pillars_active=$((pillars_active + 1))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# CDN Cache running
|
# CDN Cache running
|
||||||
if pgrep squid >/dev/null 2>&1; then
|
if pgrep squid >/dev/null 2>&1; then
|
||||||
score=$((score + 20))
|
score=$((score + 17))
|
||||||
pillars_active=$((pillars_active + 1))
|
pillars_active=$((pillars_active + 1))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Cookie Tracker enabled
|
# Cookie Tracker enabled
|
||||||
if [ "$(uci -q get cookie-tracker.main.enabled)" = "1" ]; then
|
if [ "$(uci -q get cookie-tracker.main.enabled)" = "1" ]; then
|
||||||
score=$((score + 20))
|
score=$((score + 17))
|
||||||
pillars_active=$((pillars_active + 1))
|
pillars_active=$((pillars_active + 1))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# API Failover enabled
|
# API Failover enabled
|
||||||
if [ "$(uci -q get cdn-cache.api_failover.enabled)" = "1" ]; then
|
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))
|
pillars_active=$((pillars_active + 1))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
json_add_object "summary"
|
json_add_object "summary"
|
||||||
json_add_int "health_score" "$score"
|
json_add_int "health_score" "$score"
|
||||||
json_add_int "pillars_active" "$pillars_active"
|
json_add_int "pillars_active" "$pillars_active"
|
||||||
json_add_int "pillars_total" "5"
|
json_add_int "pillars_total" "6"
|
||||||
json_close_object
|
json_close_object
|
||||||
|
|
||||||
json_dump
|
json_dump
|
||||||
@ -234,6 +293,7 @@ case "$1" in
|
|||||||
cdn) get_cdn_status ;;
|
cdn) get_cdn_status ;;
|
||||||
cookie) get_cookie_status ;;
|
cookie) get_cookie_status ;;
|
||||||
failover) get_failover_status ;;
|
failover) get_failover_status ;;
|
||||||
|
insider|insider_waf) get_insider_waf_status ;;
|
||||||
*)
|
*)
|
||||||
json_add_boolean "success" 0
|
json_add_boolean "success" 0
|
||||||
json_add_string "error" "Unknown pillar: $pillar"
|
json_add_string "error" "Unknown pillar: $pillar"
|
||||||
|
|||||||
@ -32,6 +32,8 @@ define Package/secubox-app-crowdsec-custom/description
|
|||||||
- Gitea web/SSH/API bruteforce detection
|
- Gitea web/SSH/API bruteforce detection
|
||||||
- Streamlit app flooding and auth protection
|
- Streamlit app flooding and auth protection
|
||||||
- Webapp generic auth bruteforce 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
|
- Whitelist for trusted networks
|
||||||
endef
|
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-gitea-bruteforce.yaml $(1)/etc/crowdsec/scenarios/
|
||||||
$(INSTALL_DATA) ./files/scenarios/secubox-streamlit-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-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
|
# UCI defaults for first boot setup
|
||||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
$(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
|
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
|
||||||
run_all_checks() {
|
run_all_checks() {
|
||||||
checks_init
|
checks_init
|
||||||
@ -303,6 +443,16 @@ run_all_checks() {
|
|||||||
check_syslog_enabled
|
check_syslog_enabled
|
||||||
check_log_rotation
|
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)
|
# Updates (can be slow)
|
||||||
# check_system_uptodate
|
# check_system_uptodate
|
||||||
|
|
||||||
|
|||||||
@ -252,6 +252,75 @@
|
|||||||
"remediation": "Consider sysupgrade to latest stable release"
|
"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