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>
This commit is contained in:
@@ -0,0 +1,318 @@
|
|||||||
|
# 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)
|
||||||
Reference in New Issue
Block a user