From 78733901de82d23113cf22adf65230a0e371880b Mon Sep 17 00:00:00 2001 From: Oliver Braasch Date: Mon, 20 Apr 2026 19:11:44 +0200 Subject: [PATCH] Dateien nach "scripts" hochladen --- scripts/freqtrade-lxc-install.sh | 12 ++ scripts/install-vpn.sh | 2 +- scripts/proxmox-vpn-install.sh | 200 +++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 scripts/proxmox-vpn-install.sh diff --git a/scripts/freqtrade-lxc-install.sh b/scripts/freqtrade-lxc-install.sh index 547c5a4..3e87285 100644 --- a/scripts/freqtrade-lxc-install.sh +++ b/scripts/freqtrade-lxc-install.sh @@ -190,6 +190,18 @@ create_lxc() { success "LXC erstellt" + # TUN-Device für NordVPN/Gluetun vorbereiten + # (muss VOR dem Start in die Config, danach braucht install-vpn.sh keinen manuellen Eingriff) + cat >> "/etc/pve/lxc/${CT_ID}.conf" << 'TUNCFG' +# TUN-Device fuer NordVPN/Gluetun (eingetragen von freqtrade-lxc-install.sh) +lxc.cgroup2.devices.allow: c 10:200 rwm +lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file +TUNCFG + success "TUN-Device in LXC-Config eingetragen" + + # Container mit Tag "freqtrade" versehen (für proxmox-vpn-install.sh nutzbar) + pct set "$CT_ID" --tags "freqtrade" 2>/dev/null || true + info "Starte Container..." pct start "$CT_ID" diff --git a/scripts/install-vpn.sh b/scripts/install-vpn.sh index 31bba14..1abdf40 100644 --- a/scripts/install-vpn.sh +++ b/scripts/install-vpn.sh @@ -71,7 +71,7 @@ check_requirements() { mkdir -p /dev/net mknod /dev/net/tun c 10 200 2>/dev/null || true chmod 600 /dev/net/tun 2>/dev/null || true - [[ ! -e /dev/net/tun ]] && error "/dev/net/tun konnte nicht erstellt werden.\nBitte im Proxmox Host prüfen ob in /etc/pve/lxc/.conf diese Zeilen stehen:\n lxc.cgroup2.devices.allow: c 10:200 rwm\n lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file\n\nHinweis: proxmox-install.sh richtet das automatisch ein." + [[ ! -e /dev/net/tun ]] && error "/dev/net/tun konnte nicht erstellt werden.\nBitte im Proxmox Host prüfen ob in /etc/pve/lxc/.conf diese Zeilen stehen:\n lxc.cgroup2.devices.allow: c 10:200 rwm\n lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file\n\nHinweis: freqtrade-lxc-install.sh richtet das automatisch ein." fi success "/dev/net/tun vorhanden" } diff --git a/scripts/proxmox-vpn-install.sh b/scripts/proxmox-vpn-install.sh new file mode 100644 index 0000000..40142b2 --- /dev/null +++ b/scripts/proxmox-vpn-install.sh @@ -0,0 +1,200 @@ +#!/usr/bin/env bash +# ============================================================================= +# Freqtrade NordVPN Addon – Proxmox Host Installer +# Erkennt Freqtrade-Container automatisch per Tag, richtet TUN-Device ein +# und startet install-vpn.sh im Container. +# +# Läuft auf dem PROXMOX HOST. +# Quelle: https://git.obraasch.de/olli1986/freqtrade-proxmox-deploy +# ============================================================================= +set -euo pipefail + +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m' +BLUE='\033[0;34m'; CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m' + +info() { echo -e "${CYAN}[INFO]${NC} $*"; } +success() { echo -e "${GREEN}[ OK ]${NC} $*"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +error() { echo -e "${RED}[FAIL]${NC} $*"; exit 1; } +step() { echo -e "\n${BOLD}${BLUE}▶ $*${NC}"; } + +VPN_SCRIPT_URL="https://git.obraasch.de/olli1986/freqtrade-proxmox-deploy/raw/branch/main/scripts/install-vpn.sh" + +# ── Banner ───────────────────────────────────────────────────────────────────── +print_banner() { + clear + echo -e "${BOLD}${BLUE}" + cat << 'BANNER' + _ _ _ _ ___ _ _ + | \| |___ _ _ __| \ \ / / | \| | + | .` / _ \ '_/ _` \ V /| | .` | + |_|\_\___/_| \__,_|\_/ |_|_|\_| + NordVPN Addon – Proxmox Host Installer +BANNER + echo -e "${NC}" + echo -e " ${CYAN}Richtet TUN-Device ein und startet NordVPN-Setup im LXC${NC}\n" +} + +# ── Proxmox-Check ────────────────────────────────────────────────────────────── +check_host() { + [[ $EUID -ne 0 ]] && error "Bitte als root ausführen!" + command -v pct &>/dev/null || error "pct nicht gefunden – läuft das auf Proxmox?" + success "Proxmox Host erkannt" +} + +# ── Container-Auswahl ───────────────────────────────────────────────────────── +select_container() { + step "Freqtrade Container suchen" + + # Alle laufenden Container mit Tag "freqtrade" finden + mapfile -t TAGGED_IDS < <( + pct list 2>/dev/null | awk 'NR>1{print $1}' | while read -r id; do + tags=$(pct config "$id" 2>/dev/null | grep '^tags:' | sed 's/tags: *//' || true) + if echo "$tags" | grep -qi "freqtrade"; then + name=$(pct config "$id" 2>/dev/null | grep '^hostname:' | awk '{print $2}' || echo "?") + status=$(pct list 2>/dev/null | awk -v id="$id" '$1==id{print $2}') + echo "${id}|${name}|${status}" + fi + done + ) + + # Auch ungetaggte Container mit Hostname "freqtrade" als Fallback + mapfile -t HOSTNAME_IDS < <( + pct list 2>/dev/null | awk 'NR>1{print $1}' | while read -r id; do + hostname=$(pct config "$id" 2>/dev/null | grep '^hostname:' | awk '{print $2}' || true) + tags=$(pct config "$id" 2>/dev/null | grep '^tags:' | sed 's/tags: *//' || true) + if echo "$hostname" | grep -qi "freqtrade" && ! echo "$tags" | grep -qi "freqtrade"; then + status=$(pct list 2>/dev/null | awk -v id="$id" '$1==id{print $2}') + echo "${id}|${hostname}|${status} (kein Tag)" + fi + done + ) + + ALL_IDS=("${TAGGED_IDS[@]}" "${HOSTNAME_IDS[@]}") + + if [[ ${#ALL_IDS[@]} -eq 0 ]]; then + warn "Keine Freqtrade-Container gefunden (Tag 'freqtrade' oder Hostname 'freqtrade*')" + echo + echo -e " Alle verfügbaren Container:" + pct list 2>/dev/null | awk 'NR==1{printf " %-8s %-12s %s\n",$1,$2,$3} NR>1{printf " %-8s %-12s %s\n",$1,$2,$3}' + echo + echo -ne "${YELLOW} ➜ ${NC}Container-ID manuell eingeben: " + read -r SEL_ID + SEL_NAME=$(pct config "$SEL_ID" 2>/dev/null | grep '^hostname:' | awk '{print $2}' || echo "unbekannt") + SEL_STATUS=$(pct list 2>/dev/null | awk -v id="$SEL_ID" '$1==id{print $2}') + elif [[ ${#ALL_IDS[@]} -eq 1 ]]; then + # Genau einer gefunden → direkt nehmen + IFS='|' read -r SEL_ID SEL_NAME SEL_STATUS <<< "${ALL_IDS[0]}" + echo -e " ${GREEN}Gefunden:${NC} CT ${CYAN}${SEL_ID}${NC} | ${CYAN}${SEL_NAME}${NC} | ${SEL_STATUS}" + else + # Mehrere → Auswahl anzeigen + echo -e " ${CYAN}Gefundene Freqtrade-Container:${NC}\n" + echo -e " ${BOLD}Nr ID Hostname Status${NC}" + echo -e " ${BLUE}────────────────────────────────────${NC}" + local i=1 + for entry in "${ALL_IDS[@]}"; do + IFS='|' read -r cid cname cstatus <<< "$entry" + printf " ${CYAN}%-4s${NC} %-8s %-16s %s\n" "$i" "$cid" "$cname" "$cstatus" + ((i++)) + done + echo + echo -ne "${YELLOW} ➜ ${NC}Nummer auswählen [1]: " + read -r sel_nr + sel_nr="${sel_nr:-1}" + IFS='|' read -r SEL_ID SEL_NAME SEL_STATUS <<< "${ALL_IDS[$((sel_nr-1))]}" + fi + + [[ -z "${SEL_ID:-}" ]] && error "Keine Container-ID gewählt!" + + # Status-Check + local cur_status + cur_status=$(pct list 2>/dev/null | awk -v id="$SEL_ID" '$1==id{print $2}' || echo "unknown") + if [[ "$cur_status" != "running" ]]; then + warn "Container $SEL_ID ist nicht running (Status: $cur_status)" + echo -ne "${YELLOW} ➜ ${NC}Container starten? [j/N]: " + read -r ans + if [[ "$ans" =~ ^[jJyY]$ ]]; then + pct start "$SEL_ID" + sleep 5 + success "Container gestartet" + else + error "Container muss laufen für die Installation!" + fi + fi + + success "Gewählt: CT ${SEL_ID} | ${SEL_NAME}" +} + +# ── TUN-Device einrichten ────────────────────────────────────────────────────── +setup_tun() { + step "TUN-Device für CT ${SEL_ID} prüfen" + + local conf="/etc/pve/lxc/${SEL_ID}.conf" + [[ ! -f "$conf" ]] && error "LXC-Config nicht gefunden: $conf" + + local tun_ok=true + grep -q "lxc.cgroup2.devices.allow: c 10:200 rwm" "$conf" || tun_ok=false + grep -q "lxc.mount.entry: /dev/net/tun" "$conf" || tun_ok=false + + if [[ "$tun_ok" == "true" ]]; then + success "TUN-Device bereits konfiguriert" + return + fi + + info "TUN-Device Zeilen fehlen – trage ein..." + cat >> "$conf" << 'TUNCFG' +# TUN-Device fuer NordVPN/Gluetun (eingetragen von proxmox-vpn-install.sh) +lxc.cgroup2.devices.allow: c 10:200 rwm +lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file +TUNCFG + success "TUN-Device in $conf eingetragen" + + # Container neu starten damit die Config greift + info "Container neu starten damit TUN-Device aktiv wird..." + pct stop "$SEL_ID" + sleep 3 + pct start "$SEL_ID" + sleep 5 + + # Warten auf Netzwerk + local tries=0 + until pct exec "$SEL_ID" -- bash -c "ip route | grep -q default" 2>/dev/null; do + sleep 3; tries=$((tries+1)); echo -n "." + [[ $tries -ge 15 ]] && error "Netzwerk nach Neustart nicht erreichbar!" + done + echo + success "Container läuft wieder mit TUN-Device" +} + +# ── install-vpn.sh im Container ausführen ───────────────────────────────────── +run_vpn_install() { + step "NordVPN-Setup im Container starten" + echo -e "\n ${YELLOW}Das install-vpn.sh Script läuft jetzt interaktiv im Container.${NC}" + echo -e " ${YELLOW}Du wirst nach deinen NordVPN Service-Credentials gefragt.${NC}\n" + echo -e " Service-Credentials: ${CYAN}https://my.nordaccount.com${NC}" + echo -e " ${CYAN}→ NordVPN → 'Set up NordVPN manually'${NC}\n" + + echo -ne "${YELLOW} ➜ ${NC}Jetzt starten? [j/N]: " + read -r ans + [[ ! "$ans" =~ ^[jJyY]$ ]] && { info "Abgebrochen. Manuell starten mit:\n pct enter ${SEL_ID} dann: bash -c \"\$(curl -fsSL ${VPN_SCRIPT_URL})\""; exit 0; } + + # Script in Container laden und interaktiv ausführen + info "Lade install-vpn.sh in Container..." + pct exec "$SEL_ID" -- bash -c "curl -fsSL '${VPN_SCRIPT_URL}' -o /root/install-vpn.sh && chmod +x /root/install-vpn.sh" + success "Script geladen – starte interaktive Session im Container..." + echo + echo -e "${BOLD}${BLUE}──── Container ${SEL_ID} – NordVPN Setup ────${NC}" + # pct enter öffnet eine echte interaktive Shell → Script direkt übergeben + pct exec "$SEL_ID" -- bash /root/install-vpn.sh +} + +# ── Hauptprogramm ────────────────────────────────────────────────────────────── +main() { + print_banner + check_host + select_container + setup_tun + run_vpn_install +} + +main "$@"