Files
microdao-daarion/security/hardening/cloud.md
Apple cba2ff47f3 📚 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>
2026-01-09 02:08:13 -08:00

311 lines
6.9 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.
# ☁️ 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