浪人
DE | EN
Claude Code als Homelab-Assistent  -  Teil 1: Setup & erster Audit
tech

Claude Code als Homelab-Assistent - Teil 1: Setup & erster Audit

Zurück zum Blog
5 Min. Lesezeit

Claude Code als Homelab-Assistent - Teil 1: Setup & erster Audit

Einleitung

Wer ein Homelab betreibt kennt das Muster: Man hat eine Idee, öffnet einen Chat mit Claude, erklärt den Kontext, bekommt einen Vorschlag, kopiert ihn in den Terminal, führt ihn aus, berichtet das Ergebnis zurück, bekommt eine Korrektur - und so weiter. Es funktioniert, aber es ist umständlich. Claude kennt deinen Server nicht, du musst jedes Mal neu erklären was läuft, und zwischen Planung und Ausführung stehst immer du als manueller Zwischenschritt.

Claude Code macht das anders. Es läuft lokal auf deinem Rechner, verbindet sich per SSH direkt mit dem Server, liest Configs, führt Befehle aus und wartet auf deine Bestätigung bevor es etwas ändert. Kein Kopieren, kein Erklären, kein manuelles Hin-und-Her.

Bei mir kommt noch eine Besonderheit dazu: ich arbeite traditionell auf mehreren Systemen gleichzeitig - Stand-PC, Laptop und Tablet. Gerade experimentiere ich zusätzlich mit dem Umstieg auf Linux, arbeite also parallel auf Windows und Linux. Das Setup muss daher auf allen Systemen funktionieren, ohne dass ich es jedes Mal neu aufbauen muss.

In dieser Serie zeige ich wie ich Claude Code als Assistenten für mein Homelab eingerichtet habe - mit wiederverwendbaren Prompts, automatischen Tests und einem Setup das auf jedem Rechner in wenigen Minuten funktioniert.

Teil 1: Konzept, Repo-Aufbau, SSH-Zugang einrichten, erster Security Audit. Teil 2: Ein gefundenes Issue aus dem Audit beheben. Teil 3: Einen neuen Docker Service deployen - von Null bis HTTPS.


Hauptteil

Das Konzept

Die Grundidee ist einfach: Ein privates GitHub Repo das als “Gehirn” für Claude Code dient. Es enthält den Kontext über den Server, wiederverwendbare Prompts als Slash Commands, und Setup Scripts die auf jedem Rechner funktionieren - Windows, Linux, macOS.

homelab-claude/
├── CLAUDE.md                      <- Kontext, den Claude Code automatisch liest
├── setup.sh                       <- Einmaliges Setup Linux / macOS
├── setup.ps1                      <- Einmaliges Setup Windows
├── .env.example                   <- Benötigte Secrets (Vorlage)
├── .claude/
│   └── commands/
│       ├── health-check.md        <- /health-check
│       ├── security-audit.md      <- /security-audit
│       └── deploy-service.md      <- /deploy-service
└── prompts/                       <- Lesbare Referenz

screen1-Repo

Das Herzstück ist CLAUDE.md - eine Datei die Claude Code bei jedem Start automatisch einliest. Darin steht alles was der Assistent über den Server wissen muss: IPs, Services, URLs, kritische Container die nie ohne Bestätigung angefasst werden dürfen, Konventionen für neue Stacks, und Verhaltensregeln.

## Kritische Services -- IMMER ZULETZT ANFASSEN

| Service       | Container      | Warum kritisch                               |
|---------------|----------------|----------------------------------------------|
| Traefik       | traefik        | Reverse Proxy -- alle HTTPS-Routen           |
| AdGuardHome   | adguardhome    | DNS -- fällt das aus, ist das Netz offline   |
| Tailscale     | tailscale      | VPN -- einziger externer Zugang              |

screen2-claudeMD

Wichtig: Die CLAUDE.md im Repo ist meine persönliche Konfiguration - spezifisch für mein Setup mit meinen Services, IPs und Konventionen. Wer das nachbaut muss diese Datei für sein eigenes Homelab anpassen. Das Repo ist ein Startpunkt, kein fertiges Produkt das man einfach klont und loslegt.

Ich überlege dazu noch einen “Discovery”-Prompt einzubauen: Claude Code verbindet sich mit einem unbekannten Server, liest docker ps, Netzwerke, Volumes und vorhandene Configs - und generiert daraus automatisch eine initiale CLAUDE.md. Das wäre der saubere Einstieg für jeden der bei Null startet. Falls ich das umsetze kommt es als eigener Teil in die Serie.

Kein Erklären mehr bei jedem Chat. Der Kontext ist einmal sauber dokumentiert und immer verfügbar - auf jedem Rechner, nach jedem git pull.

SSH-Key einrichten

Claude Code verbindet sich über ssh-mcp mit dem Server - ein MCP-Server der SSH-Befehle ausführt. Dabei gibt es eine wichtige Einschränkung: der SSH-Key darf keine Passphrase haben. ssh-mcp kann verschlüsselte Keys nicht verwenden.

Für ein internes Homelab das nur per LAN oder Tailscale erreichbar ist, ist das vertretbar. Ich empfehle einen dedizierten Key nur für Claude Code - so lässt er sich bei Bedarf einfach widerrufen ohne den Haupt-Key anzufassen.

Windows (PowerShell):

# Key erstellen -- Passphrase leer lassen
ssh-keygen -t ed25519 -C "homelab-claude" -f "$env:USERPROFILE\.ssh\id_ed25519_homelab"

# Auf den Server übertragen
type "$env:USERPROFILE\.ssh\id_ed25519_homelab.pub" | ssh ronin@192.168.178.22 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

# Testen
ssh -i "$env:USERPROFILE\.ssh\id_ed25519_homelab" ronin@192.168.178.22

Linux / macOS:

# Key erstellen -- Passphrase leer lassen
ssh-keygen -t ed25519 -C "homelab-claude" -f ~/.ssh/id_ed25519_homelab

# Auf den Server übertragen
ssh-copy-id -i ~/.ssh/id_ed25519_homelab.pub ronin@192.168.178.22

# Testen
ssh -i ~/.ssh/id_ed25519_homelab ronin@192.168.178.22

Wenn die Verbindung ohne Passwort funktioniert, ist alles bereit. In .env eintragen:

SSH_KEY_PATH=~/.ssh/id_ed25519_homelab

Stolperstein: Beim ersten Versuch habe ich meinen bestehenden SSH-Key verwendet - der hatte eine Passphrase. Claude Code lief los, jeder SSH-Befehl schlug fehl mit Cannot parse privateKey: Encrypted private OpenSSH key detected. Lösung: neuen Key ohne Passphrase erstellen, MCPs neu registrieren. Das kostet 5 Minuten, aber man sollte es gleich richtig machen.

screen3-claude

Setup auf einem neuen Rechner

Genau hier zahlt sich das Repo-Prinzip aus. Egal ob Windows, Linux oder macOS - das Setup ist immer gleich:

# Repo clonen
git clone git@github.com:RoninRage/homelab-claude.git
cd homelab-claude

# Secrets konfigurieren
cp .env.example .env
# SSH_HOST, SSH_USER, SSH_KEY_PATH eintragen

Dann je nach System:

# Linux / macOS
./setup.sh

# Windows
powershell -ExecutionPolicy Bypass -File setup.ps1

Das Script installiert Claude Code, registriert drei MCP-Server (SSH LAN, SSH Tailscale, Playwright) und zeigt am Ende welche Server aktiv sind. Da ich gerade zwischen Windows und Linux wechsle, war mir wichtig dass beide Scripts identisch funktionieren - gleiche Ausgaben, gleiche Fehlermeldungen, gleiche Reihenfolge. Kein Unterschied ausser dem Dateinamen.

Dann einmal claude starten - der Browser öffnet sich für den Anthropic-Login, einmalig pro Rechner. Danach läuft alles.

screen4-slashcommands

Slash Commands

Statt Prompts aus Dateien zu kopieren und einzufügen, sind alle Prompts als Slash Commands direkt in Claude Code verfügbar. Die Dateien liegen in .claude/commands/ - Claude Code erkennt diesen Ordner automatisch.

/health-check      <- Container-Status, Speicher, Backup-Log
/security-audit    <- Ausführlicher Sicherheits-Audit
/deploy-service    <- Neuen Docker Service deployen

Die gleichen Dateien liegen zusätzlich in prompts/ als lesbare Referenz - zum Nachlesen was ein Command eigentlich tut, ohne Claude Code öffnen zu müssen.

screen5-Passphrase

Der erste Security Audit

/security-audit

Claude Code verbindet sich per SSH und prüft parallel fünf Bereiche:

  1. Traefik-Konfiguration - welche Services laufen ohne Auth-Middleware?
  2. Offene Ports - was hört auf allen Interfaces, nicht nur über Traefik?
  3. Container-Sicherheit - läuft etwas privileged oder als root?
  4. Image-Hygiene - welche Images haben :latest statt einem fixen Tag? Welche sind veraltet?
  5. Backup-Coverage - welche Services haben Volumes die nicht gesichert werden?

screen6-sudo

Das Ergebnis erscheint strukturiert im Terminal mit einer priorisierten To-Do-Liste. Nichts wird gespeichert oder committed - man entscheidet selbst was damit passiert.

Wichtig: Claude Code bekommt bei Audits nur Leserechte. Es werden keine Dateien geschrieben, keine Befehle ausgeführt die etwas verändern. Rohdaten wie IPs oder interne Ports landen nicht in Dateien oder Repos - nur die aufbereitete Zusammenfassung.

Stolperstein Nr. 2: Der Audit-Prompt verwendet ss -tlnp um offene Ports zu prüfen. Beim ersten Durchlauf kam ein Fehler: sudo: a password is required - ssh-mcp kann kein sudo-Passwort übergeben. Die Lösung ist einfach: ss -tlnp funktioniert auch ohne sudo, man sieht dann nur keine Prozessnamen. Für einen Port-Audit reicht das vollständig aus. Der Prompt wurde entsprechend angepasst.

screen7-auditrunning

screen8-auditreport


Fazit

Was vorher ein manuelles Hin-und-Her war ist jetzt ein einziger Befehl. Claude Code liest den Kontext, verbindet sich mit dem Server, führt die Checks aus und liefert einen strukturierten Report - ohne dass man den Setup jedes Mal neu erklären muss.

Das Repo-Prinzip hat dabei einen angenehmen Nebeneffekt: der Kontext ist versioniert, auf jedem Rechner verfügbar, und wächst mit dem Homelab mit. Wenn ein neuer Service hinzukommt, wird CLAUDE.md aktualisiert - und alle Rechner wissen beim nächsten git pull Bescheid. Für jemanden der auf mehreren Systemen arbeitet und gerade zwischen Betriebssystemen wechselt ist das kein nice-to-have, sondern der eigentliche Grund warum das Setup so gebaut ist.

In Teil 2 schaue ich mir einen der Findings aus dem Audit genauer an und behebe ihn - direkt mit Claude Code, Schritt für Schritt mit Bestätigung.

Ein Gedanke zum Abschluss: Was hier manuell per Slash Command ausgeführt wird, lässt sich prinzipiell auch automatisieren. /health-check und /security-audit könnten als regelmäßige Cronjobs laufen - jeden Morgen ein automatischer Status-Report, jede Woche ein Audit. Die Prompts sind dabei nur der Ausgangspunkt: was geprüft wird, wie der Report aussieht, und was bei einem kritischen Finding passiert - das alles lässt sich den eigenen Anforderungen anpassen. Wer möchte kann daraus ein vollständiges Monitoring-System bauen, wer lieber manuell die Kontrolle behält bleibt beim Slash Command. Beides funktioniert mit derselben Basis.

Das Repo: github.com/RoninRage/homelab-claude-public

Hinweis zum Repo: Das ist ein anonymisiertes Beispiel meines persönlichen Setups - IPs, Benutzername, Domain und interne Pfade sind durch Platzhalter ersetzt. Die CLAUDE.md spiegelt mein Homelab wider und ist kein fertiges Template das man einfach übernehmen kann. Wer das nachbaut muss sich seine eigene CLAUDE.md erstellen - entweder manuell, oder mit KI-Hilfe: einfach docker ps, docker network ls und die vorhandenen Compose-Files als Kontext mitgeben und Claude eine initiale CLAUDE.md generieren lassen. Das ist in wenigen Minuten erledigt und ergibt sofort eine sinnvolle Basis.