Security Hardening und Dokumentation
Aenderungen: - nginx: http2 Direktive aktualisiert (deprecated Syntax) - nginx: proxy_max_temp_file_size entfernt (Windows-inkompatibel) - nginx: Rate Limiting aktiviert Dokumentation: - Stolperfallen und Lessons Learned hinzugefuegt - Changelog aktualisiert mit allen Security-Massnahmen Getestet: - Alle Services erreichbar (Vaultwarden, Nextcloud, Gitea, Websites) - nginx Config validiert - Rate Limiting aktiv 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
18
README.md
18
README.md
@@ -180,8 +180,18 @@ Siehe [docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) fuer:
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
### 2024-12-28
|
### 2025-12-28
|
||||||
- Initial Setup mit allen Services
|
- Initial Setup mit allen Services
|
||||||
- Gitea auf eigener Subdomain
|
- Gitea auf eigener Subdomain (eckardt-git.duckdns.org)
|
||||||
- Security Hardening (Registration disabled, Rate Limiting)
|
- Security Hardening:
|
||||||
- Health Checks und Resource Limits
|
- Fail2Ban (SSH: 3 Versuche = 24h Ban)
|
||||||
|
- SSH Key-Only Authentication
|
||||||
|
- UFW Firewall
|
||||||
|
- Automatische Security Updates
|
||||||
|
- Docker no-new-privileges
|
||||||
|
- nginx Rate Limiting
|
||||||
|
- Vaultwarden Registration disabled
|
||||||
|
- Gitea Registration disabled
|
||||||
|
- Isolierte Docker-Netzwerke pro Service
|
||||||
|
- Resource Limits (CPU/Memory) pro Container
|
||||||
|
- Logging mit Rotation (10MB, 3 Files)
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ http {
|
|||||||
# eckardt-vault.duckdns.org - Main Services
|
# eckardt-vault.duckdns.org - Main Services
|
||||||
# ============================================
|
# ============================================
|
||||||
server {
|
server {
|
||||||
listen 443 ssl http2;
|
listen 443 ssl;
|
||||||
|
http2 on;
|
||||||
server_name eckardt-vault.duckdns.org;
|
server_name eckardt-vault.duckdns.org;
|
||||||
|
|
||||||
ssl_certificate C:/nginx/ssl/eckardt-vault.duckdns.org-chain.pem;
|
ssl_certificate C:/nginx/ssl/eckardt-vault.duckdns.org-chain.pem;
|
||||||
@@ -123,7 +124,8 @@ http {
|
|||||||
# eckardt-cloud.duckdns.org - Nextcloud
|
# eckardt-cloud.duckdns.org - Nextcloud
|
||||||
# ============================================
|
# ============================================
|
||||||
server {
|
server {
|
||||||
listen 443 ssl http2;
|
listen 443 ssl;
|
||||||
|
http2 on;
|
||||||
server_name eckardt-cloud.duckdns.org;
|
server_name eckardt-cloud.duckdns.org;
|
||||||
|
|
||||||
ssl_certificate C:/nginx/ssl/eckardt-cloud.duckdns.org-chain.pem;
|
ssl_certificate C:/nginx/ssl/eckardt-cloud.duckdns.org-chain.pem;
|
||||||
@@ -141,7 +143,6 @@ http {
|
|||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
# Nextcloud specific
|
# Nextcloud specific
|
||||||
proxy_max_temp_file_size 10240m;
|
|
||||||
proxy_connect_timeout 300;
|
proxy_connect_timeout 300;
|
||||||
proxy_send_timeout 300;
|
proxy_send_timeout 300;
|
||||||
proxy_read_timeout 300;
|
proxy_read_timeout 300;
|
||||||
@@ -152,7 +153,8 @@ http {
|
|||||||
# eckardt-git.duckdns.org - Gitea
|
# eckardt-git.duckdns.org - Gitea
|
||||||
# ============================================
|
# ============================================
|
||||||
server {
|
server {
|
||||||
listen 443 ssl http2;
|
listen 443 ssl;
|
||||||
|
http2 on;
|
||||||
server_name eckardt-git.duckdns.org;
|
server_name eckardt-git.duckdns.org;
|
||||||
|
|
||||||
ssl_certificate C:/nginx/ssl/eckardt-git.duckdns.org-chain.pem;
|
ssl_certificate C:/nginx/ssl/eckardt-git.duckdns.org-chain.pem;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
4. [Service-spezifische Probleme](#4-service-spezifische-probleme)
|
4. [Service-spezifische Probleme](#4-service-spezifische-probleme)
|
||||||
5. [Backup/Restore Probleme](#5-backuprestore-probleme)
|
5. [Backup/Restore Probleme](#5-backuprestore-probleme)
|
||||||
6. [Performance Probleme](#6-performance-probleme)
|
6. [Performance Probleme](#6-performance-probleme)
|
||||||
|
7. [Stolperfallen und Lessons Learned](#7-stolperfallen-und-lessons-learned)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -343,6 +344,132 @@ docker system df
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 7. Stolperfallen und Lessons Learned
|
||||||
|
|
||||||
|
### nginx auf Windows
|
||||||
|
|
||||||
|
**Problem:** `listen 443 ssl http2;` ist deprecated
|
||||||
|
|
||||||
|
**Loesung:** Neue Syntax verwenden:
|
||||||
|
```nginx
|
||||||
|
listen 443 ssl;
|
||||||
|
http2 on;
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problem:** `proxy_max_temp_file_size` Direktive funktioniert nicht
|
||||||
|
|
||||||
|
**Loesung:** Direktive entfernen oder auf gueltigen Wert setzen (z.B. `0` zum Deaktivieren)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Docker User Namespace Remapping
|
||||||
|
|
||||||
|
**Problem:** Container starten nicht nach Aktivierung von `userns-remap`
|
||||||
|
|
||||||
|
**Ursache:** Bestehende Volumes haben falsche Berechtigungen fuer den remapped User
|
||||||
|
|
||||||
|
**Loesung:**
|
||||||
|
- Option 1: `userns-remap` nicht verwenden fuer bestehende Installationen
|
||||||
|
- Option 2: Alle Volume-Berechtigungen anpassen (aufwendig)
|
||||||
|
|
||||||
|
```json
|
||||||
|
// /etc/docker/daemon.json - OHNE userns-remap fuer bestehende Volumes
|
||||||
|
{
|
||||||
|
"log-driver": "json-file",
|
||||||
|
"log-opts": {
|
||||||
|
"max-size": "10m",
|
||||||
|
"max-file": "3"
|
||||||
|
},
|
||||||
|
"no-new-privileges": true,
|
||||||
|
"live-restore": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### MariaDB Health Checks
|
||||||
|
|
||||||
|
**Problem:** `healthcheck.sh --connect --innodb_initialized` schlaegt fehl
|
||||||
|
|
||||||
|
**Ursache:** Health Check versucht root-Login ohne Passwort
|
||||||
|
|
||||||
|
**Loesung:** Einfachen Health Check verwenden oder ganz weglassen:
|
||||||
|
```yaml
|
||||||
|
# Option 1: Einfacher TCP Check
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "nextcloud", "-pNextcloudDB123!"]
|
||||||
|
|
||||||
|
# Option 2: Kein Health Check (Container verlaesst sich auf depends_on)
|
||||||
|
# healthcheck: weglassen
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Gitea Subpath vs Subdomain
|
||||||
|
|
||||||
|
**Problem:** Gitea unter Subpath (z.B. `/git/`) laedt Assets nicht
|
||||||
|
|
||||||
|
**Ursache:** Gitea generiert absolute Asset-Pfade basierend auf ROOT_URL
|
||||||
|
|
||||||
|
**Loesung:** Immer eigene Subdomain verwenden:
|
||||||
|
- ❌ `https://example.com/git/` - funktioniert nicht zuverlaessig
|
||||||
|
- ✅ `https://git.example.com/` - funktioniert
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### SSH Key-Only nach Passwort-Deaktivierung
|
||||||
|
|
||||||
|
**Problem:** Ausgesperrt nach Deaktivierung von PasswordAuthentication
|
||||||
|
|
||||||
|
**Praevention:**
|
||||||
|
1. IMMER erst SSH Key testen bevor Passwort deaktiviert wird
|
||||||
|
2. Backup-Zugang via Proxmox Console behalten
|
||||||
|
|
||||||
|
**Notfall-Recovery:**
|
||||||
|
```bash
|
||||||
|
# Via Proxmox Web Console (https://192.168.178.111:8006)
|
||||||
|
# 1. Shell oeffnen
|
||||||
|
# 2. Passwort-Auth wieder aktivieren
|
||||||
|
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
|
||||||
|
systemctl restart sshd
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### UFW und Docker
|
||||||
|
|
||||||
|
**Problem:** UFW Regeln werden von Docker ignoriert
|
||||||
|
|
||||||
|
**Ursache:** Docker manipuliert iptables direkt
|
||||||
|
|
||||||
|
**Loesung:** Docker-Ports nur auf localhost binden oder UFW-Docker Integration nutzen:
|
||||||
|
```yaml
|
||||||
|
# In docker-compose.yml - nur lokal erreichbar
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8080:80"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Rate Limiting Debugging
|
||||||
|
|
||||||
|
**Problem:** Unklar ob Rate Limiting greift
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
```bash
|
||||||
|
# Schnelle Anfragen senden
|
||||||
|
for i in {1..20}; do curl -s -o /dev/null -w "%{http_code}\n" https://eckardt-vault.duckdns.org/vault/; done
|
||||||
|
|
||||||
|
# Bei aktivem Limit: 503 nach einigen Anfragen
|
||||||
|
```
|
||||||
|
|
||||||
|
**nginx Logs pruefen (auf VPS):**
|
||||||
|
```cmd
|
||||||
|
type C:\nginx\logs\error.log | findstr "limiting"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Kontakt / Hilfe
|
## Kontakt / Hilfe
|
||||||
|
|
||||||
- **Gitea Issues:** https://eckardt-git.duckdns.org/Martin/proxmox-infrastruktur/issues
|
- **Gitea Issues:** https://eckardt-git.duckdns.org/Martin/proxmox-infrastruktur/issues
|
||||||
|
|||||||
Reference in New Issue
Block a user