cryodev/docs/getting-started/first-install.md
steffen dbf98e2f22 add .gitignore, fix headscale CLI to use numeric user IDs
- Add .gitignore for nix build result symlinks
- Fix all headscale CLI commands: --user now requires numeric ID,
  not username (changed in newer headscale versions)
- Add 'headscale users list' step to docs where preauth keys are created
2026-03-14 12:28:47 +01:00

8.9 KiB

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.

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

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

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:

{
  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:

sops = {
  defaultSopsFile = ../secrets.yaml;
  # secrets = {
  #   "forgejo-runner/token" = { };
  #   "tailscale/auth-key" = { };
  # };
};

1.5 Konfiguration testen

nix eval .#nixosConfigurations.<hostname>.config.system.build.toplevel.name

Schritt 2: Installation durchfuehren

2.1 NixOS ISO booten

Vom NixOS Minimal ISO booten (USB/CD).

2.2 Netzwerk und SSH einrichten

passwd                  # Root-Passwort setzen fuer SSH-Zugang
ip a                    # IP-Adresse ermitteln

Optional per SSH verbinden (bequemer):

ssh -o StrictHostKeyChecking=no root@<IP>

2.3 Installieren

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:

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

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:

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:

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:

keys:
  - &admin_key age1e8p...     # Dein lokaler Admin-Key
  - &hostname_key age1abc...  # Key von Schritt 3.1

creation_rules:
  - path_regex: hosts/<hostname>/secrets.yaml$
    key_groups:
      - age:
          - *admin_key
          - *hostname_key

3.3 Secrets erstellen

Secrets-Datei oeffnen:

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)

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:

{
  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)

nix run .#deploy -- -n <hostname>

Dies nutzt die Konfiguration aus deploy.json. Alternativ manuell:

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.

Schritt 4: Restliche Secrets generieren und alle Services aktivieren

Nachdem der Server mit Headscale und Forgejo laeuft:

  1. Headscale-User anlegen (auf dem Server):

    sudo headscale users create default
    sudo headscale users create headplane-agent
    
  2. User-IDs ermitteln (wird fuer die Preauth-Keys benoetigt):

    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):

    # 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:

    sops hosts/<hostname>/secrets.yaml
    

    Die fehlenden Secrets eintragen:

    tailscale:
        auth-key: "tskey-..."
    forgejo-runner:
        token: "..."
    headplane:
        agent_pre_authkey: "..."
    
  6. Stufe-2-Services aktivieren in hosts/<hostname>/services/default.nix:

    {
      imports = [
        ./forgejo.nix
        ./forgejo-runner.nix
        ./headplane.nix
        ./headscale.nix
        ./mailserver.nix
        ./netdata.nix
        ./nginx.nix
        ./openssh.nix
        ./sops.nix
        ./tailscale.nix
      ];
    }
    
  7. Erneut deployen:

    nix run .#deploy -- -n <hostname>
    

Naechste Schritte