18 KiB
🐠 Clownfischserver – Projekt-Kontext
Diese Datei ist der zentrale Wissensspeicher für das Clownfischserver-Projekt. Lade sie in jede KI/Chat-Session um sofort produktiv zu sein. Letzte Aktualisierung: v0.5.0 (30.05.2026)
⚠️ Bewusst entfernt (nicht wieder einbauen!): Ein „Vault/MCP-Context"-System (
_get_vault_context,MCP_VAULT_URL,MCP_API_KEY) wurde in v0.5.0 komplett entfernt. Es war toter Code, nutzteverify=Falseund schickte Chat-Nachrichten an externe Endpoints – ein klarer DSGVO-Verstoß und Widerspruch zum „local-first"-Prinzip. Token-Optimierung über Obsidian gehört NICHT in den Bot.
Was ist der Clownfischserver?
Ein Open-Source, Telegram-gesteuerter Linux-Server-Manager. Der Admin schreibt dem Bot über Telegram – der Bot versteht, generiert Befehle, erstellt Scripts, verwaltet den Server. Komplett lokal mit Ollama, optional Cloud-Fallback über OpenRouter.
Repo: https://github.com/mehlzoerwer-claude/clownfischserver Lizenz: GPL-3.0 Entwickler: Mehlzoerwer-Claude (Thorsten Matthes) KI-Assistent: Claude (Anthropic) – Pair-Programming Partner
Architektur
┌─────────────────────┐
│ Telegram Bot │
│ (bot.py) │
└──────┬──────┬────────┘
│ │
┌─────────────────┤ ├─────────────────┐
▼ ▼ ▼ ▼
┌────────────────┐ ┌────────────┐ ┌──────────────────┐
│ ollama_client │ │ shell.py │ │ aider_wrapper │
│ (Dual-Model) │ │ (run_shell)│ │ (Code-Agent) │
└───────┬────┬────┘ └────────────┘ └──────────────────┘
│ │
┌────────┘ └────────┐
▼ ▼
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ Chat-Model│ │ Coder-Model │ │ OpenRouter │
│ (gemma3) │ │(qwen2.5-coder)│ │ (Fallback) │
└──────────┘ └──────────────┘ └──────────────┘
Prinzip: Freitext = Chat. /shell = KI generiert Befehl → Admin bestätigt mit /ja. /code = Aider erstellt Dateien. /run = direkte Shell.
Dateistruktur (19 Dateien, ~3250 Zeilen)
clownfischserver/
├── bot/
│ ├── bot.py # Hauptbot: alle Commands, Auth, Self-Update, Update-Dialog
│ ├── ollama_client.py # Dual-Model, OpenRouter Fallback, NUM_CTX, Shell-Prompt
│ ├── openrouter_client.py # OpenRouter Free Models Client (openrouter/free)
│ ├── shell.py # run_shell (shlex.quote), execute_command
│ ├── aider_wrapper.py # Aider mit --edit-format diff, 600s Timeout
│ ├── snapshot.py # tar.gz Snapshots, Workspace, Paketliste, sudo rsync
│ ├── boot_notify.py # Telegram-Nachricht 120s nach Boot
│ ├── knock_notify.py # Port-Knocking SSH-Benachrichtigungen
│ └── requirements.txt # python-telegram-bot, requests, python-dotenv
├── config/
│ ├── .env.example # Vorlage mit allen Variablen
│ └── knockd.conf # Port-Knocking Sequenz (7000→8000→9000)
├── systemd/
│ ├── clownfisch.service # Bot-Service (User=clownfish, wird gepatcht)
│ └── clownfisch-boot.service # Boot-Notification (oneshot, 120s delay)
├── install.sh # 8-Schritt Installer mit Modell/CTX-Auswahl
├── README.md # Vollständige Dokumentation
├── LICENSE # GPL-3.0
├── .gitignore
├── CONTRIBUTING.md
└── GITHUB_PROFILE.md
Wichtige Konventionen
Naming
- Service:
clownfisch.service(Deutsch, mit "ch") - Linux-User: Beliebig (z.B.
clownfisch,clownfish,admin) – wird ausMGMT_USERin.envgelesen - Branding: Immer "Clownfisch" (Deutsch)
- ZIP-Benennung:
v0.5.0-clownfischserver.zip
Code-Stil
- Python 3, keine Type Hints in Funktionssignaturen (außer Optional)
- Logging über
loggingModul - Async für alle Telegram-Handler
safe_reply()für alle Telegram-Nachrichten (Markdown-Fallback)- Fehler werden dem User angezeigt, nie verschluckt
Sicherheits-Regeln
- Configs (
sshd_config,knockd.conf) NIE überschreiben – nur gezielte Zeilen ändern .envPermissions: 0600- SSH Host-Keys,
/etc/shadowNIE in Snapshots .envseit v0.4.12 aus Snapshots excludiert- Self-Update: systemd-Services werden mit
MGMT_USERaus.envgepatcht (Regex:User=\S+)
.env Variablen
TELEGRAM_BOT_TOKEN=... # Bot-Token von @BotFather
TELEGRAM_CHAT_ID=... # Autorisierte Chat-ID (Single-User)
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=qwen2.5-coder:7b # Coder-Modell für /shell und /code
OLLAMA_MODEL_FAST=gemma3:4b # Chat-Modell für Freitext
OLLAMA_NUM_CTX=16384 # Context-Window (4096-32768)
OPENROUTER_API_KEY=sk-or-v1-... # Optional: kostenloser Cloud-Fallback
SNAPSHOT_DIR=/opt/clownfisch-snapshots
SNAPSHOT_METHOD=tar
INSTALL_DIR=/opt/clownfischserver
MGMT_USER=clownfisch # Linux-User (beliebig wählbar)
AIDER_WORKDIR=/opt/clownfisch-workspace
Bot-Befehle
| Befehl | Funktion |
|---|---|
| Freitext | Chat mit KI (gemma3 lokal, OpenRouter Fallback) |
/shell <beschreibung> |
KI generiert Shell-Befehl, non-interaktiv |
/ja |
Letzten /shell Befehl ausführen (mit Snapshot davor) |
/code <aufgabe> |
Aider erstellt Dateien (Smart Prompt: Dateiname wird ergänzt) |
/run <befehl> |
Direkte Shell, kein KI, kein Bestätigen |
/status |
CPU, RAM, Disk, Top-Prozesse |
/ssh open [ip] |
SSH via ufw öffnen |
/ssh close [ip] |
SSH via ufw schließen |
/snapshot [label] |
Manuell Snapshot erstellen |
/snapshot keep/delete <n> |
Snapshot markieren/löschen |
/snapshots |
Alle Snapshots anzeigen |
/rollback <name> |
Zu Snapshot zurückkehren (sudo rsync --delete) |
/start / /help |
Bot-Info und Befehlsübersicht |
| ZIP senden | Self-Update mit optionalem OpenRouter-Setup-Dialog |
Dual-Model Strategie
| Rolle | Modell | RAM | Aufgabe |
|---|---|---|---|
| Coder | qwen2.5-coder:7b | ~4.7GB | /shell, /code, Befehlsgenerierung |
| Chat | gemma3:4b | ~3.3GB | Freitext, Erklärungen, Übersetzungen |
| Fallback | openrouter/free | 0 (Cloud) | Wenn Ollama nicht verfügbar |
Shell-Prompt: Few-Shot mit non-interaktiven Regeln (kein nano/vim/crontab -e, sudo wenn nötig). Chat-Prompt: Deutsch als Standard, antwortet in Sprache des Nutzers. Explain-Prompt: Erklärt Befehlsergebnisse auf Deutsch.
Snapshot-System
Gesichert: /etc, /opt/clownfischserver, /home, /opt/clownfisch-workspace
Excludiert: SSH Host-Keys, shadow, .env, __pycache__, node_modules
Paketliste: dpkg --get-selections pro Snapshot als .packages.txt
Rollback: sudo rsync -av --delete pro Verzeichnis
Auto-Cleanup: Max 20 Snapshots, keep-markierte bleiben immer
OpenRouter Integration
- Client:
openrouter_client.pymitopenrouter/freeAuto-Router - Fallback-Trigger: Ollama Timeout ODER "nicht erreichbar"
- Betrifft: Chat +
/shell(nicht/code– Aider braucht Ollama direkt) - Setup: Beim Self-Update fragt Bot "OpenRouter aktivieren?" → Key eingeben →
.env - Kosten: Free Tier: 50 Requests/Tag, 20/Minute, keine Kreditkarte
Bekannte Bugs / Einschränkungen
/codehat keinen OpenRouter-Fallback (Aider spricht nur Ollama)- Kleine Modelle (< 8B) halluzinieren bei Erklärungen
- Aider
diff-Format überfordert kleine Modelle manchmal → Datei wird nicht erstellt - Shell-Prompt vergisst manchmal
sudobei Root-Operationen
Server-Umgebung
- Hoster: netcup VPS
- OS: Ubuntu 24.04 LTS
- RAM: 16GB
- Disk: 300GB
- IP: 92.60.38.175
- Ollama: qwen2.5-coder:7b + gemma3:4b (oder gemma4:e2b)
- Docker: installiert
- SSH: Port-Knocking via knockd (7000→8000→9000)
Roadmap
v0.5.0 – Sicherheit + Features
Security (DSGVO-Pflicht):
- Sensitive Dateien über Telegram blockieren (
.env, shadow, Keys) - Output-Sanitizer: API Keys/Tokens in JEDER Bot-Antwort maskieren
- Log-Sanitizer: Keine Secrets im Audit-Log
- Audit-Log: Jeder Befehl mit Timestamp (DSGVO Art. 5/32)
- SHA256-Hash bei Self-Update + Admin-Bestätigung
.envPermissions-Check beim Bot-Startbot.log,.aider.chat.history.md,bash_historyaus Snapshots excluden- Rate-Limiting: Max 30 Befehle/Minute
- Session-Timeout: Nach 30 Min Inaktivität → 2FA erneut
- 2FA bei kritischen Aktionen (TOTP/Mail/zweiter Bot)
- Persönlicher Code-Offset (SECURITY_OFFSET in .env)
Features:
- Snapshot-Scheduling + Export via Telegram
- Verschlüsselte Snapshots (SNAPSHOT_PASSWORD)
/logs,/docker- Port-Knocking Sequenz wählbar
- Open Interpreter als Aider-Alternative evaluieren
Quick-Win Security:
- Panik-Wort: Admin-definiertes Wort → Bot löscht .env, sperrt alles
- Honeypot-Befehle: Fake-Commands die Eindringlinge verraten
- Selbstzerstörende Nachrichten: Bot löscht eigene Outputs nach X Minuten
- Rollback-Bombe: 3x falscher 2FA → auto-Rollback + SSH sperren + Alert
- Dead Man's Switch: Kein Lebenszeichen in 24h → Bot sperrt sich selbst
v0.6.0 – Multi-Server + Gedächtnis
- Ein Bot steuert mehrere Server
- Audit-Log / Server-Gedächtnis (server_log.txt)
- Chat kann vergangene Aktionen abfragen
v0.7.0 – DSGVO-bewusster Backup-Manager
- Verschlüsselte Snapshots (SNAPSHOT_PASSWORD in .env)
v0.8.0 – Erweiterte Cloud-API
- Premium-Modelle auf OpenRouter
- Anthropic/OpenAI direkt
- Kosten-Tracking
v0.9.0 – Multi-Interface + Advanced Security
Alternative Interfaces (E2E-verschlüsselt):
- Matrix/Element Connector (matrix-nio, self-hosted, E2E)
- Signal Connector (signal-cli, E2E)
- Web-UI (HTTPS, self-hosted, Let's Encrypt)
- SSH-CLI (interaktive Shell-Session, kein Messenger nötig)
- E-Mail mit GPG-Verschlüsselung
Advanced Security Features (evaluieren bei v0.8.x Abschluss):
- Fake-Modus: Falscher 2FA-Code → Bot tut so als ob, führt nichts aus, stiller Alarm
- Distress-Code: Umgekehrter Offset = "Ich werde gezwungen" → Fake-Modus
- Geo-Fencing: Bot antwortet nur aus erlaubten Ländern/IP-Bereichen
- Buddy-System: Kritische Befehle brauchen Bestätigung von zweitem Admin
- Canary Token: Unsichtbare Marker-Dateien, Alert bei Zugriff
- Verschlüsselter Rückkanal: Bot-Antworten verschlüsselt über Telegram
- Hardware-Token: USB-Stick als physischer Schlüssel
Architektur-Ziel:
[Telegram] ─┐
[Matrix] ─┤
[Web-UI] ─┼─→ [bot_core.py] → [Ollama/OpenRouter]
[SSH-CLI] ─┤
[E-Mail] ─┘
Ein Bot, viele Eingänge. Admin wählt was er will.
v1.0.0 – Disaster Recovery
v2.0.0 – Cross-Distribution Server Migration
Getestete Modelle
| Modell | Größe | Rolle | Ergebnis |
|---|---|---|---|
| qwen2.5-coder:7b | 4.7GB | Coder | ✅ Beste Wahl für Code |
| qwen2.5-coder:3b | 1.9GB | Coder | ✅ Funktioniert, schwächer |
| gemma3:4b | 3.3GB | Chat | ✅ Gutes Deutsch, schnell |
| gemma4:e2b | 7.2GB | Beide | ⚠️ Zu groß für Dual-Setup |
| rnj-1:8b | 5.1GB | Coder | ❓ Test ausstehend |
| qwen3.5:4b | – | Coder | ❌ Thinking, zu langsam auf CPU |
| openrouter/free | Cloud | Fallback | ✅ Nemotron-H, stark |
Wichtige Design-Entscheidungen
- Local-first: Cloud ist Opt-in Werkzeug, nicht Abhängigkeit
- Kein Classifier: Freitext = Chat. Befehle explizit per
/shell,/run,/code - Bestätigungs-Flow:
/shellgeneriert → Admin prüft →/jaführt aus - Beliebiger Username: MGMT_USER wird überall per Regex eingesetzt
- Smart
/codePrompt: Bot ergänzt Dateiname wenn User keinen nennt - Snapshot vor destruktiven Aktionen: Automatisch bei apt install, rm, chmod etc.
- DSGVO by design: Lokal, keine Daten an Cloud, Snapshots ohne Secrets
Security-Analyse (v0.4.13)
Was wir haben ✅
- Chat-ID Auth (Single-User)
.envmit 0600 Permissions- SSH Host-Keys + shadow excluded aus Snapshots
.envexcluded aus Snapshots (seit v0.4.12)- Port-Knocking statt offenes SSH
- Lokal-first, Cloud opt-in
- Safe-Reply Markdown-Fallback (kein Crash bei Sonderzeichen)
Bekannte Schwachstellen ❌
Telegram als Angriffsfläche:
- Bot-Token im Klartext in
.env– wer den Server hackt hat den Bot - Telegram Chat-History enthält alle Befehle + Outputs – nicht löschbar vom Bot
- Telegram API ist NICHT E2E-verschlüsselt – Telegram Inc. kann mitlesen
- Jemand der das Handy entsperrt hat vollen Zugriff
.envInhalte können per/run cat .envüber Telegram geleakt werden
Bot-Sicherheit:
- Kein Rate-Limiting – Brute-Force auf Befehle möglich
- Kein Session-Timeout – Bot antwortet 24/7 ohne erneute Auth
bot.logenthält möglicherweise sensible Daten (unverschlüsselt).aider.chat.history.mdloggt alle Code-Prompts im Klartext- Ollama API auf localhost:11434 hat keine Auth – jeder lokale Prozess kann anfragen
Snapshots:
- Snapshots enthalten
/home– SSH Keys, bash_history, private Dateien - Snapshot-Verzeichnis nicht verschlüsselt
- Kein Integrity-Check ob Snapshots manipuliert wurden
Netzwerk:
- knockd Sequenz steht im Klartext in
knockd.conf - ufw Regeln können über
/runbeliebig geändert werden
Server:
- NOPASSWD sudo – kompromittierter Bot = Root
install.shlädt Pakete aus dem Internet ohne Signatur-Check- Docker Socket zugänglich → Container-Escape möglich
Security-Maßnahmen geplant
v0.5.0 (realistisch umsetzbar):
.env/Secrets über Telegram blockieren (Blacklist für sensitive Pfade)- Output-Sanitizer: API Keys/Tokens in JEDER Bot-Antwort maskieren
- Log-Sanitizer: Keine Secrets im Audit-Log
bot.log+.aider.chat.history.md+bash_historyaus Snapshots excluden- Rate-Limiting: Max 30 Befehle/Minute
- Session-Timeout: Nach 30 Min Inaktivität → 2FA erneut nötig
- 2FA bei kritischen Aktionen (TOTP/Mail/zweiter Bot)
- Persönlicher Code-Offset (SECURITY_OFFSET in .env)
- SHA256-Hash bei Self-Update → Admin bestätigt
.envPermissions-Check beim Bot-Start (warnen wenn nicht 0600)- Audit-Log mit Timestamp für jeden Befehl (DSGVO Art. 5/32)
v0.6.0+ (langfristig): 12. Bot-Token Rotation 13. Verschlüsselte Snapshots (SNAPSHOT_PASSWORD) 14. Integrity-Hashes für Snapshots (Manipulation erkennen) 15. Ollama API Auth 16. Audit-Log mit Tamper-Protection (Signierung)
DSGVO-Regel für Telegram
.env wird NUR angelegt/geändert über SSH. Niemals über Telegram lesbar.
Der Bot BLOCKIERT Befehle die sensitive Dateien über Telegram ausgeben würden.
ZIP bauen – exakte Vorgehensweise
Voraussetzungen
- Alle 20 Dateien müssen im Ordner
clownfischserver/liegen - Python-Dateien müssen syntax-geprüft sein
- install.sh muss bash-syntax-geprüft sein
Schritt 1: Syntax-Check (IMMER vor dem ZIP)
cd clownfischserver
python3 -m py_compile bot/bot.py
python3 -m py_compile bot/ollama_client.py
python3 -m py_compile bot/openrouter_client.py
python3 -m py_compile bot/shell.py
python3 -m py_compile bot/snapshot.py
python3 -m py_compile bot/aider_wrapper.py
python3 -m py_compile bot/boot_notify.py
python3 -m py_compile bot/knock_notify.py
bash -n install.sh
Schritt 2: ZIP erstellen
cd .. # Eine Ebene über clownfischserver/
zip -r v0.5.0-clownfischserver.zip clownfischserver/ -x "*__pycache__*" "*.pyc"
WICHTIG:
- ZIP-Name:
v<version>-clownfischserver-opus.zip - Root-Ordner im ZIP muss
clownfischserver/heißen (nichtbuild/oder anderer Name) - Keine
__pycache__oder.pycDateien - Keine
.git/Ordner - Keine
.envmit echten Credentials
Schritt 3: Verifizieren
unzip -l v0.5.0-clownfischserver.zip | head -30
# Muss zeigen: clownfischserver/bot/bot.py etc. (20 Dateien)
Schritt 4: Einspielen
Per Telegram: ZIP an den ClownfischServer Bot senden → Self-Update Dialog
Per Server: bash install.sh im entpackten Ordner
Schritt 5: GitHub Push
cd clownfischserver
rm -rf .git
git init
git remote add origin https://github.com/mehlzoerwer-claude/clownfischserver.git
git add -A
git commit -m "v0.4.13 – Beschreibung der Änderungen"
git branch -M main
git push -u origin main --force
Dateiliste (20 Dateien, vollständig)
clownfischserver/
├── .gitignore
├── CLOWNFISCHSERVER.md ← diese Datei
├── CONTRIBUTING.md
├── GITHUB_PROFILE.md
├── LICENSE
├── README.md
├── install.sh
├── bot/
│ ├── aider_wrapper.py
│ ├── boot_notify.py
│ ├── bot.py
│ ├── knock_notify.py
│ ├── ollama_client.py
│ ├── openrouter_client.py
│ ├── requirements.txt
│ ├── shell.py
│ └── snapshot.py
├── config/
│ ├── .env.example
│ └── knockd.conf
└── systemd/
├── clownfisch-boot.service
└── clownfisch.service
Versions-Bump Checkliste
Bei neuer Version diese Stellen aktualisieren:
install.sh– Banner + Log-Meldung (3xv0.4.13)bot/bot.py–cmd_startBegrüßung +main()Log-MeldungREADME.md– BadgeVersion-0.4.13+ Roadmap "Fertig (v0.1 – v0.4.13)"CLOWNFISCHSERVER.md– Header + Dateiliste- ZIP-Dateiname
"Angefangen als einfacher Telegram-Bot – gewachsen zu einer Vision." 🐠