📚 docs(security): Add comprehensive Security chapter
## New Security Documentation Structure
/security/
├── README.md # Security overview & contacts
├── forensics-checklist.md # Incident investigation guide
├── persistence-scan.sh # Quick persistence detector
├── runtime-detector.sh # Mining/suspicious process detector
└── hardening/
├── docker.md # Docker security baseline
├── kubernetes.md # K8s policies (future reference)
└── cloud.md # Hetzner-specific hardening
## Key Components
### Forensics Checklist
- Process analysis commands
- Persistence mechanism detection
- Network connection analysis
- File system inspection
- Authentication audit
- Decision matrix for threat response
### Scripts
- persistence-scan.sh: Cron, systemd, executables, SSH keys
- runtime-detector.sh: Mining process detection with --kill option
### Hardening Guides
- Docker: Secure compose template, Dockerfile best practices
- Kubernetes: NetworkPolicy, PodSecurityStandard, Falco rules
- Cloud: Egress firewall, SSH hardening, fail2ban, monitoring
## Post-Incident Documentation
Based on lessons learned from Incidents #1 and #2 (Jan 2026)
Co-authored-by: Cursor Agent <agent@cursor.sh>
This commit is contained in:
217
security/runtime-detector.sh
Executable file
217
security/runtime-detector.sh
Executable file
@@ -0,0 +1,217 @@
|
||||
#!/bin/bash
|
||||
# ============================================
|
||||
# Runtime Detector — DAARION Security
|
||||
# Version: 1.0.0
|
||||
# Purpose: Detect and respond to suspicious runtime activity
|
||||
# Usage: ./runtime-detector.sh [--kill] [--alert]
|
||||
# ============================================
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Configuration
|
||||
KILL_MODE=false
|
||||
ALERT_MODE=false
|
||||
ALERT_ENDPOINT="${ALERT_ENDPOINT:-}"
|
||||
CPU_THRESHOLD=80
|
||||
LOG_FILE="/var/log/daarion-security.log"
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--kill)
|
||||
KILL_MODE=true
|
||||
shift
|
||||
;;
|
||||
--alert)
|
||||
ALERT_MODE=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ============================================
|
||||
# Logging function
|
||||
# ============================================
|
||||
log() {
|
||||
local level=$1
|
||||
local message=$2
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "[$timestamp] [$level] $message" >> "$LOG_FILE" 2>/dev/null || true
|
||||
|
||||
case $level in
|
||||
"CRITICAL")
|
||||
echo -e "${RED}[$level] $message${NC}"
|
||||
;;
|
||||
"WARNING")
|
||||
echo -e "${YELLOW}[$level] $message${NC}"
|
||||
;;
|
||||
"INFO")
|
||||
echo -e "${GREEN}[$level] $message${NC}"
|
||||
;;
|
||||
*)
|
||||
echo "[$level] $message"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Alert function
|
||||
# ============================================
|
||||
send_alert() {
|
||||
local message=$1
|
||||
local hostname=$(hostname)
|
||||
|
||||
if [ "$ALERT_MODE" = true ] && [ -n "$ALERT_ENDPOINT" ]; then
|
||||
curl -s -X POST "$ALERT_ENDPOINT" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"host\":\"$hostname\",\"message\":\"$message\",\"timestamp\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}" \
|
||||
2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Check for mining processes
|
||||
# ============================================
|
||||
check_mining_processes() {
|
||||
log "INFO" "Checking for mining processes..."
|
||||
|
||||
# Known mining process patterns
|
||||
local patterns="xmrig|catcal|softirq|vrarhpb|G4NQXBp|minergate|cpuminer|cgminer|bfgminer|ethminer|cryptonight"
|
||||
|
||||
local suspicious=$(ps aux | grep -iE "$patterns" | grep -v grep | grep -v "$0")
|
||||
|
||||
if [ -n "$suspicious" ]; then
|
||||
log "CRITICAL" "Suspicious mining process detected!"
|
||||
echo "$suspicious"
|
||||
|
||||
send_alert "Mining process detected on $(hostname): $(echo "$suspicious" | head -1)"
|
||||
|
||||
if [ "$KILL_MODE" = true ]; then
|
||||
log "WARNING" "Kill mode enabled - terminating processes..."
|
||||
echo "$suspicious" | awk '{print $2}' | xargs -r kill -9 2>/dev/null || true
|
||||
log "INFO" "Processes terminated"
|
||||
else
|
||||
log "INFO" "Run with --kill to terminate processes"
|
||||
fi
|
||||
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "INFO" "No mining processes found"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Check high CPU processes
|
||||
# ============================================
|
||||
check_high_cpu() {
|
||||
log "INFO" "Checking for high CPU usage..."
|
||||
|
||||
local high_cpu=$(ps -eo pid,user,cmd,%cpu --sort=-%cpu | awk -v threshold="$CPU_THRESHOLD" 'NR>1 && $NF > threshold {print}')
|
||||
|
||||
if [ -n "$high_cpu" ]; then
|
||||
log "WARNING" "Processes with CPU > ${CPU_THRESHOLD}%:"
|
||||
echo "$high_cpu"
|
||||
|
||||
# Check if it's a known good process
|
||||
local suspicious=$(echo "$high_cpu" | grep -vE "(node|python|docker|nginx|postgres|redis)" | head -5)
|
||||
|
||||
if [ -n "$suspicious" ]; then
|
||||
log "CRITICAL" "Unknown high-CPU process detected!"
|
||||
send_alert "High CPU process on $(hostname): $(echo "$suspicious" | head -1)"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Check outbound connections
|
||||
# ============================================
|
||||
check_network() {
|
||||
log "INFO" "Checking network connections..."
|
||||
|
||||
# Known mining pool ports
|
||||
local mining_ports="3333|5555|7777|14433|45700|45560|14444|9999"
|
||||
|
||||
local suspicious_conn=$(ss -antp 2>/dev/null | grep ESTAB | grep -E ":($mining_ports)")
|
||||
|
||||
if [ -n "$suspicious_conn" ]; then
|
||||
log "CRITICAL" "Connection to potential mining pool detected!"
|
||||
echo "$suspicious_conn"
|
||||
|
||||
send_alert "Mining pool connection on $(hostname): $(echo "$suspicious_conn" | head -1)"
|
||||
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "INFO" "No suspicious connections found"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Check Docker containers
|
||||
# ============================================
|
||||
check_docker() {
|
||||
if ! command -v docker &> /dev/null; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "INFO" "Checking Docker containers..."
|
||||
|
||||
# Check container CPU usage
|
||||
local container_stats=$(docker stats --no-stream --format "{{.Name}}: {{.CPUPerc}}" 2>/dev/null)
|
||||
|
||||
echo "$container_stats" | while read line; do
|
||||
local cpu=$(echo "$line" | grep -oE '[0-9]+\.[0-9]+' | head -1)
|
||||
if [ -n "$cpu" ]; then
|
||||
local cpu_int=${cpu%.*}
|
||||
if [ "$cpu_int" -gt "$CPU_THRESHOLD" ]; then
|
||||
log "WARNING" "Container with high CPU: $line"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# Main
|
||||
# ============================================
|
||||
echo -e "${BLUE}============================================${NC}"
|
||||
echo -e "${BLUE} DAARION Runtime Detector${NC}"
|
||||
echo -e "${BLUE}============================================${NC}"
|
||||
echo ""
|
||||
|
||||
ISSUES=0
|
||||
|
||||
check_mining_processes || ISSUES=$((ISSUES + 1))
|
||||
echo ""
|
||||
check_high_cpu || ISSUES=$((ISSUES + 1))
|
||||
echo ""
|
||||
check_network || ISSUES=$((ISSUES + 1))
|
||||
echo ""
|
||||
check_docker || ISSUES=$((ISSUES + 1))
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}============================================${NC}"
|
||||
if [ $ISSUES -gt 0 ]; then
|
||||
echo -e "${RED} ⚠️ ISSUES DETECTED: $ISSUES${NC}"
|
||||
echo -e "${RED} Immediate investigation required!${NC}"
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN} ✓ No issues detected${NC}"
|
||||
exit 0
|
||||
fi
|
||||
echo -e "${BLUE}============================================${NC}"
|
||||
Reference in New Issue
Block a user