207 lines
11 KiB
Markdown
207 lines
11 KiB
Markdown
# 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.
|