diff --git a/CADDY_TROUBLESHOOTING.md b/CADDY_TROUBLESHOOTING.md new file mode 100644 index 0000000..fc9cb4c --- /dev/null +++ b/CADDY_TROUBLESHOOTING.md @@ -0,0 +1,183 @@ +# Caddy Zertifikat-Troubleshooting + +## Problem: Zertifikat für Punycode-Domain (hördle.de / xn--hrdle-jua.de) fehlt + +Wenn die Domain `hördle.de` (xn--hrdle-jua.de) einen `ERR_SSL_PROTOCOL_ERROR` zeigt, bedeutet das, dass kein gültiges SSL-Zertifikat vorhanden ist. + +### Schritt 1: Zertifikat-Status prüfen + +Führe das Check-Script aus: + +```bash +./scripts/check-caddy-certificates.sh +``` + +Dieses Script prüft: +- Ob Caddy läuft +- Welche Zertifikate vorhanden sind +- Ob die DNS-Einträge korrekt sind +- Ob die HTTPS-Verbindungen funktionieren + +### Schritt 2: DNS-Einträge prüfen + +**Wichtig**: Beide Domains müssen auf die gleiche Server-IP zeigen! + +#### In GoDaddy prüfen: + +1. Gehe zu [GoDaddy DNS-Verwaltung](https://dcc.godaddy.com/manage/hoerdle.de/dns) +2. Prüfe die A-Records: + + **Für hoerdle.de:** + - Name: `@` oder `hoerdle.de` + - Typ: `A` + - Wert: `DEINE_SERVER_IP` + + **Für hördle.de (Punycode):** + - Name: `@` oder `xn--hrdle-jua.de` (oder der Unicode-Name, falls unterstützt) + - Typ: `A` + - Wert: **GLEICHE_SERVER_IP wie hoerdle.de** + +#### DNS manuell testen: + +```bash +# Prüfe hoerdle.de +dig +short hoerdle.de @8.8.8.8 + +# Prüfe xn--hrdle-jua.de (Punycode) +dig +short xn--hrdle-jua.de @8.8.8.8 + +# Beide sollten die gleiche IP zurückgeben! +``` + +### Schritt 3: Zertifikat neu erstellen + +Wenn die DNS-Einträge korrekt sind, lösche das alte (fehlgeschlagene) Zertifikat und lass Caddy es neu erstellen: + +```bash +./scripts/renew-caddy-certificates.sh +``` + +Wähle Option 2: "Nur Zertifikat für xn--hrdle-jua.de löschen" + +### Schritt 4: Caddy-Logs überwachen + +Während Caddy das Zertifikat erstellt, überwache die Logs: + +```bash +docker logs hoerdle-caddy -f +``` + +Du solltest sehen: +- `[INFO] attempting ACME challenge` - Caddy versucht die Challenge +- `[INFO] successfully completed ACME challenge` - Challenge erfolgreich +- `[INFO] certificate obtained successfully` - Zertifikat erstellt + +Bei Fehlern siehst du: +- `[ERROR] acme: error` - Challenge fehlgeschlagen +- `[ERROR] unable to validate` - Validierung fehlgeschlagen + +### Schritt 5: Häufige Probleme und Lösungen + +#### Problem 1: DNS zeigt auf falsche IP + +**Symptom**: `dig` zeigt eine andere IP als erwartet + +**Lösung**: +1. Prüfe DNS-Einträge in GoDaddy +2. Warte auf DNS-Propagierung (kann 5-60 Minuten dauern) +3. Verwende einen DNS-Checker: https://www.whatsmydns.net/ + +#### Problem 2: Port 80 nicht erreichbar + +**Symptom**: Caddy-Logs zeigen "connection refused" oder Timeout + +**Lösung**: +1. Prüfe Firewall: `sudo ufw status` +2. Prüfe ob Port 80 offen ist: `sudo netstat -tulpn | grep :80` +3. Prüfe ob Caddy auf Port 80 lauscht: `docker exec hoerdle-caddy netstat -tulpn | grep :80` + +#### Problem 3: Let's Encrypt Rate Limit + +**Symptom**: Logs zeigen "too many certificates already issued" + +**Lösung**: +- Warte 1 Woche (Rate Limit von Let's Encrypt) +- Oder verwende Staging-Environment zum Testen: + ```caddyfile + tls { + staging + } + ``` + +#### Problem 4: Punycode-Domain wird nicht erkannt + +**Symptom**: Caddy erstellt Zertifikat nur für hoerdle.de, nicht für xn--hrdle-jua.de + +**Lösung**: +1. Prüfe ob beide Domains in der Caddyfile stehen +2. Prüfe DNS-Einträge (siehe Schritt 2) +3. Erzwinge Zertifikat-Erstellung (siehe Schritt 3) + +### Manuelle Zertifikat-Löschung + +Falls das Script nicht funktioniert, kannst du Zertifikate manuell löschen: + +```bash +# Alle Zertifikate löschen +docker exec hoerdle-caddy rm -rf /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/* + +# Nur Punycode-Zertifikat löschen (manuell) +docker exec hoerdle-caddy find /data/caddy/certificates -name "*xn--*" -delete + +# Container neu starten +docker compose -f docker-compose.caddy.yml --profile production restart caddy +``` + +### DNS-Propagierung prüfen + +Nach DNS-Änderungen kann es bis zu 60 Minuten dauern, bis alle DNS-Server aktualisiert sind: + +```bash +# Prüfe DNS-Propagierung weltweit +curl "https://dnschecker.org/#A/hoerdle.de" +curl "https://dnschecker.org/#A/xn--hrdle-jua.de" +``` + +### Test-Zertifikat erstellen (Staging) + +Zum Testen ohne Rate-Limits kannst du ein Staging-Zertifikat erstellen: + +1. Temporär Caddyfile ändern (in beiden Domain-Blocks): +```caddyfile +tls { + staging +} +``` + +2. Container neu starten +3. Zertifikat erstellen lassen +4. Zurück zu Produktion ändern (Staging-Block entfernen) +5. Erneut Container neu starten + +### Verifizieren, dass es funktioniert + +Nach erfolgreicher Zertifikats-Erstellung: + +```bash +# Teste HTTPS-Verbindung +curl -I https://hoerdle.de +curl -I https://xn--hrdle-jua.de + +# Prüfe Zertifikat-Details +echo | openssl s_client -connect hoerdle.de:443 -servername hoerdle.de 2>/dev/null | openssl x509 -noout -subject -dates +echo | openssl s_client -connect xn--hrdle-jua.de:443 -servername xn--hrdle-jua.de 2>/dev/null | openssl x509 -noout -subject -dates +``` + +### Support + +Falls das Problem weiterhin besteht: +1. Prüfe Caddy-Logs: `docker logs hoerdle-caddy` +2. Prüfe DNS: `dig +short xn--hrdle-jua.de @8.8.8.8` +3. Prüfe Firewall: `sudo ufw status` +4. Prüfe Port-Zugriff: `curl -I http://hoerdle.de` + diff --git a/scripts/check-caddy-certificates.sh b/scripts/check-caddy-certificates.sh new file mode 100755 index 0000000..5792d90 --- /dev/null +++ b/scripts/check-caddy-certificates.sh @@ -0,0 +1,94 @@ +#!/bin/bash +# Script zum Prüfen der Caddy-Zertifikate + +set -e + +echo "🔍 Prüfe Caddy-Zertifikat-Status..." +echo "" + +# Prüfe ob Caddy-Container läuft +if ! docker ps | grep -q hoerdle-caddy; then + echo "❌ Caddy-Container läuft nicht!" + echo " Starte ihn mit: docker compose -f docker-compose.caddy.yml --profile production up -d" + exit 1 +fi + +echo "✅ Caddy-Container läuft" +echo "" + +# Prüfe Zertifikate im Volume +echo "📜 Gespeicherte Zertifikate im Volume:" +docker exec hoerdle-caddy find /data/caddy/certificates -name "*.crt" -o -name "*.key" 2>/dev/null | head -20 || echo " (Keine Zertifikate gefunden oder Fehler beim Zugriff)" +echo "" + +# Prüfe Caddy-Logs für Zertifikats-Fehler +echo "📋 Letzte Caddy-Logs (Zertifikat-bezogen):" +docker logs hoerdle-caddy 2>&1 | grep -i -E "(certificate|tls|acme|challenge|error)" | tail -20 || echo " (Keine relevanten Log-Einträge gefunden)" +echo "" + +# Prüfe DNS-Einträge +echo "🌐 DNS-Einträge prüfen:" +echo "" + +# Prüfe hoerdle.de +echo "1️⃣ hoerdle.de:" +HOERDLE_IP=$(dig +short hoerdle.de @8.8.8.8 | head -1 || echo "DNS-Fehler") +if [ -n "$HOERDLE_IP" ] && [ "$HOERDLE_IP" != "DNS-Fehler" ]; then + echo " ✅ DNS-A-Record: $HOERDLE_IP" +else + echo " ❌ DNS-A-Record: nicht aufgelöst" +fi + +# Prüfe xn--hrdle-jua.de (Punycode) +echo "2️⃣ xn--hrdle-jua.de (hördle.de):" +PUNYCODE_IP=$(dig +short xn--hrdle-jua.de @8.8.8.8 | head -1 || echo "DNS-Fehler") +if [ -n "$PUNYCODE_IP" ] && [ "$PUNYCODE_IP" != "DNS-Fehler" ]; then + echo " ✅ DNS-A-Record: $PUNYCODE_IP" +else + echo " ❌ DNS-A-Record: nicht aufgelöst" +fi + +# Prüfe auch die Unicode-Domain direkt (falls unterstützt) +echo "3️⃣ hördle.de (Unicode):" +UNICODE_IP=$(dig +short hördle.de @8.8.8.8 2>/dev/null | head -1 || echo "Nicht unterstützt") +if [ -n "$UNICODE_IP" ] && [ "$UNICODE_IP" != "Nicht unterstützt" ]; then + echo " ✅ DNS-A-Record: $UNICODE_IP" +else + echo " ⚠️ Unicode-Domain-Abfrage nicht unterstützt (normal)" +fi + +echo "" +echo "🔒 Zertifikat-Test:" +echo "" + +# Teste HTTPS-Verbindung zu hoerdle.de +echo "1️⃣ hoerdle.de HTTPS:" +if echo | timeout 5 openssl s_client -connect hoerdle.de:443 -servername hoerdle.de 2>/dev/null | grep -q "Verify return code: 0"; then + echo " ✅ Zertifikat gültig" + CERT_INFO=$(echo | timeout 5 openssl s_client -connect hoerdle.de:443 -servername hoerdle.de 2>/dev/null | openssl x509 -noout -subject -dates 2>/dev/null || echo "") + echo " $CERT_INFO" | sed 's/^/ /' +else + echo " ❌ Zertifikat fehlt oder ungültig" +fi + +echo "" +echo "2️⃣ hördle.de (xn--hrdle-jua.de) HTTPS:" +if echo | timeout 5 openssl s_client -connect xn--hrdle-jua.de:443 -servername xn--hrdle-jua.de 2>/dev/null | grep -q "Verify return code: 0"; then + echo " ✅ Zertifikat gültig" + CERT_INFO=$(echo | timeout 5 openssl s_client -connect xn--hrdle-jua.de:443 -servername xn--hrdle-jua.de 2>/dev/null | openssl x509 -noout -subject -dates 2>/dev/null || echo "") + echo " $CERT_INFO" | sed 's/^/ /' +else + echo " ❌ Zertifikat fehlt oder ungültig" +fi + +echo "" +echo "📝 Zertifikat-Details aus Caddy Volume:" +echo "" +docker exec hoerdle-caddy ls -la /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/ 2>/dev/null | head -10 || echo " (Verzeichnis nicht gefunden oder leer)" + +echo "" +echo "💡 Tipps:" +echo " - Wenn kein Zertifikat vorhanden ist, führe aus: ./scripts/renew-caddy-certificates.sh" +echo " - Prüfe die Caddy-Logs: docker logs hoerdle-caddy" +echo " - Prüfe DNS-Einträge in GoDaddy: https://dcc.godaddy.com/manage/hoerdle.de/dns" + diff --git a/scripts/quick-check-punycode-dns.sh b/scripts/quick-check-punycode-dns.sh new file mode 100755 index 0000000..429d33c --- /dev/null +++ b/scripts/quick-check-punycode-dns.sh @@ -0,0 +1,110 @@ +#!/bin/bash +# Quick-Check für Punycode-Domain DNS und Zertifikat + +set -e + +echo "🔍 Quick-Check für hördle.de (xn--hrdle-jua.de)" +echo "" + +# Prüfe DNS +echo "1️⃣ DNS-Auflösung:" +echo "" +echo " hoerdle.de:" +HOERDLE_IP=$(dig +short hoerdle.de @8.8.8.8 | head -1 || echo "") +if [ -z "$HOERDLE_IP" ]; then + echo " ❌ Konnte nicht aufgelöst werden" +else + echo " ✅ IP: $HOERDLE_IP" +fi + +echo "" +echo " xn--hrdle-jua.de:" +PUNYCODE_IP=$(dig +short xn--hrdle-jua.de @8.8.8.8 | head -1 || echo "") +if [ -z "$PUNYCODE_IP" ]; then + echo " ❌ Konnte nicht aufgelöst werden" +else + echo " ✅ IP: $PUNYCODE_IP" +fi + +if [ -n "$HOERDLE_IP" ] && [ -n "$PUNYCODE_IP" ]; then + if [ "$HOERDLE_IP" = "$PUNYCODE_IP" ]; then + echo "" + echo " ✅ Beide Domains zeigen auf die gleiche IP ($HOERDLE_IP)" + else + echo "" + echo " ⚠️ WARNUNG: Domains zeigen auf unterschiedliche IPs!" + echo " hoerdle.de: $HOERDLE_IP" + echo " xn--hrdle-jua.de: $PUNYCODE_IP" + echo " → Beide sollten auf die gleiche IP zeigen!" + fi +fi + +echo "" +echo "2️⃣ HTTPS-Verbindungstest:" +echo "" + +# Test hoerdle.de +echo " hoerdle.de:" +if timeout 5 bash -c "echo > /dev/tcp/hoerdle.de/443" 2>/dev/null; then + echo " ✅ Port 443 ist erreichbar" + if echo | timeout 5 openssl s_client -connect hoerdle.de:443 -servername hoerdle.de 2>/dev/null | grep -q "Verify return code: 0"; then + CERT_VALID_UNTIL=$(echo | timeout 5 openssl s_client -connect hoerdle.de:443 -servername hoerdle.de 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2 || echo "") + echo " ✅ Zertifikat gültig bis: $CERT_VALID_UNTIL" + else + echo " ❌ Zertifikat ungültig oder fehlt" + fi +else + echo " ❌ Port 443 nicht erreichbar" +fi + +echo "" +echo " xn--hrdle-jua.de:" +if timeout 5 bash -c "echo > /dev/tcp/xn--hrdle-jua.de/443" 2>/dev/null; then + echo " ✅ Port 443 ist erreichbar" + if echo | timeout 5 openssl s_client -connect xn--hrdle-jua.de:443 -servername xn--hrdle-jua.de 2>/dev/null | grep -q "Verify return code: 0"; then + CERT_VALID_UNTIL=$(echo | timeout 5 openssl s_client -connect xn--hrdle-jua.de:443 -servername xn--hrdle-jua.de 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2 || echo "") + echo " ✅ Zertifikat gültig bis: $CERT_VALID_UNTIL" + else + echo " ❌ Zertifikat ungültig oder fehlt (ERR_SSL_PROTOCOL_ERROR)" + echo "" + echo " 💡 Lösung: Führe aus: ./scripts/renew-caddy-certificates.sh" + fi +else + echo " ❌ Port 443 nicht erreichbar" +fi + +echo "" +echo "3️⃣ Caddy-Container Status:" +echo "" +if docker ps | grep -q hoerdle-caddy; then + echo " ✅ Caddy-Container läuft" + echo "" + echo " 📋 Letzte Caddy-Logs (Zertifikat-bezogen):" + docker logs hoerdle-caddy 2>&1 | grep -i -E "(xn--hrdle|punycode|certificate|tls|acme|challenge)" | tail -5 || echo " (Keine relevanten Einträge gefunden)" +else + echo " ❌ Caddy-Container läuft nicht" + echo " Starte mit: docker compose -f docker-compose.caddy.yml --profile production up -d" +fi + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo "💡 Nächste Schritte:" +echo "" +if [ -n "$HOERDLE_IP" ] && [ -n "$PUNYCODE_IP" ] && [ "$HOERDLE_IP" != "$PUNYCODE_IP" ]; then + echo " 1. ❗ DNS-Konfiguration prüfen!" + echo " Beide Domains müssen auf die gleiche IP zeigen." + echo " Prüfe in GoDaddy: https://dcc.godaddy.com/manage/hoerdle.de/dns" + echo "" +fi + +echo " 2. Wenn DNS korrekt ist, Zertifikat neu erstellen:" +echo " ./scripts/renew-caddy-certificates.sh" +echo "" +echo " 3. Caddy-Logs überwachen:" +echo " docker logs hoerdle-caddy -f" +echo "" +echo " 4. Detaillierte Diagnose:" +echo " ./scripts/check-caddy-certificates.sh" +echo "" + diff --git a/scripts/renew-caddy-certificates.sh b/scripts/renew-caddy-certificates.sh new file mode 100755 index 0000000..9d71a99 --- /dev/null +++ b/scripts/renew-caddy-certificates.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# Script zum Erneuern/Löschen und Neu-Erstellen von Caddy-Zertifikaten + +set -e + +echo "🔄 Caddy-Zertifikat-Erneuerung" +echo "" +echo "⚠️ WICHTIG: Dieses Script wird die Zertifikate löschen und Caddy zwingen, sie neu zu erstellen." +echo "" + +# Prüfe ob Caddy-Container läuft +if ! docker ps | grep -q hoerdle-caddy; then + echo "❌ Caddy-Container läuft nicht!" + echo " Starte ihn mit: docker compose -f docker-compose.caddy.yml --profile production up -d" + exit 1 +fi + +echo "📋 Verfügbare Optionen:" +echo " 1) Alle Zertifikate löschen und neu erstellen (empfohlen bei Problemen)" +echo " 2) Nur Zertifikat für xn--hrdle-jua.de löschen (Punycode-Domain)" +echo " 3) Nur Zertifikat für hoerdle.de löschen" +echo " 4) Abbrechen" +echo "" +read -p "Wähle eine Option (1-4): " choice + +case $choice in + 1) + echo "" + echo "🗑️ Lösche ALLE Zertifikate..." + docker exec hoerdle-caddy rm -rf /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/* 2>/dev/null || true + echo "✅ Alle Zertifikate gelöscht" + ;; + 2) + echo "" + echo "🗑️ Lösche Zertifikat für xn--hrdle-jua.de..." + docker exec hoerdle-caddy find /data/caddy/certificates -name "*xn--hrdle-jua.de*" -delete 2>/dev/null || true + docker exec hoerdle-caddy find /data/caddy/certificates -name "*xn--*" -delete 2>/dev/null || true + echo "✅ Zertifikat für Punycode-Domain gelöscht" + ;; + 3) + echo "" + echo "🗑️ Lösche Zertifikat für hoerdle.de..." + docker exec hoerdle-caddy find /data/caddy/certificates -name "*hoerdle.de*" ! -name "*xn--*" -delete 2>/dev/null || true + echo "✅ Zertifikat für hoerdle.de gelöscht" + ;; + 4) + echo "❌ Abgebrochen." + exit 0 + ;; + *) + echo "❌ Ungültige Option. Abgebrochen." + exit 1 + ;; +esac + +echo "" +echo "🔄 Starte Caddy-Container neu, um Zertifikate neu zu erstellen..." +docker compose -f docker-compose.caddy.yml --profile production restart caddy + +echo "" +echo "⏳ Warte 5 Sekunden, damit Caddy startet..." +sleep 5 + +echo "" +echo "📋 Prüfe Caddy-Logs auf Zertifikats-Erstellung:" +echo "" +docker logs hoerdle-caddy --tail=30 2>&1 | grep -i -E "(certificate|tls|acme|challenge|error|success)" || echo " (Keine relevanten Log-Einträge in den letzten 30 Zeilen)" + +echo "" +echo "✅ Container wurde neu gestartet." +echo "" +echo "💡 Nächste Schritte:" +echo " 1. Warte 1-2 Minuten, damit Caddy die Zertifikate erstellt" +echo " 2. Prüfe die Logs: docker logs hoerdle-caddy -f" +echo " 3. Prüfe den Status: ./scripts/check-caddy-certificates.sh" +echo " 4. Teste die Domain: curl -I https://xn--hrdle-jua.de" +echo "" +echo "⚠️ Falls das Zertifikat nicht erstellt wird:" +echo " - Prüfe DNS-Einträge: Beide Domains müssen auf die Server-IP zeigen" +echo " - Prüfe Port 80: Muss von außen erreichbar sein (für HTTP-01 Challenge)" +echo " - Prüfe Firewall: Ports 80 und 443 müssen offen sein" +echo " - Prüfe Caddy-Logs: docker logs hoerdle-caddy" +