Files
freqtrade-proxmox-deploy/scripts/install-vpn.sh
T

280 lines
9.3 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# =============================================================================
# Freqtrade NordVPN Addon (Gluetun)
# Ergänzt eine bestehende Freqtrade-Installation um NordVPN-Routing.
# Läuft im FREQTRADE LXC (nicht 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}"; }
ask() {
local prompt="$1" default="${2:-}"
if [[ -n "$default" ]]; then
echo -ne "${YELLOW}${NC}${prompt} [${CYAN}${default}${NC}]: "
else
echo -ne "${YELLOW}${NC}${prompt}: "
fi
read -r REPLY; REPLY="${REPLY:-$default}"
}
ask_secret() {
echo -ne "${YELLOW}${NC}${1}: "
read -rs REPLY; echo
}
confirm() {
echo -ne "${YELLOW}${NC}${1} [${CYAN}j${NC}/N]: "
read -r ans; [[ "$ans" =~ ^[jJyY]$ ]]
}
print_banner() {
clear
echo -e "${BOLD}${BLUE}"
echo " _ _ _ ___ ___ _ _"
echo " | \| |___ _ _ __ | \ \ \ / / | \| |"
echo " | .\` / _ \ '_/ _\` \ V /\ V /| | .\` |"
echo " |_|\_\___/_| \__,_|\_/ \_/ |_|_|\_|"
echo " Freqtrade + NordVPN Addon (Gluetun)"
echo -e "${NC}"
echo -e " ${CYAN}Ergänzt Freqtrade um NordVPN-Routing via Gluetun${NC}"
echo -e " ${YELLOW}Läuft im Freqtrade LXC nicht auf dem Proxmox Host!${NC}\n"
}
check_requirements() {
step "Voraussetzungen prüfen"
[[ $EUID -ne 0 ]] && error "Bitte als root ausführen!"
command -v docker &>/dev/null || error "Docker nicht gefunden."
docker compose version &>/dev/null || error "Docker Compose Plugin nicht gefunden."
success "Docker + Compose vorhanden"
FT_DIR=""
for candidate in /opt/docker-projekte/freqtrade /opt/freqtrade; do
if [[ -f "$candidate/docker-compose.yml" ]] && [[ -d "$candidate/user_data" ]]; then
FT_DIR="$candidate"; break
fi
done
[[ -z "$FT_DIR" ]] && error "Keine Freqtrade-Installation gefunden in /opt/docker-projekte/freqtrade/"
success "Freqtrade gefunden: $FT_DIR"
if [[ ! -e /dev/net/tun ]]; then
warn "/dev/net/tun fehlt lege an..."
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/<ID>.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"
}
collect_config() {
step "NordVPN Konfiguration"
echo -e "\n ${BOLD}Service-Credentials${NC} findest du unter:"
echo -e " ${CYAN}https://my.nordaccount.com → NordVPN → 'Set up NordVPN manually'${NC}"
echo -e " ${RED} Nicht deine E-Mail/Passwort die Service-Credentials!${NC}\n"
ask "NordVPN Service-Username"
NORD_USER="$REPLY"
[[ -z "$NORD_USER" ]] && error "Username darf nicht leer sein!"
ask_secret "NordVPN Service-Passwort"
NORD_PASS="$REPLY"
[[ -z "$NORD_PASS" ]] && error "Passwort darf nicht leer sein!"
echo
echo -e " ${BOLD}VPN-Server Modus:${NC}"
echo -e " ${CYAN}1)${NC} Serverland normaler Server (IP kann wechseln)"
echo -e " ${CYAN}2)${NC} Hostname spezifischen Server/Dedicated-IP pinnen"
ask "Auswahl [1/2]" "1"
VPN_MODE="$REPLY"
if [[ "$VPN_MODE" == "2" ]]; then
ask "Hostname (z.B. de123.nordvpn.com)"
VPN_HOSTNAME="$REPLY"; VPN_COUNTRY=""
else
ask "Serverland" "Germany"
VPN_COUNTRY="$REPLY"; VPN_HOSTNAME=""
fi
CURRENT_PORT=$(grep -oP '"0\.0\.0\.0:\K\d+(?=:\d+")' "$FT_DIR/docker-compose.yml" 2>/dev/null | head -1 || echo "8080")
ask "FreqUI Port" "$CURRENT_PORT"
FT_PORT="$REPLY"
echo -e "\n${BOLD}${BLUE}══════════ Zusammenfassung ══════════${NC}"
echo -e " Freqtrade: ${CYAN}$FT_DIR${NC}"
echo -e " NordVPN User: ${CYAN}$NORD_USER${NC}"
if [[ -n "$VPN_HOSTNAME" ]]; then
echo -e " VPN Server: ${CYAN}$VPN_HOSTNAME${NC}"
else
echo -e " VPN Land: ${CYAN}$VPN_COUNTRY${NC}"
fi
echo -e " FreqUI Port: ${CYAN}$FT_PORT${NC}"
echo -e "${BOLD}${BLUE}=====================================\n${NC}"
confirm "Einrichten?" || { info "Abgebrochen."; exit 0; }
}
backup_and_stop() {
step "Backup & Stack stoppen"
local BAK="$FT_DIR/docker-compose.yml.bak-$(date +%Y%m%d_%H%M%S)"
cp "$FT_DIR/docker-compose.yml" "$BAK"
success "Backup: $BAK"
cd "$FT_DIR"
if docker compose ps --quiet 2>/dev/null | grep -q .; then
docker compose down; success "Stack gestoppt"
else
info "Kein laufender Stack"
fi
}
write_env() {
step ".env schreiben"
[[ -f "$FT_DIR/.env" ]] && cp "$FT_DIR/.env" "$FT_DIR/.env.bak-$(date +%Y%m%d_%H%M%S)"
cat > "$FT_DIR/.env" << ENVEOF
# NordVPN Service-Credentials
# Quelle: https://my.nordaccount.com → NordVPN → Set up NordVPN manually
OPENVPN_USER=${NORD_USER}
OPENVPN_PASSWORD=${NORD_PASS}
ENVEOF
chmod 600 "$FT_DIR/.env"
success ".env gespeichert (chmod 600)"
}
write_compose() {
step "docker-compose.yml erstellen"
local VPN_SERVER_LINE=""
if [[ -n "$VPN_HOSTNAME" ]]; then
VPN_SERVER_LINE=" - SERVER_HOSTNAMES=${VPN_HOSTNAME}"
else
VPN_SERVER_LINE=" - SERVER_COUNTRIES=${VPN_COUNTRY}"
fi
cat > "$FT_DIR/docker-compose.yml" << COMPOSEEOF
# Freqtrade + NordVPN/Gluetun | $(date '+%Y-%m-%d %H:%M:%S')
# Netzwerk: [Freqtrade] → [Gluetun] → NordVPN → Internet
# WebUI: http://LXC-IP:${FT_PORT} (Port liegt bei Gluetun!)
services:
# VPN-Gateway exponiert alle Ports
gluetun:
image: qmcgaw/gluetun:latest
container_name: gluetun
restart: unless-stopped
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
environment:
- VPN_SERVICE_PROVIDER=nordvpn
- VPN_TYPE=openvpn
- OPENVPN_USER=\${OPENVPN_USER}
- OPENVPN_PASSWORD=\${OPENVPN_PASSWORD}
${VPN_SERVER_LINE}
ports:
- "0.0.0.0:${FT_PORT}:8080"
volumes:
- gluetun_data:/gluetun
healthcheck:
test: ["CMD-SHELL", "wget -qO- https://ipinfo.io/ip || exit 1"]
interval: 30s
timeout: 15s
retries: 5
start_period: 45s
# Freqtrade KEIN ports: hier, läuft über Gluetun-Netzwerk
freqtrade:
image: freqtradeorg/freqtrade:stable
restart: unless-stopped
container_name: freqtrade
network_mode: "container:gluetun"
depends_on:
gluetun:
condition: service_healthy
volumes:
- "./user_data:/freqtrade/user_data"
command: >
trade
--logfile /freqtrade/user_data/logs/freqtrade.log
--db-url sqlite:////freqtrade/user_data/tradesv3.sqlite
--config /freqtrade/user_data/config.json
--strategy SampleStrategy
volumes:
gluetun_data:
COMPOSEEOF
success "docker-compose.yml geschrieben"
}
start_and_verify() {
step "Stack starten & VPN prüfen"
cd "$FT_DIR"
docker compose up -d
echo
info "Warte auf VPN-Verbindung (bis zu 90s)..."
local tries=0 vpn_ok=false
while [[ $tries -lt 18 ]]; do
sleep 5; echo -n "."
docker exec gluetun wget -qO- https://ipinfo.io/ip &>/dev/null && { vpn_ok=true; break; }
tries=$((tries+1))
done
echo
if [[ "$vpn_ok" == "true" ]]; then
VPN_IP=$(docker exec gluetun wget -qO- https://ipinfo.io/ip 2>/dev/null)
success "VPN verbunden! Ausgehende IP: ${BOLD}${VPN_IP}${NC}"
else
warn "VPN-Verbindung Timeout. Prüfe: docker logs gluetun"
VPN_IP="unbekannt prüfe: docker exec gluetun wget -qO- https://ipinfo.io/ip"
fi
sleep 5
docker ps | grep -q "freqtrade" && success "Freqtrade läuft" || warn "Freqtrade prüfen: docker logs freqtrade"
}
show_result() {
local LXC_IP; LXC_IP=$(hostname -I | awk '{print $1}')
echo
echo -e "${BOLD}${GREEN}╔═══════════════════════════════════════╗${NC}"
echo -e "${BOLD}${GREEN}║ ✅ NordVPN Addon eingerichtet! ║${NC}"
echo -e "${BOLD}${GREEN}╚═══════════════════════════════════════╝${NC}"
echo
echo -e " ${BOLD}FreqUI:${NC} ${CYAN}http://${LXC_IP}:${FT_PORT}${NC}"
echo -e " ${BOLD}NordVPN IP:${NC} ${CYAN}${VPN_IP}${NC}"
echo
echo -e " ${BOLD}${YELLOW}⚠ Binance API-Key anpassen:${NC}"
echo -e " ${YELLOW}In Binance → API Management → IP-Beschränkung${NC}"
echo -e " ${YELLOW}Die NordVPN-IP eintragen (nicht mehr die Home-IP)!${NC}"
echo
echo -e " ${BOLD}Befehle:${NC}"
echo -e " ${CYAN}docker exec gluetun wget -qO- https://ipinfo.io/ip${NC} # VPN-IP prüfen"
echo -e " ${CYAN}docker logs gluetun${NC} # VPN-Logs"
echo -e " ${CYAN}cd $FT_DIR && docker compose restart${NC} # Neustart"
echo
}
main() {
print_banner
check_requirements
collect_config
backup_and_stop
write_env
write_compose
start_and_verify
show_result
}
main "$@"