Dateien nach "scripts" hochladen

This commit is contained in:
2026-04-22 13:09:22 +02:00
parent d51a612764
commit 2c62afcb34
+102 -37
View File
@@ -1,7 +1,13 @@
#!/usr/bin/env bash
# =============================================================================
# Freqtrade NordVPN Addon Proxmox Host Installer (Custom Config Edition)
# Ablauf: System -> Ordner -> Filebrowser -> User-Input -> VPN-Start
# Läuft komplett auf dem PROXMOX HOST.
# - Richtet TUN-Device ein
# - Erstellt VPN-Ordner & Berechtigungen
# - Fragt NordVPN-Credentials ab & pausiert für custom.conf
# - Ermittelt automatisch das lokale Subnetz
# - Schreibt docker-compose.yml & startet den Stack
# - NEU: Integriert den VPN-Ordner automatisch in den Filebrowser
# =============================================================================
set -euo pipefail
@@ -27,11 +33,22 @@ confirm() {
read -r ans; [[ "$ans" =~ ^[jJyY]$ ]]
}
# ── Banner ─────────────────────────────────────────────────────────────────────
print_banner() {
clear
echo -e "${BOLD}${BLUE} NordVPN Custom Config Installer (Filebrowser-First)${NC}\n"
echo -e "${BOLD}${BLUE}"
cat << 'BANNER'
_ _ _ _ ___ _ _
| \| |___ _ _ __| \ \ / / | \| |
| .` / _ \ '_/ _` \ V /| | .` |
|_|\_\___/_| \__,_|\_/ |_|_|\_|
NordVPN Custom Config Installer
BANNER
echo -e "${NC}"
echo -e " ${CYAN}Automatisiertes Setup für feste IPs via custom.conf${NC}\n"
}
# ── Proxmox-Check ──────────────────────────────────────────────────────────────
check_host() {
step "Proxmox Host prüfen"
[[ $EUID -ne 0 ]] && error "Bitte als root ausführen!"
@@ -39,28 +56,43 @@ check_host() {
success "Proxmox Host erkannt"
}
# ── Container-Auswahl ─────────────────────────────────────────────────────────
select_container() {
step "Freqtrade Container auswählen"
local -a display_list=()
while IFS= read -r line; do
local ct_id status hostname
local ct_id status hostname tags
ct_id=$(echo "$line" | awk '{print $1}')
status=$(echo "$line" | awk '{print $2}')
[[ "$ct_id" =~ ^[0-9]+$ ]] || continue
hostname=$(pct config "$ct_id" 2>/dev/null | awk '/^hostname:/{print $2}' || echo "?")
display_list+=("${ct_id}|${hostname}|${status}")
tags=$(pct config "$ct_id" 2>/dev/null | awk '/^tags:/{print $2}' || echo "")
if echo "$tags" | grep -qi "freqtrade"; then
display_list+=("${ct_id}|${hostname}|${status}")
fi
done < <(pct list 2>/dev/null | tail -n +2)
echo -e " ${BOLD}Nr ID Hostname${NC}"
[[ ${#display_list[@]} -eq 0 ]] && error "Keine Container mit Tag 'freqtrade' gefunden!"
echo -e " ${BOLD}Nr ID Hostname Status${NC}"
echo -e " ${BLUE}─────────────────────────────────────────${NC}"
local i=1
for entry in "${display_list[@]}"; do
IFS='|' read -r cid cname cstatus <<< "$entry"
printf " ${CYAN}%-4s${NC} %-8s %-18s\n" "$i" "$cid" "$cname"
printf " ${CYAN}%-4s${NC} %-8s %-18s %-10s\n" "$i" "$cid" "$cname" "$cstatus"
((i++))
done
echo
ask "Container Nummer wählen" "1"; local sel_nr="$REPLY"
local sel_nr=1
[[ ${#display_list[@]} -gt 1 ]] && { ask "Container Nummer wählen" "1"; sel_nr="$REPLY"; }
IFS='|' read -r SEL_ID SEL_NAME SEL_STATUS <<< "${display_list[$((sel_nr-1))]}"
[[ -z "${SEL_ID:-}" ]] && error "Ungültige Auswahl!"
success "Gewählt: CT ${SEL_ID}"
if [[ "$SEL_STATUS" != "running" ]]; then
info "Starte Container..."
@@ -68,83 +100,113 @@ select_container() {
fi
}
setup_base_system() {
step "Grundsystem & VPN-Ordner vorbereiten"
# ── TUN-Device & Ordner einrichten ─────────────────────────────────────────────
setup_system() {
step "System & VPN-Ordner vorbereiten"
# TUN-Device in LXC Config
# 1. TUN-Device in LXC Config schreiben
local conf="/etc/pve/lxc/${SEL_ID}.conf"
if ! grep -q "lxc.mount.entry: /dev/net/tun" "$conf"; then
info "Konfiguriere TUN-Device..."
info "Trage TUN-Device in Config ein..."
cat >> "$conf" << 'TUNCFG'
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
TUNCFG
pct stop "$SEL_ID" && sleep 2 && pct start "$SEL_ID" && sleep 5
pct stop "$SEL_ID" && sleep 3 && pct start "$SEL_ID"
sleep 5
success "TUN-Device eingerichtet & Container neu gestartet"
else
success "TUN-Device war bereits konfiguriert"
fi
# VPN Ordner erstellen (BEVOR Filebrowser ihn braucht)
# 2. Ordner und Datei erstellen & Rechte setzen
pct exec "$SEL_ID" -- bash -c "
mkdir -p /opt/docker-projekte/VPN
touch /opt/docker-projekte/VPN/custom.conf
chown 1000:1000 -R /opt/docker-projekte/VPN
"
success "VPN Ordner ist bereit."
success "VPN-Ordner und custom.conf erstellt (/opt/docker-projekte/VPN)"
}
# ── Filebrowser anpassen ───────────────────────────────────────────────────────
update_filebrowser() {
step "Filebrowser Anbindung (Vorbereitung)"
step "Filebrowser aktualisieren"
local FB_DIR="/opt/docker-projekte/filebrowser"
local FB_YML="${FB_DIR}/docker-compose.yml"
# Prüfen, ob der Filebrowser überhaupt da ist
if pct exec "$SEL_ID" -- bash -c "[ -f ${FB_YML} ]"; then
if ! pct exec "$SEL_ID" -- bash -c "grep -q '/opt/docker-projekte/VPN:/srv/VPN' ${FB_YML}"; then
info "Binde VPN-Ordner in Filebrowser ein..."
pct exec "$SEL_ID" -- bash -c "sed -i '/volumes:/a \\ - /opt/docker-projekte/VPN:/srv/VPN' ${FB_YML}"
pct exec "$SEL_ID" -- bash -c "cd ${FB_DIR} && docker compose down && docker compose up -d"
success "Filebrowser neu gestartet. VPN-Ordner ist jetzt im Web-UI sichtbar!"
info "Filebrowser gefunden. Prüfe Konfiguration..."
# Prüfen, ob der Mount schon existiert, um Doppel-Einträge zu vermeiden
if pct exec "$SEL_ID" -- bash -c "grep -q '/opt/docker-projekte/VPN:/srv/VPN' ${FB_YML}"; then
success "VPN-Ordner ist bereits im Filebrowser gemountet."
else
success "Filebrowser bereits konfiguriert."
info "Füge VPN-Mountpunkt zur docker-compose.yml hinzu..."
# Fügt die Zeile exakt nach 'volumes:' ein
pct exec "$SEL_ID" -- bash -c "sed -i '/volumes:/a \\ - /opt/docker-projekte/VPN:/srv/VPN' ${FB_YML}"
success "Konfiguration ergänzt."
info "Starte Filebrowser neu..."
pct exec "$SEL_ID" -- bash -c "cd ${FB_DIR} && docker compose down && docker compose up -d"
success "Filebrowser ist neugestartet und hat jetzt Zugriff auf den VPN-Ordner!"
fi
else
warn "Filebrowser nicht gefunden. Du musst die custom.conf manuell bearbeiten."
info "Kein Filebrowser unter ${FB_DIR} gefunden. Überspringe diesen Schritt."
fi
}
# ── Konfiguration abfragen & Datei befüllen lassen ─────────────────────────────
collect_and_wait() {
step "Konfiguration & User-Input"
step "NordVPN Credentials & Config"
echo -e " ${YELLOW}Hinweis: Bitte nutze die Service-Credentials von der NordVPN-Website!${NC}"
ask "NordVPN Service-Username"
NORD_USER="$REPLY"
ask "NordVPN Service-Passwort"
NORD_PASS="$REPLY"
echo -e "\n${BOLD}${CYAN}=== JETZT CUSTOM.CONF BEFÜLLEN ===${NC}"
echo -e "Öffne dein Filebrowser Web-Interface (${BOLD}Port 8081${NC})."
echo -e "Gehe in den Ordner ${BOLD}VPN${NC} und bearbeite die ${BOLD}custom.conf${NC}."
echo -e "Füge dort den Inhalt deiner .ovpn Datei von NordVPN ein."
echo -e "\n${BOLD}${CYAN}=== WICHTIGER SCHRITT ===${NC}"
echo -e "Bitte öffne nun auf deinem Server (oder via SFTP/Filebrowser) die Datei im Container:"
echo -e " ${BOLD}/opt/docker-projekte/VPN/custom.conf${NC}"
echo -e "Füge dort den kompletten Text deiner NordVPN-Konfigurationsdatei (.ovpn) ein und speichere."
echo -e "Tipp: Du kannst auch in einer zweiten Konsole ausführen:"
echo -e " pct enter ${SEL_ID} und dann nano /opt/docker-projekte/VPN/custom.conf"
while true; do
echo
if confirm "Ist die custom.conf im Filebrowser gespeichert?"; then
if confirm "Hast du die custom.conf befüllt und gespeichert?"; then
# Kurzer Check, ob die Datei nicht mehr leer ist
local size
size=$(pct exec "$SEL_ID" -- stat -c%s /opt/docker-projekte/VPN/custom.conf 2>/dev/null || echo 0)
[[ "$size" -gt 10 ]] && { success "Inhalt erkannt!"; break; }
warn "Die Datei ist noch leer oder zu klein. Bitte nochmal prüfen."
if [[ "$size" -gt 10 ]]; then
success "Datei ist befüllt!"
break
else
warn "Die Datei scheint noch leer zu sein. Bitte überprüfe das."
fi
fi
done
}
deploy_vpn_stack() {
step "VPN & Freqtrade Stack starten"
# ── Docker Compose schreiben & anwenden ────────────────────────────────────────
deploy_stack() {
step "Docker Stack anwenden"
local FT_DIR="/opt/docker-projekte/freqtrade"
# Subnetz ermitteln
# Lokales Subnetz automatisch ermitteln (z.B. 192.168.178.0/24)
local SUBNET
SUBNET=$(pct exec "$SEL_ID" -- bash -c "ip -o -f inet addr show eth0 | awk '{print \$4}' | sed 's/\.[0-9]\{1,3\}\//.0\//'" 2>/dev/null || echo "192.168.0.0/24")
info "Ermitteltes lokales Subnetz: ${SUBNET}"
info "Schreibe neue docker-compose.yml für Freqtrade..."
# Alten Stack stoppen
info "Stoppe aktuellen Stack..."
pct exec "$SEL_ID" -- bash -c "cd ${FT_DIR} && docker compose down 2>/dev/null || true"
# Neue docker-compose.yml generieren
info "Schreibe neue docker-compose.yml..."
pct exec "$SEL_ID" -- bash -c "cat > ${FT_DIR}/docker-compose.yml << 'COMPOSEEOF'
version: '3.8'
services:
gluetun:
image: qmcgaw/gluetun:latest
@@ -160,6 +222,7 @@ services:
- OPENVPN_CUSTOM_CONFIG=/gluetun/custom.conf
- OPENVPN_USER=${NORD_USER}
- OPENVPN_PASSWORD=${NORD_PASS}
# Automatisch ermitteltes lokales Netz für Erreichbarkeit
- FIREWALL_OUTBOUND_SUBNETS=${SUBNET}
volumes:
- /opt/docker-projekte/VPN:/gluetun
@@ -184,10 +247,12 @@ services:
--strategy SampleStrategy
COMPOSEEOF"
pct exec "$SEL_ID" -- bash -c "cd ${FT_DIR} && docker compose down 2>/dev/null || true"
# Stack starten
info "Starte Stack neu..."
pct exec "$SEL_ID" -- bash -c "cd ${FT_DIR} && docker compose up -d"
success "Freqtrade & VPN Stack gestartet!"
sleep 5
success "Deployment abgeschlossen!"
}
main() {