#!/bin/bash # Erster Anmeldetest am IBKR-Paper-Konto: IB Gateway als Container in WSL, nur lesend. # Koordinator-Werkzeug, nicht fuers Repo. Pascal am 2026-09-24: Container in WSL, beide Downloads frei # (ghcr.io/gnzsnz/ib-gateway, festgelegt auf die Pruefsumme unten; nautilus-ibapi im eigenen Venv # ~/venvs/ibkr-probe), Test nach 22:00, zweiter Faktor bei ihm nur ein Passkey. # Das Abbild ist dasselbe, das NautilusTrader 1.231.0 mit DockerizedIBGatewayConfig startet # (config.py: container_image "ghcr.io/gnzsnz/ib-gateway:stable"; gateway.py: Paper aussen 4004). # Die Zugangsdaten liest der Container aus /home/claude/.config/trading-plattform/ibkr/ (Pascal traegt sie # mit ibkr_zugang_eintragen.sh ein); dieses Skript gibt sie nie aus und maskiert den Benutzernamen im Log. # Aufruf aus der PowerShell (sudo per WSLENV, wie bei den anderen Betriebsskripten): # $env:WSL_PW=[Environment]::GetEnvironmentVariable('DEBIAN_WSL_PASSWORD','User'); $env:WSLENV='WSL_PW' # wsl -d Debian -u claude -- bash /mnt/d/Claude/.vault-tools/trading-plattform-pruefung/ibkr_gateway_test.sh # Schritte: laden | pruefen | starten | log | probe | stoppen set -u BILD="ghcr.io/gnzsnz/ib-gateway@sha256:5fb04cb93cd705eff8a5a58b015503003864ffd9ea890be4d07273389149aa9f" ZUGANG=/home/claude/.config/trading-plattform/ibkr NAME=ibkr-gateway-probe PROBE_PY=/home/claude/venvs/ibkr-probe/bin/python PROBE=/mnt/d/Claude/.vault-tools/trading-plattform-pruefung/ibkr_probe.py [ -n "${WSL_PW:-}" ] || { echo "WSL_PW fehlt (sudo per WSLENV)"; exit 20; } S() { printf '%s\n' "$WSL_PW" | sudo -S -p '' "$@"; } stunde=$(TZ=Europe/Berlin date +%-H) # RUHE_AUSNAHME: nur auf Pascals ausdrueckliche Anweisung fuer einen einzelnen Lauf (so am 2026-09-24, # 17:0x: "Bitte schon einmal testen ohne andere Workflows zu gefaehrden"); der Wert nennt Datum und Anlass. if [ "$stunde" -ge 15 ] && [ "$stunde" -lt 22 ] && [ -z "${RUHE_AUSNAHME:-}" ]; then echo "Ruhe-Regel: zwischen 15 und 22 Uhr Berlin laeuft hier nichts (jetzt $(TZ=Europe/Berlin date +%H:%M))." exit 21 fi maske() { # Den Benutzernamen und lange Ziffernfolgen aus fremder Ausgabe nehmen, ohne ihn selbst zu zeigen. python3 -c ' import re, sys from pathlib import Path benutzer = "" p = Path(sys.argv[1]) if p.is_file(): benutzer = p.read_text(encoding="utf-8").strip() for zeile in sys.stdin: if benutzer: zeile = zeile.replace(benutzer, "[benutzer]") # Kontonummern: ein bis vier Grossbuchstaben und mindestens fuenf Ziffern. Die erste Fassung kannte # nur DU plus Ziffern; das Paper-Konto hat einen Buchstaben mehr und stand am 2026-09-24 unmaskiert im Log. zeile = re.sub(r"\b[A-Z]{1,4}\d{5,}\b", "[konto]", zeile) sys.stdout.write(zeile) ' "$ZUGANG/paper_benutzer" } case "${1:-}" in laden) S docker pull "$BILD" 2>&1 | tail -n 3 S docker image inspect "$BILD" --format 'Id {{.Id}} Groesse {{.Size}} Erstellt {{.Created}}' ;; pruefen) # Welche Variablen liest das Abbild aus Dateien, und unter welcher UID laeuft es? S docker run --rm --entrypoint sh "$BILD" -c ' echo "== id"; id echo "== _FILE-Variablen in den Startskripten"; grep -rhoE "[A-Z_]+_FILE" /home /usr/local/bin /opt 2>/dev/null | sort -u | head -20 echo "== Ports"; grep -rhoE "4003|4004|4001|4002|5900" /home /usr/local/bin 2>/dev/null | sort | uniq -c | head ' 2>&1 | head -40 ;; starten) for datei in paper_benutzer paper_passwort; do [ -s "$ZUGANG/$datei" ] || { echo "fehlt: $ZUGANG/$datei (erst ibkr_zugang_eintragen.sh)"; exit 22; } done S docker rm -f "$NAME" >/dev/null 2>&1 # Benutzername und Passwort aus Dateien im Container; TWS_USERID_FILE nur, wenn "pruefen" es fand, # sonst setzt BENUTZER_ALS_VARIABLE=1 den Namen als Variable (er ist kein Geheimnis wie das Passwort). if [ "${BENUTZER_ALS_VARIABLE:-0}" = "1" ]; then BENUTZER_ARG=(-e "TWS_USERID=$(cat "$ZUGANG/paper_benutzer")") else BENUTZER_ARG=(-e "TWS_USERID_FILE=/run/secrets/ibkr/paper_benutzer") fi S docker run -d --name "$NAME" \ -e TRADING_MODE=paper -e READ_ONLY_API=yes -e TWOFA_TIMEOUT_ACTION=exit \ -e TWS_PASSWORD_FILE=/run/secrets/ibkr/paper_passwort "${BENUTZER_ARG[@]}" \ -e TIME_ZONE=America/New_York \ -v "$ZUGANG:/run/secrets/ibkr:ro" \ -p 127.0.0.1:4004:4004 \ "$BILD" >/dev/null && echo "gestartet: $NAME (Paper, nur lesend, Port 127.0.0.1:4004)" ;; log) S docker logs --tail "${2:-60}" "$NAME" 2>&1 | maske ;; probe) cd /tmp && "$PROBE_PY" "$PROBE" --port 4004 ;; stoppen) S docker rm -f "$NAME" 2>&1 | tail -n 1 ;; *) echo "Schritt fehlt: laden | pruefen | starten | log | probe | stoppen" exit 2 ;; esac