Files
microdao-daarion/SECURITY-HARDENING-PLAN.md
Apple 1231647f94 🛡️ Add comprehensive Security Hardening Plan
- Created SECURITY-HARDENING-PLAN.md with 6 security levels
- Added setup-node1-security.sh for automated hardening
- Added scan-image.sh for pre-deployment image scanning
- Created docker-compose.secure.yml template
- Includes: Trivy, fail2ban, UFW, auditd, rkhunter, chkrootkit
- Network isolation, egress filtering, process monitoring
- Incident response procedures and recovery playbook
2026-01-10 05:05:21 -08:00

714 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🛡️ Security Hardening Plan — DAARION & MicroDAO
**Версія:** 1.0.0
**Дата:** 2026-01-10
**Статус:** В процесі впровадження
---
## 📋 Зміст
1. [Аналіз інцидентів](#аналіз-інцидентів)
2. [Рівень 1: Image Security](#рівень-1-image-security)
3. [Рівень 2: Container Runtime Security](#рівень-2-container-runtime-security)
4. [Рівень 3: Host Security](#рівень-3-host-security)
5. [Рівень 4: Network Security](#рівень-4-network-security)
6. [Рівень 5: Monitoring & Detection](#рівень-5-monitoring--detection)
7. [Рівень 6: Incident Response](#рівень-6-incident-response)
8. [Чеклист впровадження](#чеклист-впровадження)
---
## 📊 Аналіз інцидентів
### Що пішло не так:
| Інцидент | Вектор атаки | Чому не виявили раніше |
|----------|--------------|------------------------|
| #1 | Вразливий `daarion-web` образ | Не сканували образи |
| #2 | `restart: unless-stopped` | Не видалили image, тільки container |
| #3 | Compromised postgres image | Довіряли Docker Hub без перевірки |
| #4 | Host persistence (perfctl) | Не перевіряли host на malware |
### Ключові уроки:
1. 🔴 **Не довіряти жодному образу** — навіть official
2. 🟡 **Сканувати ВСЕ** — images, containers, host
3. 🟢 **Моніторити в реальному часі** — CPU, network, processes
4. 🔵 **Мати план відновлення** — швидкий rebuild з нуля
---
## 🔒 Рівень 1: Image Security
### 1.1 Image Scanning (Trivy)
```bash
# Встановлення Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
# Сканування перед pull
trivy image --severity HIGH,CRITICAL postgres:16-alpine
# Автоматичне сканування в CI/CD
trivy image --exit-code 1 --severity CRITICAL $IMAGE_NAME
```
### 1.2 Image Pinning by SHA256
**❌ НІКОЛИ:**
```yaml
image: postgres:16-alpine # Тег може змінитись!
```
**✅ ЗАВЖДИ:**
```yaml
image: postgres@sha256:abc123... # Фіксований digest
```
### 1.3 Allowlist Registry
```yaml
# /etc/docker/daemon.json
{
"allowed-registries": [
"docker.io/library",
"ghcr.io/daarion-dao"
]
}
```
### 1.4 Custom Base Images
Створити власні базові образи з мінімальним attack surface:
```dockerfile
# Dockerfile.postgres-secure
FROM postgres:16-alpine@sha256:verified_digest
# Remove unnecessary packages
RUN apk del --purge wget curl busybox-extras
# Add security scanning
COPY --from=aquasec/trivy:latest /usr/local/bin/trivy /usr/local/bin/trivy
# Non-root user
USER postgres
# Read-only filesystem
# (set in docker-compose)
```
---
## 🐳 Рівень 2: Container Runtime Security
### 2.1 Security Options
```yaml
# docker-compose.yml
services:
postgres:
image: postgres@sha256:verified_digest
# ⚠️ НІКОЛИ auto-restart для нових сервісів
restart: "no" # Змінити на "unless-stopped" ТІЛЬКИ після верифікації
# Security options
security_opt:
- no-new-privileges:true
- seccomp:seccomp-profile.json
# Read-only root filesystem
read_only: true
# Temporary directories
tmpfs:
- /tmp:noexec,nosuid,nodev,size=100m
- /var/run/postgresql:noexec,nosuid,nodev
# Resource limits
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
# Drop all capabilities, add only needed
cap_drop:
- ALL
cap_add:
- CHOWN
- SETUID
- SETGID
# No privileged mode
privileged: false
# User namespace
userns_mode: "host"
```
### 2.2 Seccomp Profile
```json
// seccomp-profile.json
{
"defaultAction": "SCCOMP_ACT_ERRNO",
"syscalls": [
{
"names": ["accept", "bind", "clone", "close", "connect", ...],
"action": "SCCOMP_ACT_ALLOW"
}
]
}
```
### 2.3 AppArmor Profile
```bash
# /etc/apparmor.d/docker-postgres
profile docker-postgres flags=(attach_disconnected) {
# Deny network raw access
deny network raw,
# Deny ptrace
deny ptrace,
# Allow only postgres paths
/var/lib/postgresql/** rw,
/var/run/postgresql/** rw,
# Deny /tmp execution
deny /tmp/** x,
}
```
---
## 🖥️ Рівень 3: Host Security
### 3.1 Hardening Script
```bash
#!/bin/bash
# /opt/scripts/harden-host.sh
set -e
echo "🔒 Hardening NODE1..."
# 1. Update system
apt update && apt upgrade -y
# 2. Install security tools
apt install -y \
fail2ban \
ufw \
auditd \
rkhunter \
chkrootkit \
lynis \
aide
# 3. Configure fail2ban
cat > /etc/fail2ban/jail.local << 'EOF'
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
[docker-abuse]
enabled = true
filter = docker-abuse
logpath = /var/log/docker.log
maxretry = 5
bantime = 86400
EOF
# 4. Configure UFW
ufw default deny incoming
ufw default deny outgoing # ⚠️ Strict egress!
ufw allow 22/tcp # SSH
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw allow out 53/udp # DNS
ufw allow out 443/tcp # HTTPS out (for updates)
ufw allow out 80/tcp # HTTP out (for updates)
# Block internal networks
ufw deny out to 10.0.0.0/8
ufw deny out to 172.16.0.0/12
ufw deny out to 192.168.0.0/16
ufw enable
# 5. Kernel hardening
cat >> /etc/sysctl.conf << 'EOF'
# Disable IP forwarding
net.ipv4.ip_forward = 0
# Disable ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
# Enable SYN cookies
net.ipv4.tcp_syncookies = 1
# Disable source routing
net.ipv4.conf.all.accept_source_route = 0
# Log martians
net.ipv4.conf.all.log_martians = 1
EOF
sysctl -p
# 6. Audit rules
cat > /etc/audit/rules.d/docker.rules << 'EOF'
# Monitor Docker daemon
-w /usr/bin/docker -p rwxa -k docker
-w /var/lib/docker -p rwxa -k docker
-w /etc/docker -p rwxa -k docker
# Monitor /tmp for executables
-w /tmp -p x -k tmp_exec
# Monitor network connections
-a exit,always -F arch=b64 -S connect -k network
EOF
service auditd restart
# 7. Initialize AIDE (file integrity)
aideinit
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
echo "✅ Hardening complete!"
```
### 3.2 Automated Security Checks
```bash
#!/bin/bash
# /opt/scripts/security-check.sh
# Run via cron every hour
LOG="/var/log/security-check.log"
ALERT_EMAIL="admin@daarion.city"
echo "$(date) - Starting security check" >> $LOG
# 1. Check for suspicious processes
SUSPICIOUS=$(ps aux | grep -E "(xmrig|kdevtmp|kinsing|perfctl|httpd.*tmp)" | grep -v grep)
if [ -n "$SUSPICIOUS" ]; then
echo "🚨 ALERT: Suspicious process found!" >> $LOG
echo "$SUSPICIOUS" >> $LOG
# Kill and alert
pkill -9 -f "xmrig|kdevtmp|kinsing|perfctl"
echo "$SUSPICIOUS" | mail -s "🚨 NODE1 ALERT: Suspicious process" $ALERT_EMAIL
fi
# 2. Check /tmp for executables
TMP_EXEC=$(find /tmp -type f -executable 2>/dev/null)
if [ -n "$TMP_EXEC" ]; then
echo "🚨 ALERT: Executable in /tmp!" >> $LOG
echo "$TMP_EXEC" >> $LOG
rm -f $TMP_EXEC
echo "$TMP_EXEC" | mail -s "🚨 NODE1 ALERT: Executable in /tmp" $ALERT_EMAIL
fi
# 3. Check CPU load
LOAD=$(uptime | awk -F'load average:' '{print $2}' | cut -d',' -f1 | tr -d ' ')
if (( $(echo "$LOAD > 5" | bc -l) )); then
echo "⚠️ WARNING: High CPU load: $LOAD" >> $LOG
TOP_PROCS=$(ps aux --sort=-%cpu | head -5)
echo "$TOP_PROCS" | mail -s "⚠️ NODE1 WARNING: High CPU load" $ALERT_EMAIL
fi
# 4. Check for rootkits
rkhunter --check --skip-keypress --quiet
RKHUNTER_STATUS=$?
if [ $RKHUNTER_STATUS -ne 0 ]; then
echo "🚨 ALERT: Rootkit detected!" >> $LOG
rkhunter --check --skip-keypress | mail -s "🚨 NODE1 ALERT: Rootkit detected" $ALERT_EMAIL
fi
# 5. Check file integrity
aide --check > /tmp/aide_check.txt 2>&1
if grep -q "changed" /tmp/aide_check.txt; then
echo "⚠️ WARNING: File integrity changed" >> $LOG
cat /tmp/aide_check.txt | mail -s "⚠️ NODE1 WARNING: File integrity" $ALERT_EMAIL
fi
# 6. Check Docker containers
UNKNOWN_CONTAINERS=$(docker ps --format '{{.Names}}' | grep -v -E "(dagi-|postgres|redis|neo4j|qdrant|grafana|prometheus)")
if [ -n "$UNKNOWN_CONTAINERS" ]; then
echo "🚨 ALERT: Unknown containers running!" >> $LOG
echo "$UNKNOWN_CONTAINERS" >> $LOG
fi
echo "$(date) - Security check complete" >> $LOG
```
### 3.3 Cron Setup
```bash
# /etc/cron.d/security
# Security checks
0 * * * * root /opt/scripts/security-check.sh
*/15 * * * * root /opt/scripts/monitor-docker.sh
# Daily scans
0 3 * * * root rkhunter --update && rkhunter --check --skip-keypress
0 4 * * * root chkrootkit > /var/log/chkrootkit.log
0 5 * * * root lynis audit system --quiet
# Weekly
0 2 * * 0 root aide --check > /var/log/aide-weekly.log
```
---
## 🌐 Рівень 4: Network Security
### 4.1 Docker Network Isolation
```yaml
# docker-compose.yml
networks:
frontend:
driver: bridge
internal: false # Can access internet
backend:
driver: bridge
internal: true # No internet access!
database:
driver: bridge
internal: true # No internet access!
services:
nginx:
networks:
- frontend
router:
networks:
- frontend
- backend
postgres:
networks:
- database # Only database network!
```
### 4.2 Egress Filtering
```bash
#!/bin/bash
# /opt/scripts/setup-egress-firewall.sh
# Default deny outgoing
iptables -P OUTPUT DROP
# Allow established connections
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow loopback
iptables -A OUTPUT -o lo -j ACCEPT
# Allow DNS
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
# Allow HTTPS (for updates, API calls)
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
# Allow HTTP (for Let's Encrypt)
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
# Allow NTP
iptables -A OUTPUT -p udp --dport 123 -j ACCEPT
# Block internal networks (Hetzner)
iptables -A OUTPUT -d 10.0.0.0/8 -j DROP
iptables -A OUTPUT -d 172.16.0.0/12 -j DROP
# Log dropped packets
iptables -A OUTPUT -j LOG --log-prefix "DROPPED_EGRESS: "
# Save
iptables-save > /etc/iptables/rules.v4
```
### 4.3 Mining Pool Blocking
```bash
# /etc/hosts.deny additions
# Block known mining pools
0.0.0.0 pool.minexmr.com
0.0.0.0 xmr.pool.minergate.com
0.0.0.0 xmrpool.eu
0.0.0.0 pool.supportxmr.com
0.0.0.0 xmr-eu1.nanopool.org
0.0.0.0 xmr-eu2.nanopool.org
0.0.0.0 xmr.2miners.com
0.0.0.0 pool.hashvault.pro
```
---
## 📊 Рівень 5: Monitoring & Detection
### 5.1 Real-time Process Monitoring
```python
#!/usr/bin/env python3
# /opt/scripts/process-monitor.py
import psutil
import time
import subprocess
import smtplib
from email.mime.text import MIMEText
SUSPICIOUS_NAMES = [
'xmrig', 'kdevtmp', 'kinsing', 'perfctl', 'httpd',
'softirq', 'vrarhpb', 'cpioshuf', 'ipcalc', 'mysql'
]
ALERT_EMAIL = "admin@daarion.city"
CPU_THRESHOLD = 80 # Alert if process uses >80% CPU
def send_alert(subject, body):
"""Send email alert"""
# Implement email sending
print(f"ALERT: {subject}\n{body}")
def check_processes():
"""Check for suspicious processes"""
for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'cmdline']):
try:
name = proc.info['name'].lower()
cmdline = ' '.join(proc.info['cmdline'] or []).lower()
cpu = proc.info['cpu_percent']
# Check suspicious names
for suspicious in SUSPICIOUS_NAMES:
if suspicious in name or suspicious in cmdline:
send_alert(
f"🚨 Suspicious process: {name}",
f"PID: {proc.info['pid']}\nCPU: {cpu}%\nCmd: {cmdline}"
)
# Kill it
proc.kill()
return
# Check high CPU
if cpu > CPU_THRESHOLD:
send_alert(
f"⚠️ High CPU process: {name}",
f"PID: {proc.info['pid']}\nCPU: {cpu}%"
)
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass
def check_network():
"""Check for suspicious network connections"""
connections = psutil.net_connections()
for conn in connections:
if conn.status == 'ESTABLISHED':
# Check for mining pool ports
if conn.raddr and conn.raddr.port in [3333, 4444, 5555, 8080, 8888]:
send_alert(
f"🚨 Suspicious connection to port {conn.raddr.port}",
f"Remote: {conn.raddr}\nPID: {conn.pid}"
)
if __name__ == "__main__":
while True:
check_processes()
check_network()
time.sleep(10) # Check every 10 seconds
```
### 5.2 Docker Event Monitoring
```bash
#!/bin/bash
# /opt/scripts/monitor-docker.sh
# Monitor Docker events in real-time
docker events --filter 'type=container' --format '{{.Time}} {{.Action}} {{.Actor.Attributes.name}}' | while read event; do
echo "$event" >> /var/log/docker-events.log
# Alert on suspicious events
if echo "$event" | grep -qE "(start|create)"; then
CONTAINER=$(echo "$event" | awk '{print $3}')
# Check if container is in allowlist
if ! grep -q "$CONTAINER" /opt/config/allowed-containers.txt; then
echo "🚨 Unknown container started: $CONTAINER" | mail -s "NODE1 ALERT" admin@daarion.city
fi
fi
done
```
### 5.3 Prometheus Alerts
```yaml
# /opt/prometheus/alerts.yml
groups:
- name: security
rules:
- alert: HighCPUUsage
expr: node_cpu_seconds_total{mode="idle"} < 20
for: 5m
labels:
severity: warning
annotations:
summary: "High CPU usage detected"
- alert: SuspiciousProcess
expr: process_cpu_seconds_total{process=~"xmrig|kdevtmp|perfctl"} > 0
for: 1m
labels:
severity: critical
annotations:
summary: "Suspicious process detected"
- alert: UnauthorizedContainer
expr: container_last_seen{name!~"dagi-.*|postgres|redis|neo4j"} > 0
for: 1m
labels:
severity: critical
annotations:
summary: "Unauthorized container running"
```
---
## 🚨 Рівень 6: Incident Response
### 6.1 Automated Response Script
```bash
#!/bin/bash
# /opt/scripts/incident-response.sh
# Автоматична реакція на інцидент
set -e
LOG="/var/log/incident-response.log"
BACKUP_DIR="/opt/backups/incident-$(date +%Y%m%d_%H%M%S)"
echo "$(date) - INCIDENT RESPONSE STARTED" >> $LOG
# 1. Зберегти стан для форензики
mkdir -p $BACKUP_DIR
ps aux > $BACKUP_DIR/processes.txt
netstat -tulpn > $BACKUP_DIR/network.txt
docker ps -a > $BACKUP_DIR/containers.txt
docker images > $BACKUP_DIR/images.txt
iptables -L -n > $BACKUP_DIR/iptables.txt
cat /etc/crontab > $BACKUP_DIR/crontab.txt
ls -la /tmp > $BACKUP_DIR/tmp.txt
# 2. Kill suspicious processes
pkill -9 -f "xmrig|kdevtmp|kinsing|perfctl|httpd.*tmp"
# 3. Stop all non-essential containers
docker stop $(docker ps -q --filter "name!=dagi-router" --filter "name!=dagi-gateway")
# 4. Block all outgoing traffic except SSH
iptables -P OUTPUT DROP
iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
# 5. Clean /tmp
find /tmp -type f -executable -delete
rm -rf /tmp/.perf.c /tmp/httpd /tmp/mysql
# 6. Alert
echo "INCIDENT RESPONSE COMPLETED at $(date)" | mail -s "🚨 NODE1 INCIDENT" admin@daarion.city
echo "$(date) - INCIDENT RESPONSE COMPLETED" >> $LOG
echo "Backup saved to: $BACKUP_DIR" >> $LOG
```
### 6.2 Recovery Playbook
```markdown
## 🔄 Recovery Playbook
### Крок 1: Ізоляція (0-5 хвилин)
1. Запустити incident-response.sh
2. Відключити від мережі (якщо критично)
3. Зберегти докази
### Крок 2: Аналіз (5-30 хвилин)
1. Переглянути логи: /var/log/security-check.log
2. Перевірити processes.txt
3. Ідентифікувати вектор атаки
### Крок 3: Очищення (30-60 хвилин)
1. Видалити compromised containers + images
2. Очистити persistence mechanisms
3. Перевірити cron, systemd, /etc/ld.so.preload
### Крок 4: Відновлення (1-2 години)
1. Rebuild з чистих images
2. Restore з backup (якщо потрібно)
3. Перевірити функціональність
### Крок 5: Post-mortem (24 години)
1. Документувати інцидент
2. Оновити захист
3. Ротувати секрети
```
---
## ✅ Чеклист впровадження
### Негайно (сьогодні):
- [ ] Встановити Trivy на NODE1
- [ ] Створити security-check.sh
- [ ] Налаштувати cron для перевірок
- [ ] Оновити docker-compose.yml з security options
- [ ] Налаштувати egress firewall
### Цього тижня:
- [ ] Впровадити image pinning by SHA
- [ ] Налаштувати fail2ban
- [ ] Встановити rkhunter, chkrootkit
- [ ] Налаштувати auditd
- [ ] Створити process-monitor.py
### Цього місяця:
- [ ] Впровадити network isolation
- [ ] Налаштувати Prometheus alerts
- [ ] Створити custom secure base images
- [ ] Документувати всі процедури
- [ ] Провести security audit
---
## 📚 Додаткові ресурси
- [Docker Security Best Practices](https://docs.docker.com/engine/security/)
- [CIS Docker Benchmark](https://www.cisecurity.org/benchmark/docker)
- [Trivy Documentation](https://aquasecurity.github.io/trivy/)
- [Falco Runtime Security](https://falco.org/)
- [OWASP Container Security](https://owasp.org/www-project-container-security/)
---
**Автор:** Ivan Tytar & AI Assistant
**Останнє оновлення:** 2026-01-10