feat: Security Audit Auto-Fix Buttons + manuelle Dokumentation (docs/security-audit.md)
This commit is contained in:
@@ -0,0 +1,270 @@
|
||||
# Security Audit — archivmail
|
||||
|
||||
Dieses Dokument beschreibt alle Security-Checks die das System automatisch durchführt,
|
||||
welche Werte als sicher gelten und wie Probleme manuell behoben werden können.
|
||||
|
||||
---
|
||||
|
||||
## Übersicht der Checks
|
||||
|
||||
| Check | OK-Kriterium | Auto-Fix verfügbar |
|
||||
|------------------------|----------------------------------------------|--------------------|
|
||||
| Firewall (nftables) | Input-Chain policy: drop | Ja |
|
||||
| Port 3000 (Next.js) | Nicht in Whitelist | Nein (via Firewall)|
|
||||
| Port 8080 (Go Backend) | Nicht in Whitelist | Nein (via Firewall)|
|
||||
| HTTPS (TLS) | Port 443 in Firewall + Zertifikat vorhanden | Nein (manuell) |
|
||||
| SSH Root-Login | `prohibit-password` oder `no` | Ja |
|
||||
| SSH Passwort-Auth | `PasswordAuthentication no` | Ja |
|
||||
| Fail2ban | Dienst aktiv | Ja |
|
||||
|
||||
---
|
||||
|
||||
## 1. Firewall (nftables)
|
||||
|
||||
### Was wird geprüft
|
||||
Ob `nft list ruleset` eine Input-Chain mit `policy drop` zurückgibt.
|
||||
Whitelist-Modus: Nur explizit erlaubte Ports sind erreichbar.
|
||||
|
||||
### Erlaubte externe Ports
|
||||
| Port | Dienst |
|
||||
|------|-------------------|
|
||||
| 22 | SSH |
|
||||
| 80 | nginx (Web-UI) |
|
||||
| 2525 | SMTP Einlieferung |
|
||||
|
||||
### Manuell prüfen
|
||||
```bash
|
||||
ssh root@192.168.1.131
|
||||
|
||||
# Aktuelle Regeln anzeigen
|
||||
nft list ruleset
|
||||
|
||||
# Offene Ports prüfen
|
||||
ss -tlnp
|
||||
```
|
||||
|
||||
### Manuell beheben
|
||||
```bash
|
||||
# Konfiguration neu laden
|
||||
nft -f /etc/nftables.conf
|
||||
|
||||
# Beim Systemstart aktivieren
|
||||
systemctl enable nftables
|
||||
systemctl restart nftables
|
||||
|
||||
# Prüfen ob Regeln aktiv sind
|
||||
nft list ruleset | grep "policy drop"
|
||||
```
|
||||
|
||||
### Konfigurationsdatei
|
||||
`/etc/nftables.conf` — Änderungen hier sind persistent.
|
||||
|
||||
---
|
||||
|
||||
## 2. Port 3000 / Port 8080
|
||||
|
||||
### Was wird geprüft
|
||||
Ob diese Ports explizit in der Firewall-Whitelist stehen.
|
||||
Beide Dienste sollen nur intern erreichbar sein (nginx proxied den Zugriff).
|
||||
|
||||
### Warum gefährlich
|
||||
- **Port 3000**: Next.js Frontend — keine eigene Authentifizierung auf diesem Port
|
||||
- **Port 8080**: Go Backend REST API — direkte API-Zugriffe ohne nginx möglich
|
||||
|
||||
### Manuell prüfen
|
||||
```bash
|
||||
# Lauscht Port 3000 auf allen Interfaces?
|
||||
ss -tlnp | grep 3000
|
||||
# => Wenn "0.0.0.0:3000" erscheint, ist er intern offen (Firewall muss blockieren)
|
||||
|
||||
# Ist Port von außen erreichbar?
|
||||
nft list ruleset | grep "dport 3000"
|
||||
# => Wenn keine Zeile erscheint: gut (policy drop blockiert ihn)
|
||||
```
|
||||
|
||||
### Manuell beheben (falls Firewall fehlt)
|
||||
```bash
|
||||
# Firewall neu laden — blockiert automatisch 3000 und 8080
|
||||
nft -f /etc/nftables.conf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. HTTPS (TLS)
|
||||
|
||||
### Was wird geprüft
|
||||
Ob Port 443 in der Firewall freigegeben ist.
|
||||
Aktuell läuft archivmail nur über HTTP (Port 80) — Verbindungen sind unverschlüsselt.
|
||||
|
||||
### Warum wichtig
|
||||
Ohne TLS werden Passwörter und E-Mail-Inhalte im Klartext übertragen.
|
||||
|
||||
### Manuell einrichten (Let's Encrypt / certbot)
|
||||
```bash
|
||||
ssh root@192.168.1.131
|
||||
|
||||
# certbot installieren
|
||||
apt-get install -y certbot python3-certbot-nginx
|
||||
|
||||
# Zertifikat ausstellen (Domain muss auf den Server zeigen)
|
||||
certbot --nginx -d archivmail.example.com
|
||||
|
||||
# Firewall: Port 443 freigeben
|
||||
# In /etc/nftables.conf folgende Zeile in chain input ergänzen:
|
||||
# tcp dport 443 accept
|
||||
nft -f /etc/nftables.conf
|
||||
|
||||
# Automatische Erneuerung prüfen
|
||||
certbot renew --dry-run
|
||||
```
|
||||
|
||||
### nginx nach certbot
|
||||
certbot passt die nginx-Konfiguration automatisch an und fügt SSL + Redirect HTTP→HTTPS hinzu.
|
||||
|
||||
---
|
||||
|
||||
## 4. SSH Root-Login
|
||||
|
||||
### Was wird geprüft
|
||||
Den Wert von `PermitRootLogin` in `/etc/ssh/sshd_config`.
|
||||
|
||||
| Wert | Bewertung |
|
||||
|--------------------|-----------|
|
||||
| `no` | OK |
|
||||
| `prohibit-password`| OK (Key-Auth für root erlaubt) |
|
||||
| `yes` | Warnung |
|
||||
| nicht gesetzt | Warnung (Default ist prohibit-password) |
|
||||
|
||||
### Manuell prüfen
|
||||
```bash
|
||||
grep -i "PermitRootLogin" /etc/ssh/sshd_config
|
||||
```
|
||||
|
||||
### Manuell beheben
|
||||
```bash
|
||||
# Datei bearbeiten
|
||||
nano /etc/ssh/sshd_config
|
||||
|
||||
# Zeile setzen oder ändern:
|
||||
PermitRootLogin prohibit-password
|
||||
|
||||
# SSH-Dienst neu starten
|
||||
systemctl restart ssh
|
||||
|
||||
# Prüfen
|
||||
sshd -T | grep permitrootlogin
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. SSH Passwort-Authentifizierung
|
||||
|
||||
### Was wird geprüft
|
||||
Den Wert von `PasswordAuthentication` in `/etc/ssh/sshd_config`.
|
||||
Empfehlung: Nur SSH-Key-Authentifizierung erlauben.
|
||||
|
||||
### Manuell prüfen
|
||||
```bash
|
||||
grep -i "PasswordAuthentication" /etc/ssh/sshd_config
|
||||
sshd -T | grep passwordauthentication
|
||||
```
|
||||
|
||||
### Manuell beheben
|
||||
```bash
|
||||
# Sicherstellen dass ein SSH-Key hinterlegt ist, BEVOR Passwort-Auth deaktiviert wird
|
||||
cat ~/.ssh/authorized_keys # muss mindestens einen Eintrag enthalten
|
||||
|
||||
# Dann in /etc/ssh/sshd_config:
|
||||
PasswordAuthentication no
|
||||
|
||||
# SSH neu starten
|
||||
systemctl restart ssh
|
||||
```
|
||||
|
||||
> **Warnung:** Passwort-Auth nur deaktivieren wenn ein SSH-Key in `~/.ssh/authorized_keys` vorhanden ist.
|
||||
> Sonst ist kein Login mehr möglich.
|
||||
|
||||
---
|
||||
|
||||
## 6. Fail2ban
|
||||
|
||||
### Was wird geprüft
|
||||
Ob der `fail2ban`-Systemd-Dienst aktiv ist.
|
||||
|
||||
### Was ist Fail2ban
|
||||
Fail2ban überwacht Log-Dateien und blockiert IPs automatisch bei zu vielen fehlgeschlagenen Login-Versuchen (Brute-Force-Schutz).
|
||||
|
||||
### Manuell prüfen
|
||||
```bash
|
||||
systemctl status fail2ban
|
||||
|
||||
# Aktive Jails anzeigen
|
||||
fail2ban-client status
|
||||
|
||||
# SSH-Jail prüfen
|
||||
fail2ban-client status sshd
|
||||
|
||||
# Gesperrte IPs anzeigen
|
||||
fail2ban-client status sshd | grep "Banned IP"
|
||||
```
|
||||
|
||||
### Manuell installieren und konfigurieren
|
||||
```bash
|
||||
apt-get install -y fail2ban
|
||||
|
||||
# Konfiguration erstellen
|
||||
cat > /etc/fail2ban/jail.local << 'EOF'
|
||||
[sshd]
|
||||
enabled = true
|
||||
maxretry = 5
|
||||
bantime = 3600
|
||||
findtime = 600
|
||||
|
||||
[nginx-http-auth]
|
||||
enabled = true
|
||||
EOF
|
||||
|
||||
systemctl enable fail2ban
|
||||
systemctl start fail2ban
|
||||
|
||||
# Prüfen
|
||||
fail2ban-client status
|
||||
```
|
||||
|
||||
### Gesperrte IP manuell entsperren
|
||||
```bash
|
||||
fail2ban-client set sshd unbanip <IP-Adresse>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Kompletter manueller Audit (alle Checks auf einmal)
|
||||
|
||||
```bash
|
||||
ssh root@192.168.1.131
|
||||
|
||||
echo "=== Firewall ==="
|
||||
nft list ruleset | grep -E "policy|dport"
|
||||
|
||||
echo "=== Offene Ports ==="
|
||||
ss -tlnp
|
||||
|
||||
echo "=== SSH Config ==="
|
||||
sshd -T | grep -E "permitrootlogin|passwordauthentication"
|
||||
|
||||
echo "=== Fail2ban ==="
|
||||
systemctl is-active fail2ban
|
||||
fail2ban-client status 2>/dev/null || echo "nicht installiert"
|
||||
|
||||
echo "=== nftables Dienst ==="
|
||||
systemctl is-enabled nftables
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Weiterführende Ressourcen
|
||||
|
||||
- [Debian SSH Hardening](https://wiki.debian.org/SSH)
|
||||
- [nftables Dokumentation](https://wiki.nftables.org/)
|
||||
- [Fail2ban Dokumentation](https://www.fail2ban.org/wiki/index.php/MANUAL_0_8)
|
||||
- [Let's Encrypt / certbot](https://certbot.eff.org/)
|
||||
Reference in New Issue
Block a user