Files
clownfischserver/CLAUDE.md
T
mehlzoerwerandClaude Haiku 4.5 5c1f56a60e Docs: CLAUDE.md für zukünftige Claude-Instanzen
Context für nachfolgende Entwicklung:
- Architektur & Multi-Distro/Firewall-Patterns
- Dateistruktur & Responsibilities
- Critical Design Decisions (iptables Persistierung, .env Parsing)
- Development Workflow (Ubuntu/Fedora/Arch Testing)
- Git Policies (4 pushes/hour)
- Code Patterns & Gotchas
- Quick Reference Commands

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-02 00:00:50 +02:00

319 lines
11 KiB
Markdown
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.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
---
## Project Overview
**Clownfischserver** is a self-hosted, AI-driven Linux server manager controlled exclusively via Telegram. The core principle: admins write naturally, the bot understands, generates commands, creates scripts, manages the server.
- **Version:** v0.5.0 (in development)
- **License:** GPL-3.0
- **Status:** Active Development (feature/homeip-auto-update branch)
- **Core Dev:** Mehlzoerwer-Claude (Thomas Matthes)
---
## Architecture & Key Patterns
### Core Data Flow
```
Telegram User → bot.py → {ollama_client, shell.py, aider_wrapper} → Server Actions
↓
Chat-Model (gemma3) + Coder-Model (qwen2.5-coder)
Fallback: OpenRouter Free (if Ollama unavailable)
```
### Central Patterns
**Multi-Distro Abstraction:** The codebase abstracts firewall & package managers:
- **install.sh Step 2:** Detects `apt`/`dnf`/`pacman` → installs appropriate packages
- **install.sh Step 4:** Installs firewall (`ufw` for apt, `firewalld` for dnf, manual for pacman)
- **homeip-updater.sh:** Detects active firewall at runtime (`detect_firewall()` at line 18-26) → adapts rule syntax
This is critical: **Any Firewall change must support all three backends** (ufw, firewalld, iptables).
**Dual-Model KI Strategy:**
- **Coder-Model (qwen2.5-coder:7b):** `/shell`, `/code`, command generation → requires good programming ability
- **Chat-Model (gemma3:4b):** Freetext, explanations, translations → requires good German + multilingual
- **Fallback:** OpenRouter free tier if Ollama times out (optional, configured in `.env`)
**Telegram Safety Patterns:**
- `safe_reply()` wraps all bot responses (Markdown fallback for special chars)
- Long responses auto-split (Telegram 4096 char limit)
- Command confirmation: `/shell` generates → `/ja` confirms → executes (no auto-exec)
---
## File Structure & Responsibilities
### `bot/` – Core Bot Logic
- **bot.py** (700+ lines): Main handler, all commands, auth guard, self-update dialog
- **ollama_client.py**: Dual-model manager, OpenRouter fallback, context-window config
- **openrouter_client.py**: Cloud fallback (openrouter/free auto-router)
- **shell.py**: Command execution (shlex.quote for safety), result capture
- **aider_wrapper.py**: Code agent wrapper (--edit-format diff, 600s timeout)
- **snapshot.py**: tar.gz backups, workspace tracking, package list snapshots
- **boot_notify.py**: Sends Telegram message 120s after server boot (systemd oneshot)
- **knock_notify.py**: Alerts on port-knock SSH access attempts
### `scripts/` – Utility Scripts (NEW in v0.5.0)
- **clownfischserver-homeip-updater.sh**: Auto-update firewall rule for home IP (5-min cron)
- Detects firewall type (ufw/firewalld/iptables)
- Resolves myfritz DNS (dig/nslookup/getent fallbacks)
- State-file tracking to skip redundant updates
- **Critical:** Must work on Ubuntu/Debian/Fedora/Arch/openSUSE
- **README-HOMEIP.md**: Complete homeip-updater documentation (setup, troubleshooting, firewall details)
### `install.sh` – Multi-Step Installation (900+ lines)
8-step installer with full automation:
1. **System checks** → RAM, disk, distro detection
2. **Packages** → distro-specific (apt/dnf/pacman)
3. **User setup** → custom username, passwordless sudo
4. **SSH + Firewall** → sshd_config tuning, ufw/firewalld setup, **NEW: myfritz prompt**
5. **Ollama** → download, models selection (RAM-aware defaults)
6. **Python venv** → bot + aider (separate venvs due to dependency conflicts)
7. **Telegram bot** → BotFather token, chat-ID, optional OpenRouter key
8. **Systemd** → clownfisch service + boot-notification service, **NEW: cron-job for homeip-updater**
**Key Pattern:** `install.sh` runs **as root** and manages root-level resources. The homeip-updater cron-job runs as root (for firewall access).
### Configuration & Data
- **config/.env** → All secrets, model choices, paths (generated by install.sh, permissions 0600)
- **config/.env.example** → Template (must be kept in sync with install.sh additions)
- **config/knockd.conf** → Port-knocking rules (7000→8000→9000)
- **systemd/clownfisch.service** → Bot service (User patched dynamically from MGMT_USER)
- **systemd/clownfisch-boot.service** → Boot notification (oneshot, 120s delay)
---
## Critical Design Decisions
### 1. Firewall Abstraction (New in v0.5.0)
The homeip-updater.sh demonstrates the new **multi-firewall abstraction pattern**:
```bash
detect_firewall() {
systemctl is-active ufw → use: ufw allow from X port 22
systemctl is-active firewalld → use: firewall-cmd rich-rule
command -v iptables → use: iptables -I INPUT
}
```
**Why this matters:** When adding firewall-dependent features, always implement for all three. This is not optional.
### 2. No Interactive Commands in /shell
The `/shell` command uses a "non-interactive only" prompt. Why?
- **Cron-friendly:** homeip-updater runs in cron, can't wait for user input
- **Safety:** No `nano`, `vim`, `crontab -e` (can't pipe credentials)
- **Pattern:** UFW delete needs `echo "y" |` confirmation (line 81 in homeip-updater.sh)
### 3. .env Parsing Robustness
Variable loading must handle CRLF (Windows git clones):
```bash
MYFRITZ_DOMAIN=$(grep "^VAR=" .env | cut -d= -f2 | tr -d '\r\n')
```
This trims trailing newlines/carriage returns. Critical for .env variables used in firewall rules.
### 4. State File Tracking in homeip-updater
The `/var/lib/clownfischserver-homeip-state` file prevents redundant UFW updates:
- If DNS resolves to same IP → skip rule updates (idempotent)
- If IP changed → remove old rule, add new rule
- Logging includes old IP vs new IP for audit trail
This is important because UFW rule deletion prompts interactively (hence the `echo "y" |` workaround).
### 5. Package Dependency Management
- **dnsutils** must be in apt install (Step 2) for `dig` command
- **firewalld** installed for dnf systems (handled in Step 4)
- **iptables** assumed on pacman (Arch) systems
- The homeip-updater has DNS fallbacks: dig → nslookup → getent (lines 43-52)
---
## Development Workflow
### Testing on Multiple Distros
The project must work on:
- **Ubuntu/Debian** (primary, uses ufw)
- **Fedora/RHEL** (uses firewalld)
- **Arch/Manjaro** (uses iptables/nftables)
- **openSUSE** (uses firewalld)
**Recommended setup (from project notes):**
- Pop!_OS on laptop → development & editing
- Homlab VMs (Arch, openSUSE) → local testing of install.sh + homeip-updater
- VPS Server (Ubuntu) → real-world myfritz testing
### Bash Script Syntax Check
```bash
bash -n install.sh
bash -n scripts/clownfischserver-homeip-updater.sh
```
Run before commits. CRLF warnings are harmless (Windows git clones), but scripts must be syntactically valid.
### Python Syntax Check
```bash
python3 -m py_compile bot/*.py
```
### Testing Firewall Rules
**ufw (Ubuntu/Debian):**
```bash
ufw status numbered
ufw allow from 192.168.1.100 to any port 22 comment "test"
echo "y" | ufw delete allow from 192.168.1.100 to any port 22
```
**firewalld (Fedora/openSUSE):**
```bash
firewall-cmd --list-all
firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' port protocol='tcp' port='22' accept"
firewall-cmd --reload
```
**iptables (Arch):**
```bash
iptables -L INPUT -n
iptables -I INPUT -s 192.168.1.100 -p tcp --dport 22 -j ACCEPT
iptables -D INPUT -s 192.168.1.100 -p tcp --dport 22 -j ACCEPT
```
---
## Git Workflow & Policies
### Push Policy
**Maximum 4 pushes per hour** (one every ~15 minutes). This is documented in `memory/feedback_github_policy.md`.
**Why:** Reduces GitHub notification spam, allows batching commits logically, leaves review time between updates.
### Branch Strategy
- **main:** Stable releases only (v0.4.13, v0.5.0, etc.)
- **feature/*** → PR reviewed → merged to main after testing
- Current: `feature/homeip-auto-update` (v0.5.0 preparation)
### Commit Message Style
```
<Type>: <Title> – <Subtitle if complex>
Details paragraph (optional, multi-line OK)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
```
Examples:
- `v0.5.0 – Clownfischserver HomeIP Auto-Update: myfritz Automatik für SSH (5-Min Cron)`
- `Bugfix: Clownfischserver HomeIP Updater – Fehlerbehandlung & Fallbacks`
- `Feature: Multi-Distro Firewall-Support für HomeIP Updater`
---
## Important Gotchas & Caveats
### 1. iptables Persistence on Arch
The homeip-updater uses `iptables -I INPUT` to add rules. On some systems, these don't persist after reboot. **Future enhancement:** integrate with `iptables-persistent` or `nftables` for persistence. Current status: evaluating.
### 2. Firewall Rule Comments
UFW and firewalld support rule comments (`comment "..."`) for tracking. **iptables does not.** This makes tracking which rules were added by clownfischserver harder on Arch. Document this if implementing rule deletion on iptables.
### 3. systemd Service User Patching
The MGMT_USER (arbitrary username) must be patched into systemd service files during installation. This uses regex: `User=\S+` (line 822 in install.sh). If systemd syntax changes, update regex.
### 4. Ollama Model Download Brittleness
`ollama pull` can hang or timeout. The installer includes progress bars but no retry logic. Users on slow/intermittent connections may need manual intervention.
### 5. .env Variable Escaping
Variables like `CLOWNFISCHSERVER_HOME_IP_DOMAIN=vorname.myfritz.net` are read with `grep` and `cut`. They must not contain `=` characters. Document constraints in `.env.example`.
---
## Code Patterns to Follow
### Safe Telegram Replies
Always use `safe_reply()` wrapper (bot.py). Never call `send_message()` directly.
### Async Telegram Handlers
All message handlers must be `async def`. Use `@app.message_handler()` decorator pattern from existing code.
### Shell Command Safety
Use `shlex.quote()` for untrusted user input in shell.py. Example:
```python
cmd = f"rm {shlex.quote(user_path)}"
```
### Firewall Rule Matching
When detecting or modifying firewall rules, match exact patterns to avoid false positives:
- UFW: `"22.*ALLOW.*FROM\s+$IP"` (line 79, homeip-updater.sh)
- firewalld: exact rule with family + port + protocol
- iptables: exact `-s $IP -p tcp --dport 22` match
---
## Memory & Context Files
For other Claude instances working on this project:
- **project_status_v05.md** – Current v0.5.0 status, tested scenarios, known limitations
- **feedback_github_policy.md** – Push frequency policy, batching rules
These are in `.claude/projects/.../memory/`. They provide context for continued development.
---
## Key References
- **CLOWNFISCHSERVER.md** – Detailed project context (architecture, .env variables, roadmap)
- **README.md** – User-facing documentation
- **scripts/README-HOMEIP.md** – Complete homeip-updater guide
- **CONTRIBUTING.md** – Contribution guidelines (already aligned with multi-distro goals)
---
## Quick Commands
```bash
# Syntax check
bash -n install.sh
python3 -m py_compile bot/*.py
# Test homeip-updater (dry-run, logs to stdout)
bash -x scripts/clownfischserver-homeip-updater.sh
# Check git status
git status
git log --oneline -5
# Build release ZIP (from install.sh docs)
cd .. && zip -r v0.5.0-clownfischserver.zip clownfischserver/ -x "*__pycache__*" "*.pyc" ".git/*"
```
---
**Last Updated:** 2026-05-01 (v0.5.0 HomeIP Feature)
**Next Version:** v0.5.0 (pending VPS/VM testing, then merge to main)