SEC-1c-0 Exposure-Audit — Public-Surface Inventory

Projekt: Steve-TradingBot · Phase: SEC-1c-0 · Author: claude-opus-4-7[1m]
Generated: 2026-05-13 15:19 UTC · master HEAD: 2fbc7b5 (SEC-1b-6 closed)
Host: h2991365.stratoserver.net (Strato Cloud) · OS: Ubuntu 20.04.6 LTS
Status: READ-ONLY AUDIT NO CODE, NO CHANGES. Fix-Plan im Anschluss — wartet auf Operator-GO.

Executive Summary

Das System hat kein lokales Firewall-Layer (kein iptables, kein nftables, kein ufw installiert). Alle 0.0.0.0-Bindings sind damit aus dem Internet erreichbar, sofern Strato kein vorgeschaltetes Cloud-Firewall stellt (Operator-Prüfpflicht im Strato-Dashboard).

4 Critical / High Findings, sofortige Fix-Priorität:

  1. CRITICALnetdata v1.19.0 unauthenticated dashboard auf 0.0.0.0:9080 (HTTP 200 extern); leakt Hostname, alle Prozesse, Container, Memory/CPU/Disk. Version aus 2020 mit bekannten CVEs.
  2. CRITICAL — Bot-Trading-Dashboard auf 0.0.0.0:8050 ohne Authentifizierung (HTTP 200 extern); leakt Bot-Status, Positions, Logs.
  3. HIGHcupsd Snap-Service auf 0.0.0.0:631; aktuell rejectet das externe Auth-Layer mit 403, aber binding ist falsch und CUPS hat aktive CVE-Klasse (CVE-2024-47175 et al.). Server hat keinen lokalen Drucker-Use-Case.
  4. HIGHkein lokales Firewall-Layer. Defense-in-Depth fehlt komplett auf Host-Ebene.

Steve-TradingBot-spezifische Surfaces sind sauber gebunden (GUI 8090 localhost, GUI-DB intern, Portainer 9443 localhost ab SEC-1b-0, Cockpit gelöscht ab SEC-1b-0). Die kritischen Findings sind host-level / sibling-projects, nicht Bot/GUI selbst.


1 — Methode

Keine Modifikation: kein nft/iptables-Touch, kein systemctl stop/start, kein docker stop/rm, kein compose-Edit. Read-only.


2 — Vollständige Port-Matrix (Host-Listener)

PortBindServicePIDExternAuthKlassifikation
22/tcp0.0.0.0 + [::]sshd (OpenSSH)737reachablekey-only (PermitRootLogin prohibit-password), fail2ban 320 bannedOK
80/tcp0.0.0.0nginx860/4010xxxreachablen/a (force-redirect zur HTTPS-Variante + /shares/ public)OK
443/tcp0.0.0.0nginx (dashboard-ssl)860/4010xxxreachableself-signed cert, proxy zu Bot-Dashboard :8050 (zZt 502)SEC-1c-1 zu fixen (HTTPS + LE)
631/tcp0.0.0.0 + [::]cupsd (snap.cups.cupsd)1079extern HTTP 403CUPS-eigenes Allow-LayerHIGH — auf localhost-only setzen oder snap deaktivieren
587/tcp127.0.0.1sendmail-mta888not reachable externlocal-onlyOK
25/tcp127.0.0.1sendmail-mta888not reachable externlocal-onlyOK
53/udp+tcp127.0.0.53systemd-resolved411not reachablelocal-only stubOK
3456/tcp127.0.0.1claude-max-api (node)3430407not reachable (000)local-only API-proxyOK
8000/tcp127.0.0.1docker-proxy → portainer2781230not reachablelocalhost-onlyOK (SEC-1b-0)
8080/tcp0.0.0.0docker-proxy → kw-website-caddy2047077reachablenicht Steve-TradingBot-Projektout-of-scope (separates caddy-stack-Projekt)
8088/tcp0.0.0.0nginx /shares (HTTP)nginxreachableautoindex public, /shares/backups/ 403 dank dir-mode 700OK — aber autoindex der Top-Level /shares/ ist beabsichtigt für PDFs/Reports
8443/tcp0.0.0.0nginx (wp-test-ssl)nginx502 zurücktotorphan nginx-config — aufräumen
8050/tcp0.0.0.0docker-proxy → clawbot dashboard.py566966 (proxy) / clawbot PID 8HTTP 200 externkeine AuthentifizierungCRITICAL — sofort localhost-binden + nginx-Basic-Auth ODER löschen
8090/tcp127.0.0.1docker-proxy → GUI :8000 (Filament)3651547not reachable externFilament-Login + MFA (SEC-1b-6)OK — aktuell nur lokal, SEC-1c-1 wird via nginx publik
8125/tcp+udp127.0.0.1 + [::1]netdata (StatsD)1445792not reachablelocal-onlyOK
8888/tcp0.0.0.0docker-proxy → kw-website-caddy2047062reachablenicht Steve-TradingBotout-of-scope (caddy-stack)
9443/tcp127.0.0.1docker-proxy → portainer2781214not reachable externPortainer-LoginOK (SEC-1b-0)
9080/tcp0.0.0.0netdata v1.19.01445792HTTP 200 externanonymer Zugriff, vollständige System-Telemetry leaktCRITICAL — bind auf localhost ODER Auth-Layer ODER Löschung
18789/tcp127.0.0.1 + [::1]openclaw (host)1531226not reachablelocal-onlyOK
18791/tcp127.0.0.1docker-proxy → clawbot internal openclaw566950not reachablelocal-onlyOK
27017/tcp127.0.0.1mongod (system)692not reachablelocal-onlyOK
27018/tcp127.0.0.1docker-proxy → militaria-mongo1596not reachablelocal-onlyOK
38381/tcp127.0.0.1openclaw (host)1531226not reachablelocal-onlyOK

UDP-Listener

PortBindServiceKlassifikation
53/udp127.0.0.53systemd-resolvedOK
8125/udp127.0.0.1 + [::1]netdata StatsDOK
44036/45240/45286/48535/50336/50957/57691/59038/udp*eshop-poller-bot.jar (Java PID 418)ephemeral outgoing — sibling project, not a listener concern

3 — Steve-TradingBot-Container-Mappings (compose)

ContainerMappingBewertung
steve-tradingbot-gui127.0.0.1:8090 -> container:8000OK — localhost-only, SEC-1c-1 wird via nginx exposen
steve-tradingbot-gui-dbkein Host-Mapping (intern gui-db:5432)OK — nur container-network
clawbot-workerkein MappingOK
clawbot0.0.0.0:8050 -> container:8050 (dashboard) + 127.0.0.1:18791 -> container:18789CRITICAL — 8050 ist public ohne Auth; 18791 OK

4 — Kritische Findings im Detail

F1 — CRITICAL netdata v1.19.0 auf 0.0.0.0:9080

Symptomcurl http://81.169.213.37:9080 → HTTP 200 mit vollständigem netdata-Dashboard
Versionv1.19.0 (Release 2020-04) — aktueller Stable ist 1.4x
LeaktHostname (h2991365.stratoserver.net), Kernel-Version, alle laufenden Prozesse (inkl. python3 main.py --paper), alle Container, Memory/CPU/Disk-Metriken, Netzwerk-Traffic-Patterns
CVE-Klassev1.19 hat dokumentierte Issues (XSS, Info-Disclosure); aktuelle Versionen haben Auth-Layer + Bind-default 127.0.0.1
Reachability externverifiziert: HTTP 200, kein 403, kein Login-Prompt
Fix-Optionen(a) /etc/netdata/netdata.conf bind to = 127.0.0.1 + restart — schnellst
(b) hinter nginx mit Basic-Auth + Update auf 1.4x
(c) deinstallieren (Operator nutzt netdata aktuell wofür?)
Empfehlung(a) sofort, dann (b) oder (c) als SEC-1c-0-Sub-Phase

F2 — CRITICAL Bot-Dashboard auf 0.0.0.0:8050

Symptomcurl http://81.169.213.37:8050/ → HTTP 200 (Trading Bot Dashboard); /api/ → HTTP 200
Quellecompose-Mapping "0.0.0.0:8050:8050" in docker-compose.yml; Bot-Container PID 8 = dashboard.py
LeaktBot-Status (running/idle), Strategy-Stats, evtl. Position-Snapshots, evtl. PnL, evtl. Trade-History
Authkeine
Fix-Optionen(a) compose-Mapping ändern auf "127.0.0.1:8050:8050" + Container neu starten — Bot-Restart-Pflicht; nicht Plan-Review-konform ohne Operator-GO
(b) nginx-Reverse-Proxy mit Basic-Auth davor (kein Bot-Touch)
(c) Dashboard ausschalten wenn nicht aktiv genutzt — Operator-Decision
Empfehlung(b) als kurzfristige Mitigation ohne Bot-Restart: nginx auf 81.169.213.37:8050 → localhost mit Basic-Auth; danach in eigenem Bot-Maintenance-Window (b) durch (a) ersetzen.
Alternativ Operator entscheidet (c).

F3 — HIGH cupsd auf 0.0.0.0:631

Symptomextern HTTP 403 (CUPS-eigenes Auth-Layer blockt), aber binding ist auf 0.0.0.0 — Defense-in-Depth fehlt
QuelleSnap-Package snap.cups.cupsd + snap.cups.cups-browsed
RisikoCUPS hat aktive CVE-Klasse 2024-47175ff (RCE durch IPP-Pakete). 403 schliesst HTTP-Browser-Zugriff aus, schliesst aber nicht IPP-Protokoll auf 631 aus.
Use-Case auf ServerServer ohne lokalen Drucker — CUPS hat keinen ersichtlichen Nutzen
Fix-Optionen(a) snap stop cups + snap remove cups — sauberste Variante
(b) Listen 127.0.0.1:631 in CUPS-config
Empfehlung(a) deinstallieren — kein Use-Case auf Server

F4 — HIGH kein lokales Firewall-Layer

Befundweder iptables noch nftables noch ufw installiert/aktiv
Konsequenzjeder 0.0.0.0-Bind ist direkt aus dem Internet erreichbar (vorbehaltlich Strato-Cloud-Firewall)
Cloud-ProviderStrato (h2991365.stratoserver.net) — Strato bietet je nach Produkt eine separate Firewall, die im Strato-Dashboard konfiguriert wird. Operator-Prüfpflicht.
Fix-Optionen(a) ufw installieren + Default-Deny-Inbound + explicit Allow für 22/80/443 (8088 optional)
(b) nftables mit eigenem Regelsatz
(c) Strato-Cloud-Firewall im Strato-Dashboard pflegen
Empfehlung(a) ufw als Quick-Win + (c) Strato-Cloud-Firewall als zweite Layer (defense-in-depth)

5 — Medium / Sibling-Project Findings

ItemBefundBewertung
caddy-stack :8080 + :8888kw-website-caddy bindet 0.0.0.0; separates Projekt /srv/caddy-stack/out-of-scope SEC-1c — Operator-Notiz an caddy-stack-Pflege; nicht im Steve-TradingBot-Risiko
wp-test-ssl :8443nginx-config aktiv, proxy_pass dead (502)orphan — nginx-config-Eintrag wp-test-ssl aufräumen wenn nicht mehr benötigt
eshop-poller-bot.jar PID 418Java-UDP ephemeral ports; outgoing-onlyOK — sibling-project, kein Listener
fail2bannur sshd-jail aktiv; 2302 failed attempts / 320 bannederweiterbar — nginx-jail für Bot-Dashboard-/Filament-Login-Brute-Force (BACKLOG SEC-1c-1)
/srv/shares/backups/HTTP 403 extern — dir-mode 0700 blockt nginx-readOK — Defense-in-Depth-Layer 2 wirkt (Layer 1 wäre nginx internal-Block)

6 — Bestätigt sichere Items (kein Fix nötig)


7 — Fix-Plan (Operator-Decision — NO CHANGES YET)

SEC-1c-0 (sofort, vor SEC-1c-1)

StepActionRisikoAufwand
0.1netdata bind auf 127.0.0.1: /etc/netdata/netdata.conf bind socket to IP = 127.0.0.1 + systemctl reload netdataLOW (lokales Monitoring bleibt funktional; externe URL bricht)10 min
0.2cupsd deinstallieren: snap stop cups && snap remove cups (Operator-Bestätigung)LOW (kein lokaler Drucker)5 min
0.3Bot-Dashboard hinter nginx-Auth: neuer nginx-Server-Block listen 8051 ssl; location / { auth_basic; proxy_pass http://127.0.0.1:8050; } + htpasswd-Datei OHNE compose-Edit / Bot-Restart (Mitigation-Layer 1).
Langfristig: 8050-binding auf localhost im nächsten Bot-Maintenance-Window (Layer 2)
LOW (kein Bot-Touch)30 min
0.4ufw installieren + default-deny: apt install ufw && ufw default deny incoming && ufw allow 22 && ufw allow 80 && ufw allow 443 && ufw allow 8088 && ufw enable (8050-extern-Block durch ufw deny; nginx-8051 wenn neu)MEDIUM (Lockout-Gefahr falls SSH-Regel falsch — mit ufw allow 22 ZUERST)20 min
0.5wp-test-ssl-nginx-config aufräumen: rm /etc/nginx/sites-enabled/wp-test-ssl && nginx -t && systemctl reload nginxLOW5 min
0.6fail2ban-nginx-jail aktivieren: /etc/fail2ban/jail.local nginx-http-auth + nginx-limit-reqLOW20 min
0.7Strato-Cloud-Firewall prüfen: im Strato-Dashboard nachsehen ob Firewall konfiguriert ist und welche Regeln geltenOPERATOR-AUFGABE (read-only)10 min

Gesamt SEC-1c-0: 90 min + Strato-Check.

Korrekturen am SEC-1c-Plan (aus Operator-Pin)

Neue empfohlene Reihenfolge

  1. SEC-1c-0: Port-/Exposure-Fix (90 min, dieser Audit-Output)
  2. SEC-1c-1: HTTPS + Cookies + Phase-1-Headers + nginx-RL
  3. SEC-1c-2: Admin-Rotation
  4. SEC-1c-3: DB-Least-Privilege (2-User)
  5. SEC-1c-4: Audit-Alerts
  6. SEC-1c-5: CSP Report-Only → enforce
  7. SEC-1c-6: SSH-Finetuning + ufw-Refinement
  8. SEC-1d: Passkey/WebAuthn (gated auf SEC-1c-1)
  9. SEC-1e: APP_KEY-/Secret-Rotation (separat, eigenes Hochrisiko-Projekt)

8 — Boundaries (Audit-End-State)

master HEAD2fbc7b5 unverändert
git statusunverändert (Audit ist read-only)
Bot in-container PID290 (python3 main.py --paper) unverändert
Worker in-container PID1 (python3 -m trading.command_worker) unverändert
BINANCE_TESTNETtrue
managed_proposals rows0
docker cp / restart / stop / rm0
systemctl stop/start/disable0
nginx/cups/netdata config-touch0
Modifications0 — pure read-only audit

Status: SEC-1c-0 AUDIT FERTIG Fix-Plan oben. STOP per Operator-Pin.
Warte auf:

ODER: explizites GO SEC-1c-0 alle 7 Steps als ein atomarer Block.