📚 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:
96
security/README.md
Normal file
96
security/README.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
# 🔐 Security — DAARION Infrastructure
|
||||||
|
|
||||||
|
**Версія:** 1.0.0
|
||||||
|
**Останнє оновлення:** 2026-01-09
|
||||||
|
**Статус:** Production Active
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Зміст
|
||||||
|
|
||||||
|
| Документ | Призначення |
|
||||||
|
|----------|-------------|
|
||||||
|
| [forensics-checklist.md](./forensics-checklist.md) | Чекліст розслідування інцидентів |
|
||||||
|
| [persistence-scan.sh](./persistence-scan.sh) | Скрипт виявлення persistence |
|
||||||
|
| [runtime-detector.sh](./runtime-detector.sh) | Детектор підозрілих процесів |
|
||||||
|
| [hardening/docker.md](./hardening/docker.md) | Docker security baseline |
|
||||||
|
| [hardening/kubernetes.md](./hardening/kubernetes.md) | Kubernetes security policies |
|
||||||
|
| [hardening/cloud.md](./hardening/cloud.md) | Cloud security (Hetzner) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Принципи безпеки DAARION
|
||||||
|
|
||||||
|
### 1. Defense in Depth
|
||||||
|
|
||||||
|
```
|
||||||
|
[Network] → [Container] → [Process] → [Data]
|
||||||
|
↓ ↓ ↓ ↓
|
||||||
|
Firewall read-only runtime encrypt
|
||||||
|
egress cap_drop detection at rest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Zero Trust
|
||||||
|
|
||||||
|
- Кожен сервіс має мінімальні привілеї
|
||||||
|
- Мережевий доступ deny-by-default
|
||||||
|
- Аутентифікація для всіх internal API
|
||||||
|
|
||||||
|
### 3. Detect → Respond → Prevent
|
||||||
|
|
||||||
|
```
|
||||||
|
[Incident] → [Forensics] → [Root Cause] → [Hardening] → [Monitoring]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚨 Incident Response Flow
|
||||||
|
|
||||||
|
### При виявленні підозрілої активності:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Detect
|
||||||
|
./security/persistence-scan.sh
|
||||||
|
./security/runtime-detector.sh
|
||||||
|
|
||||||
|
# 2. Contain
|
||||||
|
docker stop <container>
|
||||||
|
iptables -I OUTPUT -d 0.0.0.0/0 -j DROP # emergency
|
||||||
|
|
||||||
|
# 3. Investigate
|
||||||
|
./security/forensics-checklist.md # follow checklist
|
||||||
|
|
||||||
|
# 4. Remediate
|
||||||
|
# Based on findings
|
||||||
|
|
||||||
|
# 5. Document
|
||||||
|
# Update INFRASTRUCTURE.md with incident details
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Security Metrics
|
||||||
|
|
||||||
|
| Metric | Target | Current |
|
||||||
|
|--------|--------|---------|
|
||||||
|
| Containers with `read_only` | 100% | 🔄 In progress |
|
||||||
|
| Services with `cap_drop: ALL` | 100% | 🔄 In progress |
|
||||||
|
| Egress firewall rules | Active | ✅ Active |
|
||||||
|
| Runtime detection | Active | 🔄 Planned |
|
||||||
|
| Vulnerability scan frequency | Weekly | 🔄 Planned |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📞 Security Contacts
|
||||||
|
|
||||||
|
- **Security Lead:** admin@daarion.city
|
||||||
|
- **Hetzner Abuse:** abuse@hetzner.com
|
||||||
|
- **Emergency:** Submit statement via Hetzner Robot
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Related Documents
|
||||||
|
|
||||||
|
- [INFRASTRUCTURE.md](../INFRASTRUCTURE.md) — Infrastructure overview + Incident history
|
||||||
|
- [SECURITY-REBUILD-REPORT.md](../SECURITY-REBUILD-REPORT.md) — daarion-web incident analysis
|
||||||
|
- [TASK_REBUILD_DAARION_WEB.md](../TASK_REBUILD_DAARION_WEB.md) — Rebuild task details
|
||||||
293
security/forensics-checklist.md
Normal file
293
security/forensics-checklist.md
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
# 🔍 Forensics Checklist — Incident Investigation
|
||||||
|
|
||||||
|
**Мета:** Відповісти на 3 критичні питання:
|
||||||
|
|
||||||
|
1. **Як саме зайшли** (initial access vector)
|
||||||
|
2. **Чи є persistence** (чи повернеться знову)
|
||||||
|
3. **Чи можна довіряти системі далі** (чи потрібен rebuild)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Швидкий чекліст
|
||||||
|
|
||||||
|
### A. Process-level Analysis
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Всі процеси з деревом
|
||||||
|
ps auxf
|
||||||
|
|
||||||
|
# Top CPU consumers
|
||||||
|
ps -eo pid,ppid,user,cmd,%cpu,%mem --sort=-%cpu | head -20
|
||||||
|
|
||||||
|
# Процеси конкретного користувача (напр. container user 1001)
|
||||||
|
ps aux | grep "1001"
|
||||||
|
|
||||||
|
# Zombie процеси
|
||||||
|
ps aux | grep defunct | wc -l
|
||||||
|
```
|
||||||
|
|
||||||
|
**🔴 Red flags:**
|
||||||
|
- Дивні назви: `softirq`, `.syslog`, `catcal`, `G4NQXBp`, `vrarhpb`
|
||||||
|
- Процеси без батьків (orphans)
|
||||||
|
- user ≠ expected
|
||||||
|
- CPU > 50% на невідомому процесі
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### B. Persistence Mechanisms
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Cron jobs
|
||||||
|
crontab -l
|
||||||
|
cat /etc/crontab
|
||||||
|
ls -la /etc/cron.d/
|
||||||
|
ls -la /etc/cron.daily/
|
||||||
|
ls -la /etc/cron.hourly/
|
||||||
|
|
||||||
|
# Systemd services
|
||||||
|
systemctl list-unit-files --state=enabled
|
||||||
|
ls -la /etc/systemd/system/
|
||||||
|
ls -la /usr/lib/systemd/system/
|
||||||
|
|
||||||
|
# Init scripts
|
||||||
|
ls -la /etc/init.d/
|
||||||
|
ls -la /etc/rc.local
|
||||||
|
|
||||||
|
# Docker auto-restart
|
||||||
|
docker ps --filter "restart=always"
|
||||||
|
docker ps --filter "restart=unless-stopped"
|
||||||
|
```
|
||||||
|
|
||||||
|
**🔴 Red flags:**
|
||||||
|
- Незнайомі cron jobs
|
||||||
|
- Нові systemd services
|
||||||
|
- Контейнери з `restart: unless-stopped` + compromised
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### C. Network Analysis
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Listening ports
|
||||||
|
ss -tulpn
|
||||||
|
netstat -tulpn
|
||||||
|
|
||||||
|
# Active connections
|
||||||
|
ss -antp
|
||||||
|
netstat -antp
|
||||||
|
|
||||||
|
# Firewall rules
|
||||||
|
iptables -L -n -v
|
||||||
|
iptables -L -n -v -t nat
|
||||||
|
|
||||||
|
# DNS queries (if available)
|
||||||
|
cat /var/log/syslog | grep -i dns
|
||||||
|
```
|
||||||
|
|
||||||
|
**🔴 Red flags:**
|
||||||
|
- Outbound до mining pools (порти 3333, 5555, 7777, 14433)
|
||||||
|
- Нові listening ports
|
||||||
|
- З'єднання до unknown IP
|
||||||
|
|
||||||
|
**Known mining pool patterns:**
|
||||||
|
```
|
||||||
|
*pool*
|
||||||
|
*xmr*
|
||||||
|
*monero*
|
||||||
|
*crypto*
|
||||||
|
*.ru:*
|
||||||
|
*.cn:*
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### D. File System Analysis
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Executable files in temp directories
|
||||||
|
find /tmp /var/tmp /dev/shm -type f -executable 2>/dev/null
|
||||||
|
|
||||||
|
# Recently modified binaries
|
||||||
|
find /usr/bin /usr/local/bin /usr/sbin -mtime -3 2>/dev/null
|
||||||
|
|
||||||
|
# Hidden files in home directories
|
||||||
|
find /root /home -name ".*" -type f 2>/dev/null
|
||||||
|
|
||||||
|
# Large files in unexpected places
|
||||||
|
find /tmp /var/tmp -size +10M 2>/dev/null
|
||||||
|
|
||||||
|
# SUID/SGID binaries
|
||||||
|
find / -perm -4000 -type f 2>/dev/null
|
||||||
|
find / -perm -2000 -type f 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
**🔴 Red flags:**
|
||||||
|
- Executables в /tmp, /dev/shm
|
||||||
|
- Нещодавно змінені системні бінарники
|
||||||
|
- Hidden files з executable permissions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### E. Authentication & Access
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Login history
|
||||||
|
last
|
||||||
|
lastlog
|
||||||
|
who
|
||||||
|
|
||||||
|
# SSH keys
|
||||||
|
grep -R "ssh-rsa" /root/.ssh /home 2>/dev/null
|
||||||
|
cat /root/.ssh/authorized_keys
|
||||||
|
ls -la /root/.ssh/
|
||||||
|
|
||||||
|
# Failed logins
|
||||||
|
grep "Failed" /var/log/auth.log | tail -50
|
||||||
|
grep "Accepted" /var/log/auth.log | tail -50
|
||||||
|
|
||||||
|
# Sudo usage
|
||||||
|
grep "sudo" /var/log/auth.log | tail -50
|
||||||
|
```
|
||||||
|
|
||||||
|
**🔴 Red flags:**
|
||||||
|
- Незнайомі SSH ключі
|
||||||
|
- Логіни з unknown IP
|
||||||
|
- Нові користувачі
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### F. Docker-specific
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# All containers (including stopped)
|
||||||
|
docker ps -a
|
||||||
|
|
||||||
|
# Container processes
|
||||||
|
docker top <container_name>
|
||||||
|
|
||||||
|
# Container logs
|
||||||
|
docker logs --tail 100 <container_name>
|
||||||
|
|
||||||
|
# Docker images
|
||||||
|
docker images
|
||||||
|
|
||||||
|
# Docker networks
|
||||||
|
docker network ls
|
||||||
|
docker network inspect <network>
|
||||||
|
|
||||||
|
# Container inspect (look for mounts, env vars)
|
||||||
|
docker inspect <container_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
**🔴 Red flags:**
|
||||||
|
- Контейнери з `--privileged`
|
||||||
|
- Mounted host directories (особливо /)
|
||||||
|
- Unknown images
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Decision Matrix
|
||||||
|
|
||||||
|
| Знахідка | Рівень загрози | Дія |
|
||||||
|
|----------|----------------|-----|
|
||||||
|
| Підозрілий процес, CPU > 50% | 🔴 Critical | Kill + investigate |
|
||||||
|
| Cron job до unknown binary | 🔴 Critical | Remove + investigate |
|
||||||
|
| New SSH key | 🔴 Critical | Remove + rotate all |
|
||||||
|
| Outbound to mining pool | 🔴 Critical | Block + kill |
|
||||||
|
| Modified system binary | 🔴 Critical | Full rebuild |
|
||||||
|
| Container with persistence | 🟡 High | Remove container + image |
|
||||||
|
| Unknown listening port | 🟡 High | Investigate + block |
|
||||||
|
| Failed SSH attempts | 🟢 Low | Monitor + fail2ban |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Post-Investigation Actions
|
||||||
|
|
||||||
|
### If compromised (any 🔴 finding):
|
||||||
|
|
||||||
|
1. **Contain:**
|
||||||
|
```bash
|
||||||
|
# Stop affected services
|
||||||
|
docker stop <container>
|
||||||
|
|
||||||
|
# Block outbound (emergency)
|
||||||
|
iptables -I OUTPUT -d 0.0.0.0/0 -p tcp --dport 22 -j DROP
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Preserve evidence:**
|
||||||
|
```bash
|
||||||
|
# Save process list
|
||||||
|
ps auxf > /root/evidence/ps_$(date +%Y%m%d_%H%M%S).txt
|
||||||
|
|
||||||
|
# Save network connections
|
||||||
|
ss -antp > /root/evidence/ss_$(date +%Y%m%d_%H%M%S).txt
|
||||||
|
|
||||||
|
# Save Docker state
|
||||||
|
docker ps -a > /root/evidence/docker_$(date +%Y%m%d_%H%M%S).txt
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Eradicate:**
|
||||||
|
```bash
|
||||||
|
# Kill processes
|
||||||
|
kill -9 <pid>
|
||||||
|
|
||||||
|
# Remove persistence
|
||||||
|
crontab -r
|
||||||
|
systemctl disable <service>
|
||||||
|
|
||||||
|
# Remove Docker artifacts
|
||||||
|
docker stop <container>
|
||||||
|
docker rm <container>
|
||||||
|
docker rmi <image> # CRITICAL!
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Recover:**
|
||||||
|
- Rebuild from clean source
|
||||||
|
- Apply hardening
|
||||||
|
- Monitor for recurrence
|
||||||
|
|
||||||
|
5. **Document:**
|
||||||
|
- Update INFRASTRUCTURE.md
|
||||||
|
- Create incident report
|
||||||
|
- Update hardening procedures
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Incident Report Template
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Incident Report: [Title]
|
||||||
|
|
||||||
|
**Date:** YYYY-MM-DD HH:MM UTC
|
||||||
|
**Severity:** Critical/High/Medium/Low
|
||||||
|
**Status:** Resolved/Ongoing
|
||||||
|
|
||||||
|
### Timeline
|
||||||
|
- HH:MM — Detection
|
||||||
|
- HH:MM — Containment
|
||||||
|
- HH:MM — Eradication
|
||||||
|
- HH:MM — Recovery
|
||||||
|
|
||||||
|
### Root Cause
|
||||||
|
[Description of how the attack occurred]
|
||||||
|
|
||||||
|
### Impact
|
||||||
|
- Services affected
|
||||||
|
- Data affected
|
||||||
|
- Downtime
|
||||||
|
|
||||||
|
### Indicators of Compromise (IOCs)
|
||||||
|
- Process names
|
||||||
|
- File paths
|
||||||
|
- IP addresses
|
||||||
|
- Domains
|
||||||
|
|
||||||
|
### Remediation
|
||||||
|
- Actions taken
|
||||||
|
- Hardening applied
|
||||||
|
|
||||||
|
### Lessons Learned
|
||||||
|
- What worked
|
||||||
|
- What to improve
|
||||||
|
- Prevention measures
|
||||||
|
```
|
||||||
310
security/hardening/cloud.md
Normal file
310
security/hardening/cloud.md
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
# ☁️ Cloud Security Hardening — Hetzner
|
||||||
|
|
||||||
|
**Версія:** 1.0.0
|
||||||
|
**Provider:** Hetzner Dedicated (GEX44)
|
||||||
|
**Server:** NODE1 (144.76.224.179)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Критичні налаштування
|
||||||
|
|
||||||
|
### 1. Egress Firewall (№1 Priority)
|
||||||
|
|
||||||
|
**Блокування внутрішніх мереж Hetzner:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# /root/firewall-egress.sh
|
||||||
|
|
||||||
|
# Block Hetzner internal networks (prevent scanning)
|
||||||
|
iptables -I OUTPUT -d 10.0.0.0/8 -j DROP
|
||||||
|
iptables -I OUTPUT -d 172.16.0.0/12 -j DROP
|
||||||
|
iptables -I OUTPUT -d 192.168.0.0/16 -j DROP
|
||||||
|
|
||||||
|
# Allow necessary internal traffic
|
||||||
|
iptables -I OUTPUT -d 10.0.0.0/8 -p tcp --dport 443 -j ACCEPT
|
||||||
|
iptables -I OUTPUT -d 10.0.0.0/8 -p tcp --dport 80 -j ACCEPT
|
||||||
|
|
||||||
|
# Log blocked attempts
|
||||||
|
iptables -I OUTPUT -d 10.0.0.0/8 -j LOG --log-prefix "BLOCKED_INTERNAL: "
|
||||||
|
|
||||||
|
# Block known mining pool ports
|
||||||
|
MINING_PORTS="3333 5555 7777 14433 45700 45560 14444 9999"
|
||||||
|
for port in $MINING_PORTS; do
|
||||||
|
iptables -A OUTPUT -p tcp --dport $port -j DROP
|
||||||
|
iptables -A OUTPUT -p tcp --dport $port -j LOG --log-prefix "BLOCKED_MINING: "
|
||||||
|
done
|
||||||
|
|
||||||
|
# Save rules
|
||||||
|
iptables-save > /etc/iptables/rules.v4
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. SSH Hardening
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# /etc/ssh/sshd_config
|
||||||
|
|
||||||
|
# Disable root login with password
|
||||||
|
PermitRootLogin prohibit-password
|
||||||
|
|
||||||
|
# Use only SSH keys
|
||||||
|
PasswordAuthentication no
|
||||||
|
PubkeyAuthentication yes
|
||||||
|
|
||||||
|
# Limit authentication attempts
|
||||||
|
MaxAuthTries 3
|
||||||
|
MaxSessions 5
|
||||||
|
|
||||||
|
# Idle timeout
|
||||||
|
ClientAliveInterval 300
|
||||||
|
ClientAliveCountMax 2
|
||||||
|
|
||||||
|
# Disable unused features
|
||||||
|
X11Forwarding no
|
||||||
|
AllowAgentForwarding no
|
||||||
|
AllowTcpForwarding no
|
||||||
|
|
||||||
|
# Allow only specific users
|
||||||
|
AllowUsers root
|
||||||
|
|
||||||
|
# Use strong ciphers
|
||||||
|
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
|
||||||
|
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Fail2ban Configuration
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# /etc/fail2ban/jail.local
|
||||||
|
|
||||||
|
[DEFAULT]
|
||||||
|
bantime = 3600
|
||||||
|
findtime = 600
|
||||||
|
maxretry = 3
|
||||||
|
|
||||||
|
[sshd]
|
||||||
|
enabled = true
|
||||||
|
port = ssh
|
||||||
|
filter = sshd
|
||||||
|
logpath = /var/log/auth.log
|
||||||
|
maxretry = 3
|
||||||
|
bantime = 86400
|
||||||
|
|
||||||
|
[docker-abuse]
|
||||||
|
enabled = true
|
||||||
|
filter = docker-abuse
|
||||||
|
logpath = /var/log/syslog
|
||||||
|
maxretry = 5
|
||||||
|
bantime = 3600
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔒 Network Security
|
||||||
|
|
||||||
|
### UFW Configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# /root/setup-ufw.sh
|
||||||
|
|
||||||
|
# Reset UFW
|
||||||
|
ufw --force reset
|
||||||
|
|
||||||
|
# Default policies
|
||||||
|
ufw default deny incoming
|
||||||
|
ufw default deny outgoing
|
||||||
|
|
||||||
|
# Allow SSH (from specific IPs if possible)
|
||||||
|
ufw allow in 22/tcp
|
||||||
|
|
||||||
|
# Allow HTTP/HTTPS
|
||||||
|
ufw allow in 80/tcp
|
||||||
|
ufw allow in 443/tcp
|
||||||
|
|
||||||
|
# Allow outbound DNS
|
||||||
|
ufw allow out 53/tcp
|
||||||
|
ufw allow out 53/udp
|
||||||
|
|
||||||
|
# Allow outbound HTTP/HTTPS
|
||||||
|
ufw allow out 80/tcp
|
||||||
|
ufw allow out 443/tcp
|
||||||
|
|
||||||
|
# Allow outbound to Docker registry
|
||||||
|
ufw allow out to any port 443 proto tcp
|
||||||
|
|
||||||
|
# Block mining pools (additional layer)
|
||||||
|
# Add rules from firewall-egress.sh
|
||||||
|
|
||||||
|
# Enable UFW
|
||||||
|
ufw --force enable
|
||||||
|
```
|
||||||
|
|
||||||
|
### Port Exposure Rules
|
||||||
|
|
||||||
|
| Port | Service | Binding | Notes |
|
||||||
|
|------|---------|---------|-------|
|
||||||
|
| 22 | SSH | 0.0.0.0 | With fail2ban |
|
||||||
|
| 80 | Nginx | 0.0.0.0 | Redirect to 443 |
|
||||||
|
| 443 | Nginx | 0.0.0.0 | HTTPS only |
|
||||||
|
| 3000 | daarion-web | 127.0.0.1 | Via Nginx |
|
||||||
|
| 9102 | Router | 127.0.0.1 | Internal |
|
||||||
|
| 9300 | Gateway | 127.0.0.1 | Via Nginx |
|
||||||
|
| * | Other services | 127.0.0.1 | Never public |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Monitoring
|
||||||
|
|
||||||
|
### System Monitoring Script
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# /root/security-monitor.sh
|
||||||
|
# Run via cron every 5 minutes
|
||||||
|
|
||||||
|
LOG_FILE="/var/log/security-monitor.log"
|
||||||
|
ALERT_THRESHOLD_CPU=80
|
||||||
|
ALERT_THRESHOLD_LOAD=10
|
||||||
|
|
||||||
|
timestamp() {
|
||||||
|
date '+%Y-%m-%d %H:%M:%S'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check load average
|
||||||
|
LOAD=$(cat /proc/loadavg | awk '{print $1}')
|
||||||
|
LOAD_INT=${LOAD%.*}
|
||||||
|
|
||||||
|
if [ "$LOAD_INT" -gt "$ALERT_THRESHOLD_LOAD" ]; then
|
||||||
|
echo "[$(timestamp)] ALERT: High load average: $LOAD" >> $LOG_FILE
|
||||||
|
# Send alert (implement your notification)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for mining processes
|
||||||
|
MINING=$(ps aux | grep -iE "xmrig|catcal|softirq|vrarhpb|miner" | grep -v grep)
|
||||||
|
if [ -n "$MINING" ]; then
|
||||||
|
echo "[$(timestamp)] CRITICAL: Mining process detected!" >> $LOG_FILE
|
||||||
|
echo "$MINING" >> $LOG_FILE
|
||||||
|
# Kill the process
|
||||||
|
echo "$MINING" | awk '{print $2}' | xargs -r kill -9
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check outbound connections to mining ports
|
||||||
|
MINING_CONN=$(ss -antp | grep -E ":(3333|5555|7777|14433)")
|
||||||
|
if [ -n "$MINING_CONN" ]; then
|
||||||
|
echo "[$(timestamp)] CRITICAL: Mining pool connection!" >> $LOG_FILE
|
||||||
|
echo "$MINING_CONN" >> $LOG_FILE
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check Docker containers CPU
|
||||||
|
docker stats --no-stream --format "{{.Name}}: {{.CPUPerc}}" | while read line; do
|
||||||
|
CPU=$(echo "$line" | grep -oE '[0-9]+' | head -1)
|
||||||
|
if [ -n "$CPU" ] && [ "$CPU" -gt "$ALERT_THRESHOLD_CPU" ]; then
|
||||||
|
echo "[$(timestamp)] WARNING: High CPU container: $line" >> $LOG_FILE
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cron Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# /etc/cron.d/security-monitor
|
||||||
|
|
||||||
|
# Run security monitor every 5 minutes
|
||||||
|
*/5 * * * * root /root/security-monitor.sh
|
||||||
|
|
||||||
|
# Run persistence scan daily
|
||||||
|
0 3 * * * root /opt/microdao-daarion/security/persistence-scan.sh >> /var/log/persistence-scan.log 2>&1
|
||||||
|
|
||||||
|
# Log rotation
|
||||||
|
0 0 * * * root find /var/log -name "*.log" -mtime +30 -delete
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚨 Incident Response (Hetzner)
|
||||||
|
|
||||||
|
### При отриманні Abuse Report:
|
||||||
|
|
||||||
|
1. **Негайно:**
|
||||||
|
```bash
|
||||||
|
# Заблокувати весь вихідний трафік
|
||||||
|
iptables -I OUTPUT -j DROP
|
||||||
|
|
||||||
|
# Зберегти стан для аналізу
|
||||||
|
ps auxf > /root/incident/ps_$(date +%s).txt
|
||||||
|
ss -antp > /root/incident/ss_$(date +%s).txt
|
||||||
|
docker ps -a > /root/incident/docker_$(date +%s).txt
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Знайти джерело:**
|
||||||
|
```bash
|
||||||
|
# Запустити forensics
|
||||||
|
/opt/microdao-daarion/security/persistence-scan.sh
|
||||||
|
/opt/microdao-daarion/security/runtime-detector.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Усунути загрозу:**
|
||||||
|
```bash
|
||||||
|
# Kill процеси
|
||||||
|
killall -9 <process_name>
|
||||||
|
|
||||||
|
# Видалити контейнер ТА образ
|
||||||
|
docker stop <container>
|
||||||
|
docker rm <container>
|
||||||
|
docker rmi <image> # КРИТИЧНО!
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Відповісти Hetzner:**
|
||||||
|
- URL: https://statement-abuse.hetzner.com/statements/?token=<token>
|
||||||
|
- Описати причину та вжиті заходи
|
||||||
|
- Зареєструвати retry test
|
||||||
|
|
||||||
|
5. **Задокументувати:**
|
||||||
|
- Оновити INFRASTRUCTURE.md
|
||||||
|
- Створити incident report
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔐 Secrets Management
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# /opt/microdao-daarion/.env
|
||||||
|
|
||||||
|
# NEVER commit to git!
|
||||||
|
# Use .env.example as template
|
||||||
|
|
||||||
|
# Generate secure passwords
|
||||||
|
openssl rand -base64 32
|
||||||
|
|
||||||
|
# Store secrets securely
|
||||||
|
chmod 600 .env
|
||||||
|
chown root:root .env
|
||||||
|
```
|
||||||
|
|
||||||
|
### SSH Keys
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate strong SSH key
|
||||||
|
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519
|
||||||
|
|
||||||
|
# Rotate keys periodically
|
||||||
|
# Keep backup of old keys until rotation complete
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Hetzner Security Checklist
|
||||||
|
|
||||||
|
- [ ] Egress firewall blocking internal networks
|
||||||
|
- [ ] Mining pool ports blocked
|
||||||
|
- [ ] SSH hardened (key-only, fail2ban)
|
||||||
|
- [ ] UFW configured (deny by default)
|
||||||
|
- [ ] All services bound to 127.0.0.1 except Nginx
|
||||||
|
- [ ] Security monitoring cron active
|
||||||
|
- [ ] Log rotation configured
|
||||||
|
- [ ] .env file secured (chmod 600)
|
||||||
|
- [ ] Rescue mode access documented
|
||||||
|
- [ ] Hetzner Robot access secured
|
||||||
310
security/hardening/docker.md
Normal file
310
security/hardening/docker.md
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
# 🐳 Docker Security Hardening — DAARION
|
||||||
|
|
||||||
|
**Версія:** 1.0.0
|
||||||
|
**Принцип:** Майнінг можливий тільки там, де дозволений **outbound + CPU без контролю**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Security Checklist
|
||||||
|
|
||||||
|
### Must-Have (Обов'язково)
|
||||||
|
|
||||||
|
| Налаштування | docker-compose | Пояснення |
|
||||||
|
|--------------|----------------|-----------|
|
||||||
|
| Read-only filesystem | `read_only: true` | Запобігає запису malware |
|
||||||
|
| Drop capabilities | `cap_drop: [ALL]` | Мінімальні привілеї |
|
||||||
|
| No new privileges | `security_opt: [no-new-privileges:true]` | Блокує privilege escalation |
|
||||||
|
| CPU limit | `cpus: '1.0'` | Обмежує crypto mining |
|
||||||
|
| Memory limit | `memory: 512M` | Запобігає DoS |
|
||||||
|
| Non-root user | `user: "1001:1001"` | Не root в контейнері |
|
||||||
|
| No privileged | `privileged: false` | Завжди! |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛡️ Secure docker-compose Template
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
secure-service:
|
||||||
|
image: your-image:tag
|
||||||
|
container_name: secure-service
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# SECURITY HARDENING
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
# 1. Restart policy (use "no" until verified)
|
||||||
|
restart: "no" # Change to "unless-stopped" after verification
|
||||||
|
|
||||||
|
# 2. Network binding (localhost only for internal services)
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8080:8080"
|
||||||
|
|
||||||
|
# 3. Read-only root filesystem
|
||||||
|
read_only: true
|
||||||
|
|
||||||
|
# 4. Temporary filesystems (for apps that need write)
|
||||||
|
tmpfs:
|
||||||
|
- /tmp:size=64M,mode=1777
|
||||||
|
- /app/cache:size=128M,mode=1777
|
||||||
|
|
||||||
|
# 5. Drop ALL capabilities
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
|
||||||
|
# 6. Add only what's needed (rarely needed)
|
||||||
|
# cap_add:
|
||||||
|
# - NET_BIND_SERVICE # Only if port < 1024
|
||||||
|
|
||||||
|
# 7. Security options
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
|
# 8. Resource limits
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '1.0'
|
||||||
|
memory: 512M
|
||||||
|
reservations:
|
||||||
|
cpus: '0.25'
|
||||||
|
memory: 128M
|
||||||
|
|
||||||
|
# 9. Process limits
|
||||||
|
pids_limit: 100
|
||||||
|
|
||||||
|
# 10. Disable privileged mode
|
||||||
|
privileged: false
|
||||||
|
|
||||||
|
# 11. Non-root user
|
||||||
|
user: "1001:1001"
|
||||||
|
|
||||||
|
# 12. Health check
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
# 13. Logging limits
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
|
# 14. Labels for audit
|
||||||
|
labels:
|
||||||
|
- "security.hardened=true"
|
||||||
|
- "security.reviewed=2026-01-09"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
driver: bridge
|
||||||
|
driver_opts:
|
||||||
|
com.docker.network.bridge.enable_icc: "false" # Disable inter-container communication
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Secure Dockerfile Template
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
# ============================================
|
||||||
|
# Stage 1: Builder
|
||||||
|
# ============================================
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy only package files first (cache optimization)
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm ci --only=production --ignore-scripts
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Stage 2: Production (minimal)
|
||||||
|
# ============================================
|
||||||
|
FROM node:20-alpine AS production
|
||||||
|
|
||||||
|
# Security: Create non-root user
|
||||||
|
RUN addgroup -g 1001 -S appgroup && \
|
||||||
|
adduser -u 1001 -S appuser -G appgroup
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Security: Remove unnecessary tools
|
||||||
|
RUN apk del --purge wget curl busybox-extras && \
|
||||||
|
rm -rf /var/cache/apk/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
|
# Copy from builder
|
||||||
|
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
|
||||||
|
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
|
||||||
|
COPY --from=builder --chown=appuser:appgroup /app/package.json ./
|
||||||
|
|
||||||
|
# Security: Restrictive permissions
|
||||||
|
RUN chmod -R 500 /app && \
|
||||||
|
chmod 400 /app/package.json
|
||||||
|
|
||||||
|
# Switch to non-root
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||||||
|
CMD node -e "require('http').get('http://localhost:8080/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
CMD ["node", "dist/server.js"]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚫 Anti-Patterns (НЕ робіть)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# ❌ NEVER DO THIS:
|
||||||
|
|
||||||
|
services:
|
||||||
|
insecure:
|
||||||
|
privileged: true # ❌ Full host access
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- "8080:8080" # ❌ Binds to 0.0.0.0 (public)
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- /:/host # ❌ Full host filesystem
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock # ❌ Docker escape
|
||||||
|
|
||||||
|
cap_add:
|
||||||
|
- SYS_ADMIN # ❌ Too powerful
|
||||||
|
- NET_ADMIN # ❌ Network manipulation
|
||||||
|
|
||||||
|
restart: unless-stopped # ❌ Without verification
|
||||||
|
|
||||||
|
# No resource limits # ❌ Crypto mining possible
|
||||||
|
# No read_only # ❌ Malware can persist
|
||||||
|
# No user specification # ❌ Runs as root
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Security Scanning
|
||||||
|
|
||||||
|
### Pre-deployment scan
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install Trivy
|
||||||
|
brew install trivy # macOS
|
||||||
|
apt install trivy # Ubuntu
|
||||||
|
|
||||||
|
# Scan image for vulnerabilities
|
||||||
|
trivy image --severity HIGH,CRITICAL your-image:tag
|
||||||
|
|
||||||
|
# Scan with detailed output
|
||||||
|
trivy image --format json -o scan-report.json your-image:tag
|
||||||
|
|
||||||
|
# Scan Dockerfile
|
||||||
|
trivy config Dockerfile
|
||||||
|
```
|
||||||
|
|
||||||
|
### CI/CD Integration
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# .github/workflows/security-scan.yml
|
||||||
|
name: Security Scan
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
scan:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Build image
|
||||||
|
run: docker build -t app:${{ github.sha }} .
|
||||||
|
|
||||||
|
- name: Run Trivy scan
|
||||||
|
uses: aquasecurity/trivy-action@master
|
||||||
|
with:
|
||||||
|
image-ref: 'app:${{ github.sha }}'
|
||||||
|
format: 'table'
|
||||||
|
exit-code: '1'
|
||||||
|
severity: 'HIGH,CRITICAL'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 Runtime Monitoring
|
||||||
|
|
||||||
|
### Container inspection
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check container security settings
|
||||||
|
docker inspect --format='
|
||||||
|
Privileged: {{.HostConfig.Privileged}}
|
||||||
|
ReadonlyRootfs: {{.HostConfig.ReadonlyRootfs}}
|
||||||
|
User: {{.Config.User}}
|
||||||
|
CapDrop: {{.HostConfig.CapDrop}}
|
||||||
|
CapAdd: {{.HostConfig.CapAdd}}
|
||||||
|
' container_name
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resource monitoring
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Real-time stats
|
||||||
|
docker stats container_name
|
||||||
|
|
||||||
|
# CPU limit check
|
||||||
|
docker inspect --format='{{.HostConfig.NanoCpus}}' container_name
|
||||||
|
|
||||||
|
# Memory limit check
|
||||||
|
docker inspect --format='{{.HostConfig.Memory}}' container_name
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 DAARION-specific Rules
|
||||||
|
|
||||||
|
### Services that MUST have hardening:
|
||||||
|
|
||||||
|
| Service | Priority | Notes |
|
||||||
|
|---------|----------|-------|
|
||||||
|
| daarion-web | 🔴 Critical | Post-incident, see Dockerfile.secure |
|
||||||
|
| dagi-gateway | 🔴 Critical | Public-facing |
|
||||||
|
| dagi-router | 🟡 High | Core routing |
|
||||||
|
| All others | 🟡 High | Apply baseline |
|
||||||
|
|
||||||
|
### Network rules:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Internal services: bind to localhost
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:PORT:PORT"
|
||||||
|
|
||||||
|
# Public services: use Nginx reverse proxy
|
||||||
|
# Never expose directly to 0.0.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Verification Checklist
|
||||||
|
|
||||||
|
Before deploying any container:
|
||||||
|
|
||||||
|
- [ ] Image scanned with Trivy (no HIGH/CRITICAL)
|
||||||
|
- [ ] `read_only: true` set
|
||||||
|
- [ ] `cap_drop: [ALL]` set
|
||||||
|
- [ ] `security_opt: [no-new-privileges:true]` set
|
||||||
|
- [ ] CPU/memory limits set
|
||||||
|
- [ ] Non-root user configured
|
||||||
|
- [ ] Health check defined
|
||||||
|
- [ ] Restart policy is "no" for new deployments
|
||||||
|
- [ ] Port bound to 127.0.0.1 (unless public)
|
||||||
|
- [ ] No privileged mode
|
||||||
|
- [ ] No dangerous volume mounts
|
||||||
316
security/hardening/kubernetes.md
Normal file
316
security/hardening/kubernetes.md
Normal file
@@ -0,0 +1,316 @@
|
|||||||
|
# ☸️ Kubernetes Security Hardening — DAARION
|
||||||
|
|
||||||
|
**Версія:** 1.0.0
|
||||||
|
**Статус:** Reference (для майбутньої K8s міграції)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Критичні налаштування
|
||||||
|
|
||||||
|
### 1. NetworkPolicy (Egress deny-by-default)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default-deny-egress
|
||||||
|
namespace: daarion
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Egress
|
||||||
|
egress: [] # Deny all outbound by default
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-dns-only
|
||||||
|
namespace: daarion
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Egress
|
||||||
|
egress:
|
||||||
|
- to:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
name: kube-system
|
||||||
|
ports:
|
||||||
|
- protocol: UDP
|
||||||
|
port: 53
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. PodSecurityStandard: Restricted
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: daarion
|
||||||
|
labels:
|
||||||
|
pod-security.kubernetes.io/enforce: restricted
|
||||||
|
pod-security.kubernetes.io/audit: restricted
|
||||||
|
pod-security.kubernetes.io/warn: restricted
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Secure Pod Template
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: secure-pod
|
||||||
|
namespace: daarion
|
||||||
|
spec:
|
||||||
|
# Security Context (Pod level)
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1001
|
||||||
|
runAsGroup: 1001
|
||||||
|
fsGroup: 1001
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
|
||||||
|
# Service Account
|
||||||
|
serviceAccountName: minimal-sa
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
|
||||||
|
containers:
|
||||||
|
- name: app
|
||||||
|
image: your-image:tag
|
||||||
|
|
||||||
|
# Security Context (Container level)
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1001
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
|
||||||
|
# Resource limits (CRITICAL for anti-mining)
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "128Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "1000m" # Max 1 CPU
|
||||||
|
memory: "512Mi"
|
||||||
|
|
||||||
|
# Liveness/Readiness probes
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 30
|
||||||
|
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /ready
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
|
||||||
|
# Volume mounts (if needed)
|
||||||
|
volumeMounts:
|
||||||
|
- name: tmp
|
||||||
|
mountPath: /tmp
|
||||||
|
- name: cache
|
||||||
|
mountPath: /app/cache
|
||||||
|
|
||||||
|
# Temporary volumes
|
||||||
|
volumes:
|
||||||
|
- name: tmp
|
||||||
|
emptyDir:
|
||||||
|
sizeLimit: 64Mi
|
||||||
|
- name: cache
|
||||||
|
emptyDir:
|
||||||
|
sizeLimit: 128Mi
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛡️ Security Policies
|
||||||
|
|
||||||
|
### ResourceQuota (Namespace limits)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ResourceQuota
|
||||||
|
metadata:
|
||||||
|
name: daarion-quota
|
||||||
|
namespace: daarion
|
||||||
|
spec:
|
||||||
|
hard:
|
||||||
|
requests.cpu: "10"
|
||||||
|
requests.memory: 20Gi
|
||||||
|
limits.cpu: "20"
|
||||||
|
limits.memory: 40Gi
|
||||||
|
pods: "50"
|
||||||
|
```
|
||||||
|
|
||||||
|
### LimitRange (Default limits)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: LimitRange
|
||||||
|
metadata:
|
||||||
|
name: daarion-limits
|
||||||
|
namespace: daarion
|
||||||
|
spec:
|
||||||
|
limits:
|
||||||
|
- type: Container
|
||||||
|
default:
|
||||||
|
cpu: "500m"
|
||||||
|
memory: "256Mi"
|
||||||
|
defaultRequest:
|
||||||
|
cpu: "100m"
|
||||||
|
memory: "128Mi"
|
||||||
|
max:
|
||||||
|
cpu: "2"
|
||||||
|
memory: "1Gi"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 Runtime Detection (Falco)
|
||||||
|
|
||||||
|
### Falco Rule: Crypto Mining Detection
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# falco-rules.yaml
|
||||||
|
- rule: Detect Crypto Mining Process
|
||||||
|
desc: Detect processes commonly used for cryptocurrency mining
|
||||||
|
condition: >
|
||||||
|
spawned_process and
|
||||||
|
(proc.name in (xmrig, minerd, cpuminer, cgminer, bfgminer, ethminer,
|
||||||
|
catcal, softirq, vrarhpb, G4NQXBp) or
|
||||||
|
proc.cmdline contains "stratum+" or
|
||||||
|
proc.cmdline contains "pool" or
|
||||||
|
proc.cmdline contains "cryptonight")
|
||||||
|
output: >
|
||||||
|
Crypto mining process detected
|
||||||
|
(user=%user.name command=%proc.cmdline container=%container.name
|
||||||
|
image=%container.image.repository)
|
||||||
|
priority: CRITICAL
|
||||||
|
tags: [cryptomining, mitre_execution]
|
||||||
|
|
||||||
|
- rule: Detect Connection to Mining Pool
|
||||||
|
desc: Detect outbound connections to known mining pool ports
|
||||||
|
condition: >
|
||||||
|
outbound and
|
||||||
|
(fd.sport in (3333, 5555, 7777, 14433, 45700, 45560, 14444, 9999))
|
||||||
|
output: >
|
||||||
|
Connection to potential mining pool
|
||||||
|
(user=%user.name command=%proc.cmdline connection=%fd.name
|
||||||
|
container=%container.name)
|
||||||
|
priority: CRITICAL
|
||||||
|
tags: [cryptomining, network]
|
||||||
|
|
||||||
|
- rule: High CPU in Container
|
||||||
|
desc: Detect containers with sustained high CPU usage
|
||||||
|
condition: >
|
||||||
|
container and
|
||||||
|
container.cpu.usage > 80
|
||||||
|
output: >
|
||||||
|
High CPU usage in container
|
||||||
|
(container=%container.name cpu=%container.cpu.usage%)
|
||||||
|
priority: WARNING
|
||||||
|
tags: [performance, cryptomining]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Falco Deployment
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: DaemonSet
|
||||||
|
metadata:
|
||||||
|
name: falco
|
||||||
|
namespace: falco
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: falco
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: falco
|
||||||
|
spec:
|
||||||
|
serviceAccountName: falco
|
||||||
|
containers:
|
||||||
|
- name: falco
|
||||||
|
image: falcosecurity/falco:latest
|
||||||
|
securityContext:
|
||||||
|
privileged: true
|
||||||
|
volumeMounts:
|
||||||
|
- name: proc
|
||||||
|
mountPath: /host/proc
|
||||||
|
readOnly: true
|
||||||
|
- name: rules
|
||||||
|
mountPath: /etc/falco/rules.d
|
||||||
|
volumes:
|
||||||
|
- name: proc
|
||||||
|
hostPath:
|
||||||
|
path: /proc
|
||||||
|
- name: rules
|
||||||
|
configMap:
|
||||||
|
name: falco-rules
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Monitoring & Alerting
|
||||||
|
|
||||||
|
### Prometheus Rules
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: monitoring.coreos.com/v1
|
||||||
|
kind: PrometheusRule
|
||||||
|
metadata:
|
||||||
|
name: daarion-security-rules
|
||||||
|
namespace: monitoring
|
||||||
|
spec:
|
||||||
|
groups:
|
||||||
|
- name: security
|
||||||
|
rules:
|
||||||
|
- alert: HighCPUUsage
|
||||||
|
expr: >
|
||||||
|
sum(rate(container_cpu_usage_seconds_total{namespace="daarion"}[5m]))
|
||||||
|
by (pod) > 0.8
|
||||||
|
for: 5m
|
||||||
|
labels:
|
||||||
|
severity: warning
|
||||||
|
annotations:
|
||||||
|
summary: "High CPU usage in pod {{ $labels.pod }}"
|
||||||
|
|
||||||
|
- alert: UnauthorizedNetworkConnection
|
||||||
|
expr: >
|
||||||
|
increase(falco_events_total{rule=~".*mining.*"}[5m]) > 0
|
||||||
|
for: 1m
|
||||||
|
labels:
|
||||||
|
severity: critical
|
||||||
|
annotations:
|
||||||
|
summary: "Potential crypto mining detected"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ K8s Security Checklist
|
||||||
|
|
||||||
|
Before deploying to Kubernetes:
|
||||||
|
|
||||||
|
- [ ] Namespace has PodSecurityStandard: restricted
|
||||||
|
- [ ] NetworkPolicy: deny egress by default
|
||||||
|
- [ ] All pods have resource limits
|
||||||
|
- [ ] All pods run as non-root
|
||||||
|
- [ ] All pods have readOnlyRootFilesystem
|
||||||
|
- [ ] All pods drop ALL capabilities
|
||||||
|
- [ ] seccompProfile: RuntimeDefault
|
||||||
|
- [ ] No privileged containers
|
||||||
|
- [ ] ServiceAccount tokens not auto-mounted
|
||||||
|
- [ ] Falco or similar runtime detection deployed
|
||||||
|
- [ ] Resource quotas set on namespace
|
||||||
170
security/persistence-scan.sh
Executable file
170
security/persistence-scan.sh
Executable file
@@ -0,0 +1,170 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ============================================
|
||||||
|
# Persistence Scanner — DAARION Security
|
||||||
|
# Version: 1.0.0
|
||||||
|
# Purpose: Quick detection of persistence mechanisms
|
||||||
|
# Usage: ./persistence-scan.sh
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo -e "${BLUE}============================================${NC}"
|
||||||
|
echo -e "${BLUE} DAARION Persistence Scanner${NC}"
|
||||||
|
echo -e "${BLUE}============================================${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
FINDINGS=0
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 1. Cron Jobs
|
||||||
|
# ============================================
|
||||||
|
echo -e "${YELLOW}[1/7] Checking cron jobs...${NC}"
|
||||||
|
|
||||||
|
echo "User crontab:"
|
||||||
|
crontab -l 2>/dev/null || echo " (none)"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "System cron directories:"
|
||||||
|
for dir in /etc/cron.d /etc/cron.daily /etc/cron.hourly /etc/cron.weekly /etc/cron.monthly; do
|
||||||
|
if [ -d "$dir" ]; then
|
||||||
|
count=$(ls -1 "$dir" 2>/dev/null | wc -l)
|
||||||
|
echo " $dir: $count files"
|
||||||
|
if [ $count -gt 0 ]; then
|
||||||
|
ls -la "$dir" 2>/dev/null | grep -v "^total" | head -10
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 2. Systemd Services
|
||||||
|
# ============================================
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}[2/7] Checking systemd services...${NC}"
|
||||||
|
|
||||||
|
echo "Enabled services (excluding common):"
|
||||||
|
systemctl list-unit-files --state=enabled 2>/dev/null | \
|
||||||
|
grep -vE "(ssh|network|system|docker|cron|rsyslog|ufw|fail2ban|nginx)" | \
|
||||||
|
head -20
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Custom services in /etc/systemd/system:"
|
||||||
|
ls -la /etc/systemd/system/*.service 2>/dev/null | grep -v "wants" | head -10 || echo " (none)"
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 3. Suspicious Executables
|
||||||
|
# ============================================
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}[3/7] Checking for suspicious executables...${NC}"
|
||||||
|
|
||||||
|
echo "Executables in /tmp, /var/tmp, /dev/shm:"
|
||||||
|
SUSPICIOUS_EXEC=$(find /tmp /var/tmp /dev/shm -type f -executable 2>/dev/null)
|
||||||
|
if [ -n "$SUSPICIOUS_EXEC" ]; then
|
||||||
|
echo -e "${RED}⚠️ FOUND:${NC}"
|
||||||
|
echo "$SUSPICIOUS_EXEC"
|
||||||
|
FINDINGS=$((FINDINGS + 1))
|
||||||
|
else
|
||||||
|
echo -e " ${GREEN}(none)${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Recently modified binaries (last 3 days):"
|
||||||
|
MODIFIED_BIN=$(find /usr/bin /usr/local/bin /usr/sbin -mtime -3 -type f 2>/dev/null)
|
||||||
|
if [ -n "$MODIFIED_BIN" ]; then
|
||||||
|
echo -e "${YELLOW}Modified:${NC}"
|
||||||
|
echo "$MODIFIED_BIN" | head -10
|
||||||
|
else
|
||||||
|
echo -e " ${GREEN}(none)${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 4. High CPU Processes
|
||||||
|
# ============================================
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}[4/7] Checking high CPU processes...${NC}"
|
||||||
|
|
||||||
|
echo "Top 15 by CPU:"
|
||||||
|
ps -eo pid,user,cmd,%cpu --sort=-%cpu | head -n 16
|
||||||
|
|
||||||
|
# Check for known mining process names
|
||||||
|
MINING_PATTERNS="xmrig|catcal|softirq|vrarhpb|G4NQXBp|kswapd|ksoftirqd|kworker.*mining|cryptonight"
|
||||||
|
MINING_PROC=$(ps aux | grep -iE "$MINING_PATTERNS" | grep -v grep)
|
||||||
|
if [ -n "$MINING_PROC" ]; then
|
||||||
|
echo ""
|
||||||
|
echo -e "${RED}⚠️ POTENTIAL MINING PROCESSES DETECTED:${NC}"
|
||||||
|
echo "$MINING_PROC"
|
||||||
|
FINDINGS=$((FINDINGS + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 5. Network Connections
|
||||||
|
# ============================================
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}[5/7] Checking network connections...${NC}"
|
||||||
|
|
||||||
|
echo "Outbound connections:"
|
||||||
|
ss -antp 2>/dev/null | grep ESTAB | grep -v "127.0.0.1" | head -20
|
||||||
|
|
||||||
|
# Check for connections to known mining ports
|
||||||
|
MINING_PORTS="3333|5555|7777|14433|45700|45560"
|
||||||
|
MINING_CONN=$(ss -antp 2>/dev/null | grep -E ":($MINING_PORTS)")
|
||||||
|
if [ -n "$MINING_CONN" ]; then
|
||||||
|
echo ""
|
||||||
|
echo -e "${RED}⚠️ POTENTIAL MINING POOL CONNECTIONS:${NC}"
|
||||||
|
echo "$MINING_CONN"
|
||||||
|
FINDINGS=$((FINDINGS + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 6. Docker Containers
|
||||||
|
# ============================================
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}[6/7] Checking Docker containers...${NC}"
|
||||||
|
|
||||||
|
if command -v docker &> /dev/null; then
|
||||||
|
echo "Containers with auto-restart:"
|
||||||
|
docker ps -a --filter "restart=always" --filter "restart=unless-stopped" --format "{{.Names}}: {{.Status}}" 2>/dev/null || echo " (none)"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "All running containers:"
|
||||||
|
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}" 2>/dev/null || echo " Docker not available"
|
||||||
|
else
|
||||||
|
echo " Docker not installed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 7. SSH Keys
|
||||||
|
# ============================================
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}[7/7] Checking SSH keys...${NC}"
|
||||||
|
|
||||||
|
echo "Authorized keys for root:"
|
||||||
|
if [ -f /root/.ssh/authorized_keys ]; then
|
||||||
|
wc -l /root/.ssh/authorized_keys
|
||||||
|
echo "Keys:"
|
||||||
|
cat /root/.ssh/authorized_keys | cut -d' ' -f3 | head -5
|
||||||
|
else
|
||||||
|
echo " (no authorized_keys file)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Summary
|
||||||
|
# ============================================
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}============================================${NC}"
|
||||||
|
if [ $FINDINGS -gt 0 ]; then
|
||||||
|
echo -e "${RED} ⚠️ FINDINGS: $FINDINGS potential issues${NC}"
|
||||||
|
echo -e "${RED} Review the output above carefully!${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN} ✓ No obvious persistence mechanisms found${NC}"
|
||||||
|
fi
|
||||||
|
echo -e "${BLUE}============================================${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "For detailed investigation, see:"
|
||||||
|
echo " security/forensics-checklist.md"
|
||||||
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