Dateien nach "scripts" hochladen
This commit is contained in:
+146
-28
@@ -182,7 +182,8 @@ collect_vpn_config() {
|
||||
NORD_USER="$REPLY"
|
||||
[[ -z "$NORD_USER" ]] && error "Username darf nicht leer sein!"
|
||||
|
||||
ask_secret "NordVPN Service-Passwort"
|
||||
stty echo 2>/dev/null || true
|
||||
ask "NordVPN Service-Passwort"
|
||||
NORD_PASS="$REPLY"
|
||||
[[ -z "$NORD_PASS" ]] && error "Passwort darf nicht leer sein!"
|
||||
|
||||
@@ -196,8 +197,10 @@ collect_vpn_config() {
|
||||
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}"
|
||||
echo -e "\n ${YELLOW}Hostnamen Format: de507.nordvpn.com, de654.nordvpn.com etc.${NC}"
|
||||
echo -e " ${YELLOW}Wichtig: NordVPN zeigt oft neue Server die Gluetun noch nicht kennt.${NC}"
|
||||
echo -e " ${YELLOW}Falls 'Ungültiger Hostname' erscheint → die angezeigten gültigen Server nutzen.${NC}"
|
||||
echo -e " ${CYAN}Tipp: Modus 1 (Serverland) ist einfacher – Gluetun wählt selbst.${NC}"
|
||||
ask "Hostname (z.B. de507.nordvpn.com)"
|
||||
VPN_HOSTNAME="$REPLY"; VPN_COUNTRY=""
|
||||
else
|
||||
@@ -205,13 +208,9 @@ collect_vpn_config() {
|
||||
VPN_COUNTRY="$REPLY"; VPN_HOSTNAME=""
|
||||
fi
|
||||
|
||||
# FreqUI Port aus bestehender config ermitteln
|
||||
local current_port
|
||||
current_port=$(pct exec "$SEL_ID" -- bash -c \
|
||||
"grep -oP '0\.0\.0\.0:\K[0-9]+(?=:[0-9]+)' /opt/docker-projekte/freqtrade/docker-compose.yml 2>/dev/null | head -1 || echo 8080" \
|
||||
2>/dev/null || echo "8080")
|
||||
ask "FreqUI Port" "$current_port"
|
||||
FT_PORT="$REPLY"
|
||||
# FreqUI Port aus bestehender docker-compose.yml lesen (ändert sich nicht)
|
||||
FT_PORT=$(pct exec "$SEL_ID" -- bash -c "grep -oP '0\.0\.0\.0:\K[0-9]+(?=:[0-9]+)' /opt/docker-projekte/freqtrade/docker-compose.yml 2>/dev/null | head -1 || echo 8080" 2>/dev/null || echo "8080")
|
||||
info "FreqUI Port: ${FT_PORT} (aus bestehender Konfiguration)"
|
||||
|
||||
echo -e "\n${BOLD}${BLUE}══════════ Zusammenfassung ══════════${NC}"
|
||||
echo -e " Container: ${CYAN}CT ${SEL_ID} | ${SEL_NAME}${NC}"
|
||||
@@ -227,6 +226,8 @@ collect_vpn_config() {
|
||||
# ── Konfiguration in Container schreiben ──────────────────────────────────────
|
||||
write_vpn_config() {
|
||||
step "VPN-Konfiguration in Container schreiben"
|
||||
# Image: custom build bei Dedicated-IP, sonst offizielles Image
|
||||
GLUETUN_IMAGE="${GLUETUN_IMAGE:-qmcgaw/gluetun:latest}"
|
||||
|
||||
local FT_DIR="/opt/docker-projekte/freqtrade"
|
||||
local NORD_USER_B64 NORD_PASS_B64
|
||||
@@ -234,9 +235,15 @@ write_vpn_config() {
|
||||
NORD_PASS_B64=$(printf '%s' "$NORD_PASS" | base64 -w0)
|
||||
|
||||
local VPN_SERVER_LINE=""
|
||||
[[ -n "$VPN_HOSTNAME" ]] \
|
||||
&& VPN_SERVER_LINE=" - SERVER_HOSTNAMES=${VPN_HOSTNAME}" \
|
||||
|| VPN_SERVER_LINE=" - SERVER_COUNTRIES=${VPN_COUNTRY}"
|
||||
local VPN_CUSTOM_LINE=""
|
||||
if [[ -n "$VPN_HOSTNAME" ]]; then
|
||||
# Dedicated-IP: Custom Config direkt mit IP – bypasses Gluetun Hostname-Validierung
|
||||
VPN_SERVER_LINE=" - VPN_SERVICE_PROVIDER=custom"
|
||||
VPN_CUSTOM_LINE=" - OPENVPN_CUSTOM_CONFIG=/gluetun/nordvpn-custom.conf"
|
||||
else
|
||||
VPN_SERVER_LINE=" - VPN_SERVICE_PROVIDER=nordvpn"
|
||||
VPN_CUSTOM_LINE=" - SERVER_COUNTRIES=${VPN_COUNTRY}"
|
||||
fi
|
||||
|
||||
# Backup
|
||||
pct exec "$SEL_ID" -- bash -c \
|
||||
@@ -275,7 +282,7 @@ services:
|
||||
# Gluetun läuft als HTTP-Proxy auf Port 8888.
|
||||
# Freqtrade schickt nur den Exchange-Traffic darüber.
|
||||
gluetun:
|
||||
image: qmcgaw/gluetun:latest
|
||||
image: ${GLUETUN_IMAGE:-qmcgaw/gluetun:latest}
|
||||
container_name: gluetun
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
@@ -283,11 +290,11 @@ services:
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
environment:
|
||||
- VPN_SERVICE_PROVIDER=nordvpn
|
||||
${VPN_SERVER_LINE}
|
||||
- VPN_TYPE=openvpn
|
||||
- OPENVPN_USER=\${OPENVPN_USER}
|
||||
- OPENVPN_PASSWORD=\${OPENVPN_PASSWORD}
|
||||
${VPN_SERVER_LINE}
|
||||
${VPN_CUSTOM_LINE}
|
||||
# HTTP-Proxy aktivieren – darüber leitet Freqtrade den Binance-Traffic
|
||||
- HTTPPROXY=on
|
||||
- HTTPPROXY_LOG=off
|
||||
@@ -345,6 +352,90 @@ start_and_verify() {
|
||||
local vpn_ok=false
|
||||
VPN_IP=""
|
||||
|
||||
# Bei Hostname-Modus: Gluetun aus GitHub klonen, Server eintragen, neu kompilieren
|
||||
# → Löst das Problem dauerhaft: de1370 wird in die Binary eingebaut
|
||||
if [[ -n "${VPN_HOSTNAME:-}" ]]; then
|
||||
step "Gluetun Custom Build für ${VPN_HOSTNAME}"
|
||||
|
||||
# IP per DNS auflösen
|
||||
local server_ip=""
|
||||
server_ip=$(pct exec "$SEL_ID" -- bash -c "getent hosts ${VPN_HOSTNAME} 2>/dev/null | awk '{print \$1}' | head -1" 2>/dev/null || echo "")
|
||||
[[ -z "$server_ip" ]] && server_ip=$(pct exec "$SEL_ID" -- bash -c "nslookup ${VPN_HOSTNAME} 2>/dev/null | awk '/Address:/ && !/#/{print \$2}' | head -1" 2>/dev/null || echo "")
|
||||
[[ -z "$server_ip" ]] && error "IP für ${VPN_HOSTNAME} nicht auflösbar!"
|
||||
info "DNS: ${VPN_HOSTNAME} → ${server_ip}"
|
||||
|
||||
# Prüfen ob Image bereits existiert (kein Rebuild nötig)
|
||||
local img_exists
|
||||
img_exists=$(pct exec "$SEL_ID" -- bash -c "docker image inspect gluetun-custom:latest 2>/dev/null | grep -c 'Id' || echo 0" 2>/dev/null || echo "0")
|
||||
|
||||
if [[ "$img_exists" -gt 0 ]]; then
|
||||
# Prüfen ob der Hostname schon drin ist
|
||||
local host_in_img
|
||||
host_in_img=$(pct exec "$SEL_ID" -- bash -c "docker run --rm --entrypoint sh gluetun-custom:latest -c 'cat /gluetun/servers.json 2>/dev/null | grep -c ${VPN_HOSTNAME} || echo 0'" 2>/dev/null || echo "0")
|
||||
if [[ "$host_in_img" -gt 0 ]]; then
|
||||
success "gluetun-custom:latest bereits vorhanden und enthält ${VPN_HOSTNAME}"
|
||||
GLUETUN_IMAGE="gluetun-custom:latest"
|
||||
return 0 2>/dev/null || true
|
||||
fi
|
||||
info "Image vorhanden, aber ${VPN_HOSTNAME} fehlt – baue neu..."
|
||||
fi
|
||||
|
||||
# git installieren falls nötig
|
||||
pct exec "$SEL_ID" -- bash -c "command -v git &>/dev/null || apt-get install -y -qq git" 2>/dev/null
|
||||
|
||||
info "Klone Gluetun von GitHub (einmalig, ~3-5 Min zum Kompilieren)..."
|
||||
pct exec "$SEL_ID" -- bash -c "rm -rf /tmp/gluetun-build && git clone --depth 1 https://github.com/qdm12/gluetun.git /tmp/gluetun-build 2>&1 | tail -3"
|
||||
|
||||
info "Füge ${VPN_HOSTNAME} (${server_ip}) in servers.json ein..."
|
||||
pct exec "$SEL_ID" -- bash -c "python3 << PYEOF
|
||||
import json, copy, sys
|
||||
|
||||
path = '/tmp/gluetun-build/internal/storage/servers.json'
|
||||
hostname = '${VPN_HOSTNAME}'
|
||||
ip = '${server_ip}'
|
||||
|
||||
with open(path) as f:
|
||||
db = json.load(f)
|
||||
|
||||
servers = db.get('nordvpn', {}).get('servers', [])
|
||||
|
||||
if any(s.get('hostname') == hostname for s in servers):
|
||||
print(f'Bereits vorhanden: {hostname}')
|
||||
sys.exit(0)
|
||||
|
||||
# Deutschen OpenVPN-Eintrag als Template klonen
|
||||
template = next(
|
||||
(s for s in servers if s.get('country','').lower() == 'germany' and s.get('vpn') == 'openvpn'),
|
||||
servers[0]
|
||||
)
|
||||
entry = copy.deepcopy(template)
|
||||
entry['hostname'] = hostname
|
||||
entry['ips'] = [ip]
|
||||
|
||||
servers.append(entry)
|
||||
db['nordvpn']['servers'] = servers
|
||||
|
||||
with open(path, 'w') as f:
|
||||
json.dump(db, f, indent=2)
|
||||
print(f'Eingetragen: {hostname} ({ip}) – Gesamt NordVPN-Server: {len(servers)}')
|
||||
PYEOF"
|
||||
|
||||
info "Kompiliere Gluetun Docker Image (dauert ~3-5 Minuten)..."
|
||||
echo -e " ${YELLOW}Bitte warten – Go Multi-Stage Build...${NC}"
|
||||
pct exec "$SEL_ID" -- bash -c "cd /tmp/gluetun-build && docker build -t gluetun-custom:latest . 2>&1 | grep -E '^Step|Successfully|error|Error|=>|RUN|COPY' | tail -30" && success "gluetun-custom:latest erfolgreich gebaut!" || error "Docker Build fehlgeschlagen. Prüfe: pct exec ${SEL_ID} -- docker build /tmp/gluetun-build"
|
||||
|
||||
GLUETUN_IMAGE="gluetun-custom:latest"
|
||||
info "Aufräumen..."
|
||||
pct exec "$SEL_ID" -- bash -c "rm -rf /tmp/gluetun-build" 2>/dev/null || true
|
||||
else
|
||||
GLUETUN_IMAGE="qmcgaw/gluetun:latest"
|
||||
fi
|
||||
|
||||
# docker-compose.yml mit korrektem Image aktualisieren
|
||||
info "Setze Image in docker-compose.yml: ${GLUETUN_IMAGE}"
|
||||
pct exec "$SEL_ID" -- bash -c "sed -i 's|image: .*gluetun.*|image: ${GLUETUN_IMAGE}|' ${FT_DIR}/docker-compose.yml"
|
||||
|
||||
|
||||
# Protokoll-Reihenfolge: UDP zuerst, dann automatisch TCP
|
||||
for proto in udp tcp; do
|
||||
[[ "$proto" == "tcp" ]] && info "UDP fehlgeschlagen – versuche TCP automatisch..."
|
||||
@@ -367,7 +458,7 @@ start_and_verify() {
|
||||
${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 "")
|
||||
log_snippet=$(pct exec "$SEL_ID" -- bash -c "docker logs gluetun 2>&1 | tail -60" 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
|
||||
@@ -388,22 +479,49 @@ start_and_verify() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Hostname ungültig → sofort abbrechen
|
||||
# Hostname ungültig → gültige Server aus Log parsen und zur Auswahl anbieten
|
||||
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"
|
||||
echo -e " ${RED}✗ Ungültiger Hostname: ${VPN_HOSTNAME}${NC}"
|
||||
echo -e " ${YELLOW}Nicht in Gluetuns Server-Datenbank. Bitte einen der folgenden wählen:${NC}
|
||||
"
|
||||
|
||||
if confirm "Anderen Hostname eingeben?"; then
|
||||
collect_vpn_config
|
||||
write_vpn_config
|
||||
start_and_verify
|
||||
return
|
||||
# Mehr Log holen – die Server-Liste ist sehr lang
|
||||
local full_log valid_servers
|
||||
full_log=$(pct exec "$SEL_ID" -- bash -c "docker logs gluetun 2>&1" 2>/dev/null || echo "")
|
||||
# Nur deutsche Server aus der Liste filtern (de*)
|
||||
valid_servers=$(echo "$full_log" | grep -oP 'de[0-9]+\.nordvpn\.com' | sort -uV | head -20)
|
||||
# Falls keine deutschen → alle zeigen
|
||||
[[ -z "$valid_servers" ]] && valid_servers=$(echo "$full_log" | grep -oP '[a-z]{2}[0-9]+\.nordvpn\.com' | sort -u | head -20)
|
||||
|
||||
if [[ -n "$valid_servers" ]]; then
|
||||
local i=1
|
||||
while IFS= read -r srv; do
|
||||
printf " ${CYAN}%2s)${NC} %s
|
||||
" "$i" "$srv"
|
||||
i=$((i+1))
|
||||
done <<< "$valid_servers"
|
||||
echo
|
||||
echo -ne "${YELLOW} ➜ ${NC}Nummer wählen oder Hostname direkt eingeben: "
|
||||
read -r sel
|
||||
if [[ "$sel" =~ ^[0-9]+$ ]]; then
|
||||
VPN_HOSTNAME=$(echo "$valid_servers" | sed -n "${sel}p")
|
||||
elif [[ -n "$sel" ]]; then
|
||||
VPN_HOSTNAME="$sel"
|
||||
fi
|
||||
if [[ -n "$VPN_HOSTNAME" ]]; then
|
||||
info "Neuer Hostname: $VPN_HOSTNAME – schreibe Config neu..."
|
||||
pct exec "$SEL_ID" -- bash -c "cd ${FT_DIR} && docker compose down 2>/dev/null || true"
|
||||
write_vpn_config
|
||||
tries=0; tls_error=false
|
||||
pct exec "$SEL_ID" -- bash -c "cd ${FT_DIR} && docker compose up -d 2>&1" || true
|
||||
continue
|
||||
fi
|
||||
else
|
||||
error "Abgebrochen."
|
||||
echo -e " ${YELLOW}Keine Server im Log gefunden. Modus 1 (Serverland) empfohlen.${NC}"
|
||||
fi
|
||||
pct exec "$SEL_ID" -- bash -c "cd ${FT_DIR} && docker compose down 2>/dev/null || true"
|
||||
error "Abgebrochen."
|
||||
fi
|
||||
|
||||
# TLS-Fehler → nächstes Protokoll versuchen
|
||||
|
||||
Reference in New Issue
Block a user