diff --git a/scripts/proxmox-vpn-install.sh b/scripts/proxmox-vpn-install.sh index 2908cb5..a27ee92 100644 --- a/scripts/proxmox-vpn-install.sh +++ b/scripts/proxmox-vpn-install.sh @@ -193,6 +193,8 @@ collect_vpn_config() { ask "Auswahl [1/2]" "1" VPN_MODE="$REPLY" + VPN_PROTO="udp" # Start mit UDP, automatischer Fallback auf TCP bei TLS-Fehler + if [[ "$VPN_MODE" == "2" ]]; then echo -e "\n ${YELLOW}Gültige Hostnamen haben das Format: de507.nordvpn.com, de654.nordvpn.com etc.${NC}" echo -e " ${YELLOW}Beispiele für Deutschland: de507, de654, de675 ... de1118${NC}" @@ -335,80 +337,112 @@ COMPOSEEOF" success "docker-compose.yml geschrieben" } -# ── Stack starten mit Fehlerbehandlung ───────────────────────────────────────── +# ── Stack starten mit automatischem UDP→TCP Fallback ────────────────────────── start_and_verify() { step "VPN-Stack starten" local FT_DIR="/opt/docker-projekte/freqtrade" - local MAX_ATTEMPTS=3 - local attempt=1 + local vpn_ok=false + VPN_IP="" - while [[ $attempt -le $MAX_ATTEMPTS ]]; do - echo -e "\n ${CYAN}Versuch ${attempt}/${MAX_ATTEMPTS}...${NC}" + # Protokoll-Reihenfolge: UDP zuerst, dann automatisch TCP + for proto in udp tcp; do + [[ "$proto" == "tcp" ]] && info "UDP fehlgeschlagen – versuche TCP automatisch..." - # Stack starten + # Protokoll in .env setzen (Gluetun liest OPENVPN_PROTOCOL) + pct exec "$SEL_ID" -- bash -c "sed -i '/^OPENVPN_PROTOCOL=/d' ${FT_DIR}/.env; echo 'OPENVPN_PROTOCOL=${proto}' >> ${FT_DIR}/.env" + + # Stack starten (ggf. neu) + pct exec "$SEL_ID" -- bash -c "cd ${FT_DIR} && docker compose down 2>/dev/null || true" pct exec "$SEL_ID" -- bash -c "cd ${FT_DIR} && docker compose up -d 2>&1" || true - # Auf Gluetun warten (bis zu 60s) - info "Warte auf VPN-Verbindung (bis zu 60s)..." + info "Warte auf VPN-Verbindung via ${proto^^}..." local tries=0 - local vpn_ok=false - while [[ $tries -lt 12 ]]; do - sleep 5; echo -n "."; tries=$((tries+1)) - if pct exec "$SEL_ID" -- bash -c \ - "docker exec gluetun wget -qO- https://ipinfo.io/ip 2>/dev/null" &>/dev/null; then + local tls_error=false + + while [[ $tries -lt 18 ]]; do + sleep 5; tries=$((tries+1)) + local elapsed=$(( tries * 5 )) + echo -ne " + ${CYAN}[INFO]${NC} ${proto^^} – ${elapsed}s..." + + local log_snippet + log_snippet=$(pct exec "$SEL_ID" -- bash -c "docker logs --since 30s gluetun 2>&1" 2>/dev/null || echo "") + + # Auth-Fehler → sofort abbrechen, kein Retry + if echo "$log_snippet" | grep -qi "AUTH_FAILED\|auth.*fail\|wrong.*password\|incorrect.*password"; then + echo + echo -e " + ${RED}✗ Authentifizierung fehlgeschlagen!${NC}" + echo -e " ${YELLOW}Service-Credentials prüfen:${NC}" + echo -e " ${CYAN}https://my.nordaccount.com → NordVPN → Set up NordVPN manually${NC}" + pct exec "$SEL_ID" -- bash -c "cd ${FT_DIR} && docker compose down 2>/dev/null || true" + + if confirm "Neue Credentials eingeben?"; then + collect_vpn_config + write_vpn_config + start_and_verify + return + else + error "Abgebrochen." + fi + fi + + # Hostname ungültig → sofort abbrechen + if echo "$log_snippet" | grep -qi "hostname.*not valid\|not one of the possible choices"; then + echo + echo -e " + ${RED}✗ Ungültiger Hostname!${NC}" + echo -e " ${YELLOW}Gültige Server: de507.nordvpn.com, de654.nordvpn.com, de675.nordvpn.com ...${NC}" + pct exec "$SEL_ID" -- bash -c "cd ${FT_DIR} && docker compose down 2>/dev/null || true" + + if confirm "Anderen Hostname eingeben?"; then + collect_vpn_config + write_vpn_config + start_and_verify + return + else + error "Abgebrochen." + fi + fi + + # TLS-Fehler → nächstes Protokoll versuchen + if echo "$log_snippet" | grep -q "TLS Error\|TLS key negotiation"; then + tls_error=true + break + fi + + # Verbunden? + if pct exec "$SEL_ID" -- bash -c "docker exec gluetun wget -qO- https://ipinfo.io/ip 2>/dev/null" &>/dev/null; then vpn_ok=true break fi done echo - if [[ "$vpn_ok" == "true" ]]; then - VPN_IP=$(pct exec "$SEL_ID" -- bash -c \ - "docker exec gluetun wget -qO- https://ipinfo.io/ip 2>/dev/null" || echo "unbekannt") - success "VPN verbunden! Ausgehende IP: ${BOLD}${GREEN}${VPN_IP}${NC}" - break - fi + [[ "$vpn_ok" == "true" ]] && break - # Fehleranalyse - echo - warn "VPN-Verbindung fehlgeschlagen. Gluetun-Log:" - echo -e "${YELLOW}─────────────────────────────────────────${NC}" - pct exec "$SEL_ID" -- bash -c \ - "docker logs gluetun 2>&1 | grep -E 'ERROR|WARN|hostname|credentials|password|Invalid' | tail -20" \ - 2>/dev/null || true - echo -e "${YELLOW}─────────────────────────────────────────${NC}" + # Bei TCP auch TLS-Fehler → endgültig fehlgeschlagen + if [[ "$proto" == "tcp" ]]; then + echo -e " ${RED}✗ VPN konnte weder via UDP noch TCP verbunden werden.${NC}" + echo -e " ${YELLOW}Mögliche Ursachen:${NC}" + echo -e " ${YELLOW}· Falsche NordVPN Service-Credentials${NC}" + echo -e " ${YELLOW}· Server temporär nicht erreichbar – anderen Server wählen${NC}" + echo -e " ${YELLOW}· Netzwerkproblem im LXC${NC}" + pct exec "$SEL_ID" -- bash -c "cd ${FT_DIR} && docker compose down 2>/dev/null || true" - # Häufige Fehler erkennen und erklären - local gluetun_errors - gluetun_errors=$(pct exec "$SEL_ID" -- bash -c \ - "docker logs gluetun 2>&1 | tail -30" 2>/dev/null || echo "") - - if echo "$gluetun_errors" | grep -qi "hostname.*not valid\|not one of the possible choices"; then - echo -e "\n ${RED}FEHLER: Ungültiger Hostname!${NC}" - echo -e " ${YELLOW}Gültige deutsche Server haben das Format: de507.nordvpn.com${NC}" - echo -e " ${YELLOW}Sieh die Fehlermeldung für eine Liste gültiger Hostnamen.${NC}" - elif echo "$gluetun_errors" | grep -qi "auth\|credential\|password\|unauthorized\|401"; then - echo -e "\n ${RED}FEHLER: Ungültige Credentials!${NC}" - echo -e " ${YELLOW}Bitte Service-Credentials prüfen unter:${NC}" - echo -e " ${CYAN}https://my.nordaccount.com → NordVPN → Set up NordVPN manually${NC}" - fi - - pct exec "$SEL_ID" -- bash -c "cd ${FT_DIR} && docker compose down 2>/dev/null || true" - - if [[ $attempt -lt $MAX_ATTEMPTS ]]; then - echo - if confirm "Andere Konfiguration versuchen?"; then + if confirm "Neue Konfiguration eingeben?"; then collect_vpn_config write_vpn_config + start_and_verify + return else - error "Abgebrochen. Stack wurde gestoppt." + error "Abgebrochen. Stack gestoppt." fi fi - attempt=$((attempt+1)) done - [[ "$vpn_ok" != "true" ]] && error "VPN konnte nach ${MAX_ATTEMPTS} Versuchen nicht verbunden werden." + [[ "$vpn_ok" != "true" ]] && error "VPN-Verbindung fehlgeschlagen." # Freqtrade prüfen sleep 6