cryodev/docs/getting-started/first-install.md

366 lines
9.5 KiB
Markdown

# Erstinstallation (x86_64 Server)
Diese Anleitung beschreibt die **Erstinstallation** eines neuen x86_64 Servers (z.B. cryodev-main).
> **Fuer Raspberry Pi:** Siehe [SD-Image erstellen](sd-image.md).
## Uebersicht
Bei der Erstinstallation gibt es ein Henne-Ei-Problem:
- SOPS-Secrets werden mit dem SSH-Host-Key verschluesselt
- Der SSH-Host-Key wird erst bei der Installation generiert
- Daher: **Erst ohne Secrets installieren, dann Secrets konfigurieren**
### Ablauf
```
1. Services deaktivieren (die Secrets brauchen)
2. NixOS installieren
3. SSH-Host-Key extrahieren, SOPS konfigurieren, sofort erstellbare Secrets anlegen
4. Stufe-1-Services aktivieren und deployen (Headscale, Forgejo, Mail, Nginx)
5. Restliche Secrets generieren (Tailscale, Headplane, Forgejo-Runner)
6. Stufe-2-Services aktivieren und final deployen
```
## Schritt 1: Host-Konfiguration vorbereiten
> Falls der Host bereits in `hosts/` und `flake.nix` existiert, ueberspringe 1.1-1.2.
### 1.1 Host aus Template erstellen
```bash
nix run .#create -- -t generic-server -n <hostname>
```
Das Script:
- Kopiert das Template nach `hosts/<hostname>/`
- Setzt den Hostname in `networking.nix`
- Erstellt eine leere `secrets.yaml`
- Fuegt die Dateien zu Git hinzu
### 1.2 In flake.nix registrieren
```nix
nixosConfigurations = {
<hostname> = mkNixosConfiguration "x86_64-linux" [ ./hosts/<hostname> ];
};
```
Ausserdem `hardware.nix` und `disks.sh` fuer die Zielhardware anpassen.
### 1.4 Services temporaer deaktivieren
Alle Services, die SOPS-Secrets referenzieren, muessen fuer die Erstinstallation deaktiviert werden. Andernfalls schlaegt die Installation fehl, weil die Secrets noch nicht entschluesselt werden koennen.
In `hosts/<hostname>/services/default.nix` die entsprechenden Imports auskommentieren:
```nix
{
imports = [
# Deaktiviert bis SOPS-Secrets konfiguriert sind:
# ./forgejo.nix # braucht: forgejo-runner/token, forgejo/mail-pw
# ./headplane.nix # braucht: headplane/cookie_secret, headplane/agent_pre_authkey
# ./mailserver.nix # braucht: mailserver/accounts/*
# ./tailscale.nix # braucht: tailscale/auth-key
# Diese Services brauchen keine Secrets:
./headscale.nix
./netdata.nix
./nginx.nix
./openssh.nix
./sops.nix
];
}
```
Zusaetzlich in `hosts/<hostname>/services/sops.nix` die Secrets-Definitionen auskommentieren:
```nix
sops = {
defaultSopsFile = ../secrets.yaml;
# secrets = {
# "forgejo-runner/token" = { };
# "tailscale/auth-key" = { };
# };
};
```
### 1.5 Konfiguration testen
```bash
nix eval .#nixosConfigurations.<hostname>.config.system.build.toplevel.name
```
## Schritt 2: Installation durchfuehren
### 2.1 NixOS ISO booten
Vom [NixOS Minimal ISO](https://nixos.org/download/#nixos-iso) booten (USB/CD).
### 2.2 Netzwerk und SSH einrichten
```bash
passwd # Root-Passwort setzen fuer SSH-Zugang
ip a # IP-Adresse ermitteln
```
Optional per SSH verbinden (bequemer):
```bash
ssh -o StrictHostKeyChecking=no root@<IP>
```
### 2.3 Installieren
```bash
nix --experimental-features "nix-command flakes" run \
git+<REPO_URL>#apps.x86_64-linux.install -- \
-n <hostname> \
-r <REPO_URL>
```
Alternativ, falls das Repository bereits unter `/tmp/nixos` geklont wurde:
```bash
nix --experimental-features "nix-command flakes" run /tmp/nixos#install -- -n <hostname>
```
> **Hinweis:** Die Disk-ID in `hosts/<hostname>/disks.sh` muss zur Hardware passen.
> Pruefen mit `ls -la /dev/disk/by-id/`.
Das Script:
1. Klont das Repository (bei `-r`)
2. Partitioniert die Disk (via `disks.nix` oder `disks.sh`)
3. Generiert `hardware.nix` (falls nicht vorhanden)
4. Installiert NixOS
### 2.4 Reboot
```bash
reboot
```
## Schritt 3: SOPS-Secrets konfigurieren
Nach dem ersten Boot einloggen (Passwort: `changeme`, sofort aendern mit `passwd`).
### 3.1 SSH-Host-Key zu Age-Key konvertieren
Auf dem **neuen Server**:
```bash
nix-shell -p ssh-to-age --run 'cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age'
```
Ausgabe notieren (z.B. `age1abc123...`).
Alternativ remote:
```bash
nix-shell -p ssh-to-age --run 'ssh-keyscan -p 2299 -t ed25519 <IP> | ssh-to-age'
```
### 3.2 .sops.yaml aktualisieren
Auf dem **Entwicklungsrechner** den neuen Host-Key in `.sops.yaml` eintragen:
```yaml
keys:
- &steffen_key age1e8p... # steffen (lokal)
- &hostname_key age1abc... # Key von Schritt 3.1
creation_rules:
- path_regex: hosts/<hostname>/secrets.yaml$
key_groups:
- age:
- *steffen_key
- *hostname_key
```
### 3.3 Secrets erstellen
Secrets-Datei oeffnen:
```bash
sops hosts/<hostname>/secrets.yaml
```
Die folgende Tabelle zeigt alle Secrets fuer **cryodev-main** und wie sie generiert werden:
#### Sofort erstellbare Secrets
Diese Secrets haben keine Abhaengigkeiten und koennen direkt generiert werden:
| Secret | Befehl |
|--------|--------|
| `headplane/cookie_secret` | `openssl rand -hex 16` |
| `mailserver/accounts/admin` | `mkpasswd -sm bcrypt` (Passwort merken!) |
| `mailserver/accounts/forgejo` | `mkpasswd -sm bcrypt` (Passwort merken!) |
| `forgejo/mail-pw` | Klartext-Passwort das zum bcrypt-Hash von `mailserver/accounts/forgejo` passt |
#### Secrets die laufende Services brauchen
Diese Secrets koennen erst nach Schritt 4 erstellt werden. **Jetzt noch nicht eintragen** -- sie werden spaeter ergaenzt.
| Secret | Befehl | Voraussetzung |
|--------|--------|---------------|
| `tailscale/auth-key` | Siehe Schritt 4.1-4.2 | Headscale laeuft |
| `headplane/agent_pre_authkey` | Siehe Schritt 4.1-4.2 | Headscale laeuft |
| `forgejo-runner/token` | Forgejo Admin Panel > Actions > Runners > Create Runner | Forgejo laeuft |
#### Beispiel secrets.yaml (Klartext vor Verschluesselung)
```yaml
headplane:
cookie_secret: "a1b2c3d4e5f6..."
mailserver:
accounts:
admin: "$2b$05$..."
forgejo: "$2b$05$..."
forgejo:
mail-pw: "das-klartext-passwort"
```
### 3.4 Services stufenweise reaktivieren -- Stufe 1
> **Wichtig:** Services die Headscale- oder Forgejo-Secrets brauchen (Tailscale,
> Headplane, Forgejo-Runner) duerfen noch **nicht** aktiviert werden, da diese
> Secrets erst generiert werden koennen, wenn die Services laufen.
Auf dem **Entwicklungsrechner** in `hosts/<hostname>/services/default.nix` die
Services **ohne externe Abhaengigkeiten** aktivieren:
```nix
{
imports = [
# Stufe 1: Services ohne externe Abhaengigkeiten
./forgejo.nix
./headscale.nix
./mailserver.nix
./netdata.nix
./nginx.nix
./openssh.nix
./sops.nix
# Stufe 2: Erst nach Schritt 4 aktivieren
# ./forgejo-runner.nix # braucht: forgejo-runner/token (Forgejo)
# ./headplane.nix # braucht: headplane/agent_pre_authkey (Headscale)
# ./tailscale.nix # braucht: tailscale/auth-key (Headscale)
];
}
```
### 3.5 Deployen (Stufe 1)
```bash
nix run .#deploy -- -n <hostname>
```
Dies nutzt die Konfiguration aus `deploy.json`. Alternativ manuell:
```bash
NIX_SSHOPTS="-p 2299" nixos-rebuild switch --flake .#<hostname> \
--target-host <user>@<IP> --sudo --ask-sudo-password
```
Nach diesem Deploy laufen Headscale, Forgejo, Mailserver und Nginx.
### 3.6 Forgejo Admin-Account erstellen
Beim ersten Start hat Forgejo noch keine Benutzer. Admin-Account per CLI anlegen
(auf dem **Server**):
```bash
forgejo admin user create \
--username <benutzername> \
--email <email>@<domain> \
--password <passwort> \
--admin
```
> **Hinweis:** Das `forgejo` Shell-Alias wird vom Modul bereitgestellt und fuehrt
> automatisch den Befehl als `forgejo`-User mit der richtigen Config aus.
> Falls der Alias nicht verfuegbar ist, neue Shell starten (`bash` oder `zsh`).
>
> Da `DISABLE_REGISTRATION = true` gesetzt ist, koennen neue Accounts
> nur per CLI erstellt werden.
## Schritt 4: Restliche Secrets generieren und alle Services aktivieren
Nachdem der Server mit Headscale und Forgejo laeuft:
1. **Headscale-User anlegen** (auf dem Server):
```bash
sudo headscale users create default
sudo headscale users create headplane-agent
```
2. **User-IDs ermitteln** (wird fuer die Preauth-Keys benoetigt):
```bash
sudo headscale users list
```
Die Ausgabe zeigt die numerischen IDs (z.B. `1` fuer default, `2` fuer headplane-agent).
3. **Preauth-Keys generieren** (mit den IDs aus Schritt 2):
```bash
# Fuer Tailscale (User-ID von "default" einsetzen)
sudo headscale preauthkeys create --expiration 99y --reusable --user <ID>
# Fuer Headplane Agent (User-ID von "headplane-agent" einsetzen)
sudo headscale preauthkeys create --expiration 99y --user <ID>
```
4. **Forgejo-Runner-Token** ueber das Forgejo Admin Panel erstellen:
Administration > Actions > Runners > Create new Runner
5. **Secrets ergaenzen**:
```bash
sops hosts/<hostname>/secrets.yaml
```
Die fehlenden Secrets eintragen:
```yaml
tailscale:
auth-key: "tskey-..."
forgejo-runner:
token: "..."
headplane:
agent_pre_authkey: "..."
```
6. **Stufe-2-Services aktivieren** in `hosts/<hostname>/services/default.nix`:
```nix
{
imports = [
./forgejo.nix
./forgejo-runner.nix
./headplane.nix
./headscale.nix
./mailserver.nix
./netdata.nix
./nginx.nix
./openssh.nix
./sops.nix
./tailscale.nix
];
}
```
6. **Erneut deployen**:
```bash
nix run .#deploy -- -n <hostname>
```
## Naechste Schritte
- [SOPS-Referenz](../services/sops.md) -- Detail-Dokumentation zur Secret-Verwaltung
- [SD-Image erstellen](sd-image.md) -- Raspberry Pi installieren
- [CD einrichten](../deployment/cd.md) -- Automatisches Deployment