Files
infrastructure/docs/platform/llm-server/host/GNAI-003-INFRA_Users.md
T

207 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.
# Ghostnet.AI-Host – Benutzer, Netzwerk und SSH
**Dokumenten-ID:** GNAI-003-INFRA
**Titel:** Benutzer-, Netzwerk- und SSH-Sicherheitsarchitektur des KI-Hosts `10.0.0.90`
**Status:** Betriebsanleitung; tatsächliche Netzverwaltung und Konten vor Anwendung prüfen
---
## Änderungsverlauf
| Datum | Version | Autor | Beschreibung der Änderung |
| --- | --- | --- | --- |
| 2026-08-26 | 1.0 | spektr | Erstellung des Dokuments (Benutzer, Netzwerkkonfiguration, SSH-Härtung) |
| 2026-09-15 | 1.1 | spektr | Kontenbestand, DNS-Verwaltung und SSH-Dienstnamen präzisiert; doppelte Basisschritte bereinigt. |
| 2026-09-16 | 1.2 | spektr | Tatsächliche Konten, Gruppen, Netz- und SSH-Konfiguration sowie Grenzen des Login-Tests dokumentiert. |
| 2026-09-18 | 1.3 | spektr | Workstation-spezifische Schlüsselpfade und Host-Fingerprint in den lokalen Arbeitskontext verlagert. |
| 2026-09-19 | 1.4 | spektr | Persönlichen Login `ghost` und Agentenlogin `ghost-agent` als erfolgreich getestet dokumentiert. |
| 2026-09-20 | 1.5 | spektr / Codex | Deployment- und getrennte rootless Workload-Konten mit festen IDs und Zuständigkeiten ergänzt. |
| 2026-09-20 | 1.6 | spektr / Codex | `render`-Mitgliedschaft und geprüfte AMD-Geräterechte der beiden KI-Konten ergänzt. |
| 2026-09-22 | 1.7 | Codex | In die hostbezogene Struktur `platform/ghostnet-ai/` verschoben und Geltungsbereich präzisiert. |
---
## 1. Zweck und Geltungsbereich
Dieses Dokument beschreibt Benutzer, statische IP und SSH des KI-Servers. Der ursprüngliche lesende Kontenabgleich vom 18.09.2026 umfasste `ghost`, `debugofen` und `ghost-agent`; `admin` existiert auf diesem Host nicht. Am 19. und 20.09.2026 kamen der Ansible-Deployment-Account sowie drei gesperrte Workload-Konten hinzu. Die folgenden Befehle sind für Neuinstallation oder gezielte Änderung gedacht und ersetzen keine Prüfung des vorhandenen Systems. Der WireGuard-LXC besitzt ein separates Konto `admin`.
---
## 2. Voraussetzungen & Berechtigungen
* Bereits installiertes Debian-Grundsystem gemäß [GNAI-002](GNAI-002-INFRA_BaseSystem.md).
* Root-Zugriff oder Benutzer mit `sudo`-Rechten.
* Admin-Workstation mit lokal installierter SSH-Suite (`ssh`, `ssh-keygen`); für den bestehenden Host ist die lokale Konsole oder ein bereits berechtigter Zugang zur Schlüsselaufnahme nötig.
---
## 3. Prozessbeschreibung
### 3.1 Benutzerverwaltung & Sudo-Berechtigungen (Server-Seite)
#### 1. Sudo-Paket installieren & prüfen (falls noch nicht geschehen)
Als `root` am Server anmelden:
```bash
su -
apt update && apt install -y sudo
```
#### 2. Benutzer anlegen & Berechtigungen vergeben
Vor dem Anlegen prüfen, ob das Konto bereits existiert (`getent passwd <username>`). Konten und Home-Verzeichnisse nur nach Prüfung ihrer Daten und Berechtigungen entfernen.
Nur bei einer **Neuinstallation** einen vorher festgelegten Administrationsbenutzer anlegen und zur `sudo`-Gruppe hinzufügen. Auf dem bestehenden KI-Server besitzen `ghost` und `debugofen` bereits sudo-Gruppenmitgliedschaft. Das folgende Beispiel mit `ghost` dort nicht ausführen:
```bash
# Nur auf einem neuen System ausführen.
sudo adduser ghost
sudo usermod -aG sudo ghost
```
Weitere Konten nur nach Rollenentscheidung anlegen. Die sudo-Gruppenmitgliedschaft ist pro Konto ausdrücklich festzulegen; auf dem bestehenden Host keine bereits vorhandenen Konten erneut anlegen.
Die folgenden technischen Konten werden ausschließlich durch das
Ansible-Projekt verwaltet:
| Konto | UID/GID | Zweck | interaktiver Login / sudo |
| --- | --- | --- | --- |
| `ansible-deploy` | 1003 | privilegierte Ansible-Ausführung | SSH-Key, gesperrtes Passwort, `NOPASSWD` gemäß eigener sudoers-Regel |
| `gnai-production` | 980 | rootless AI Production | gesperrtes Passwort, `/usr/sbin/nologin`, kein sudo |
| `gnai-testing` | 981 | rootless AI Testing | gesperrtes Passwort, `/usr/sbin/nologin`, kein sudo |
| `gn-encoding` | 982 | rootless CPU-Encoding | gesperrtes Passwort, `/usr/sbin/nologin`, kein sudo |
Die drei Workload-Konten besitzen nicht überlappende SubUID-/SubGID-Bereiche,
eigene Daten- und Podman-Stores sowie persistente systemd-User-Manager. Ihre
rootverwalteten Quadlet-Verzeichnisse liegen unter
`/etc/containers/systemd/users/<UID>`. Direkte SSH-Schlüssel werden dort nicht
hinterlegt. `gnai-production` und `gnai-testing` gehören zusätzlich zur
Gerätegruppe `render`; `gn-encoding` erhält keinen GPU-Zugriff.
---
### 3.2 Statische Netzwerkkonfiguration (Server-Seite)
#### 1. Netzschnittstelle ermitteln & anpassen
Primäre Netzwerkschnittstelle und zuständigen Netzwerkdienst ermitteln (z. B. `enp8s0`):
```bash
ip addr show
systemctl is-active networking NetworkManager systemd-networkd dhcpcd
```
Nur falls `ifupdown` den Host tatsächlich verwaltet, `/etc/network/interfaces` bearbeiten. Bei NetworkManager, systemd-networkd oder dhcpcd deren Konfiguration verwenden; die Schnittstelle darf nicht von mehreren Diensten zugleich verwaltet werden.
```bash
sudo nano /etc/network/interfaces
```
Netzwerkkonfiguration für statische IP eintragen:
```text
# Loopback Interface
auto lo
iface lo inet loopback
# Primary Network Interface
allow-hotplug enp8s0
iface enp8s0 inet static
address 10.0.0.90/24
gateway 10.0.0.1
dns-nameservers 10.0.0.1 1.1.1.1
```
#### 2. DNS-Resolver prüfen
`/etc/resolv.conf` kann von einem Netzwerk- oder Resolverdienst erzeugt werden. Den aktiven Dienst und die wirksamen Nameserver prüfen (`readlink -f /etc/resolv.conf`, `cat /etc/resolv.conf`); Änderungen in dessen Konfiguration vornehmen. Die aktuelle Solladresse des Heimnetz-DNS ist `10.0.0.1`.
#### 3. Netzwerkdienst neustarten & Funktion prüfen
```bash
sudo systemctl restart networking # nur bei ifupdown und mit Konsolenzugang
ip -4 addr
ping -c 4 google.com
```
Vor einem Remote-Neustart einen Rückweg über Konsole/Proxmox sicherstellen. Ein Reboot behebt keine widersprüchliche Netzkonfiguration.
---
### 3.3 SSH-Schlüssel und getrennte Konten
Für persönliche und automatisierte Zugriffe getrennte Konten und klar benannte Schlüsselpaare verwenden. Auf dem bestehenden KI-Server sind `ghost` und `ghost-agent` getrennt; `ghost-agent` hat keine sudo-Gruppenmitgliedschaft. Schlüsseldateien, lokale SSH-Aliase und der auf dieser Workstation bekannte Hostschlüssel-Fingerprint sind nur im lokalen, nicht versionierten Arbeitskontext vermerkt. Private Schlüssel und Passphrasen gehören weder in diese Dokumentation noch in ein Serverinventar. Ein Kommentar wie `@ghostnet-ki` im Public Key ist nur ein Label; die Zuordnung erfolgt über den Schlüsselinhalt und das jeweilige `authorized_keys`.
Neue öffentliche Schlüssel auf dem bestehenden Host über eine bereits berechtigte Sitzung oder die lokale Konsole in das **richtige Konto** unter `~/.ssh/authorized_keys` eintragen; bestehende Schlüssel dabei erhalten. Verzeichnis auf `700`, Datei auf `600` und Eigentümer auf das Zielkonto setzen. Passwort-SSH ist bereits deaktiviert, daher ist `ssh-copy-id` ohne bestehenden Schlüsselzugang hier kein Wiederherstellungsverfahren.
Vor Erstverbindung den Hostschlüssel-Fingerprint aus einer vertrauenswürdigen Konsole abgleichen. Die lokalen SSH-Aliase müssen auf `10.0.0.90`, das jeweils richtige Konto und Schlüsseldatei zeigen; `IdentitiesOnly yes` und strikte Hostschlüsselprüfung verwenden. Die folgenden Beispiele setzen entsprechend eingerichtete Aliase auf der Admin-Workstation voraus:
```bash
ssh ghostnet-ai-ghost 'id -un; hostnamectl --static'
ssh ghostnet-ai-agent 'id -un; hostnamectl --static'
```
Für `ghost` ist auf der aktuellen Workstation eine Passphrase-Eingabe am Terminal erforderlich, sofern der Schlüssel nicht bereits im SSH-Agenten entsperrt wurde. Beide Profile sind getestet: `ghost-agent` wurde am 19.09.2026 erneut technisch geprüft; der Betreiber bestätigte am selben Tag den erfolgreichen interaktiven Login als `ghost`.
---
### 3.4 SSH-Dienst härten (Server-Seite)
Nur auf einem **neu eingerichteten System** nach erfolgreichem SSH-Key-Test die Passwort-Authentifizierung deaktivieren. Auf dem bestehenden KI-Server ist das folgende Drop-in bereits vorhanden; es wurde am 18.09.2026 lesend geprüft.
#### 1. Drop-in-Konfiguration für SSH erstellen
```bash
sudo nano /etc/ssh/sshd_config.d/99-security.conf
```
Den folgenden Inhalt einfügen:
```text
# Root-Login über SSH komplett verbieten
PermitRootLogin no
# Passwort-Authentifizierung deaktivieren (nur SSH-Keys erlauben)
PasswordAuthentication no
KbdInteractiveAuthentication no
# Leere Passwörter verbieten
PermitEmptyPasswords no
# Nur explizite SSH-Key Methoden erlauben
PubkeyAuthentication yes
```
#### 2. SSH-Konfiguration prüfen und Dienst neustarten
> **Achtung:** Die bestehende SSH-Sitzung **nicht** schließen, bevor der Login in einem zweiten Terminalfenster erfolgreich verifiziert wurde!
```bash
# Syntaktische Prüfung der Konfiguration
sudo sshd -t
# Wenn sshd -t keine Fehler ausgibt, Dienst neustarten
sudo systemctl restart ssh
```
---
## 4. Abnahmekriterien (Checkliste für den Junior-Admin)
* [ ] **Benutzerprüfung:** `ghost` und `debugofen` können ihre vorgesehenen sudo-Rechte nutzen; `ghost-agent` bleibt ohne sudo-Zuweisung.
* [x] **Workload-Konten:** `gnai-production`, `gnai-testing` und `gn-encoding` besitzen getrennte rootless Podman-Stores und aktive persistente User-Manager; geprüft am 20.09.2026.
* [x] **GPU-Geräterechte:** Beide KI-Konten können `/dev/kfd`, `/dev/dri/renderD128` und `/dev/dri/renderD129` lesen und schreiben; das Encoding-Konto gehört nicht zu `render`; geprüft am 20.09.2026.
* [ ] **Netzwerk:** Server ist unter der statischen IP `10.0.0.90` erreichbar. Ausgehender Datenverkehr funktioniert (`ping google.com`).
* [x] **SSH-Aliase:** `ghostnet-ai-ghost` meldet `ghost`, `ghostnet-ai-agent` meldet `ghost-agent`. Beide Zugänge wurden am 19.09.2026 bestätigt. Die Passphrase des persönlichen Schlüssels ist keine Server-Passwortanmeldung.
* [ ] **Root-Sperre:** Direct-Login als Root per SSH wird abgelehnt (`ssh root@10.0.0.90` -> *Permission denied*).
* [ ] **Passwort-Sperre:** Login-Versuch ohne hinterlegten SSH-Key wird direkt abgelehnt (keine Passwort-Aufforderung mehr).
---
## 5. Lesender Ist-Abgleich am 18.09.2026
`ghost` (UID 1000) und `debugofen` (UID 1001) gehören zur Gruppe `sudo`; `ghost-agent` (UID 1002) gehört nicht dazu. Der technische Login als `ghost-agent` und der vom Betreiber interaktiv geprüfte Login als `ghost` funktionieren mit ihren jeweils eigenen Schlüsseln. Die Prüfung belegt die Kontentrennung und den Schlüsselzugang, aber keine noch offenen sudo-, Root-Sperr- oder Negativtests.
`enp8s0` hat `10.0.0.90/24`, die Default-Route führt über `10.0.0.1`. `networking` und `ssh` sind aktiv und aktiviert. `/etc/network/interfaces` enthält die statische Konfiguration; `/etc/resolv.conf` nennt `10.0.0.1` und `1.1.1.1` und trägt einen dhcpcd-Generierungskommentar. Ein aktuell laufender `dhcpcd`-Dienst wurde nicht beobachtet; vor Resolveränderungen die tatsächliche Verwaltung erneut prüfen. Das SSH-Drop-in deaktiviert Root-, Passwort- und Keyboard-Interactive-Anmeldung und aktiviert Public-Key-Anmeldung.