In diesem Beitrag möchte ich ein Remote-System mit NixOS installieren, aber dabei die manuelle Interaktion mit dem Remote-Host reduzieren, d. h., ich will kein manuelles Set-up direkt am Zielsystem durchführen.
Grundsätzliches Vorgehen
Die ersten 3 Schritte sind im Wesentlichen dieselben wie bei einer manuellen Installation – ich muss das Zielsystem vorbereiten:
- Aktuelles ISO-Image herunterladen
- Image auf einen USB-Stick brennen
- Notebook vom USB-Stick booten
Der nächste Schritt ist entscheidend: Ein mit USB-Stick gestartetes Zielsystem hat SSH aktiv. Leider ist für weder root noch den Standardbenutzer nixos ein Passwort gesetzt. Wenn man das Image von der Website verwendet, muss man kurz am Remote-System eingreifen und sudo passwd nixos oder sudo passwd root ausführen.
Manuelles Passwort-Setzen auf dem Remote-Rechner vermeiden
Anstatt das Standard-NixOS-ISO zu verwenden, kann man ein benutzerdefiniertes ISO erstellen, das bereits den eigenen öffentlichen SSH-Schlüssel enthält. Wenn das Notebook von diesem USB-Stick bootet, startet es automatisch den SSH-Daemon und vertraut dem eigenen Schlüssel.
Das lässt sich mit nixos-generators bewerkstelligen. Folgendes auf dem lokalen Rechner (von dem aus Nix-Befehle ausgeführt werden) hinzufügen:
nix run github:nix-community/nixos-generators -- \
--format iso \
--configuration '{ ... }: {
users.users.nixos.openssh.authorizedKeys.keys = [ "ssh-ed25519 AAA..." ];
}'
Das habe ich selbst noch nicht getestet.
Die Konfiguration erstellen
Angenommen, wir haben nun ein laufendes Remote-System mit einem Admin-Passwort. Bevor wir beginnen können, benötigen wir eine Konfiguration. Neben der Systemkonfiguration (Bootloader usw.) benötigen wir auch die Festplattenkonfiguration. Dafür verwenden wir disko – ein Werkzeug, das es erlaubt, das Festplatten-Layout (Partitionen, LVM, LUKS, Dateisysteme) in einer .nix-Datei zu beschreiben.
disko.devices = {
disk = {
main = {
device = "/dev/sdb";
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = {
size = "500M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
root = {
end = "-1G";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
plainSwap = {
size = "100%";
content = {
type = "swap";
discardPolicy = "both";
resumeDevice = true; # Ruhezustand von diesem Gerät fortsetzen
};
};
};
};
};
};
};
}
Im GitHub-Repository von disko finden sich viele verschiedene Beispiele für komplexere Set-ups. Für mein Homelab reicht es einfach: Ich brauche nur eine Boot-Partition, eine Swap-Partition und die Root-Partition.
Das zweite benötigte Werkzeug ist nixos-anywhere – ein Tool, das die Installation von NixOS auf beliebigen Maschinen über SSH ermöglicht. Es setzt lediglich voraus, dass die Zielmaschine von einem Linux-Installer (wie einem NixOS-ISO) gebootet ist und SSH-Zugang besteht.
Ich passe meine flake.nix entsprechendan, um den neuen Host zu installieren. Einfachheitshalber zeige ich hier eine vereinfachte Version:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
disko.url = "github:nix-community/disko";
disko.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, disko, ... }: {
nixosConfigurations.lenovo = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
disko.nixosModules.disko
./hosts/lenovo
./profiles/server
];
};
};
}
Das Verzeichnis hosts/lenovo enthält die hostspezifische Konfiguration einschließlich der Disko-Konfiguration. Die default.nix sieht so aus:
{ pkgs, ... }: {
imports = [
./hardware.nix
./disko.nix
];
}
Die hardware.nix wiederum sieht folgendermaßen aus:
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
}
Unter profiles/server befinden sich gemeinsame Netzwerkkonfigurationen usw., die für alle „Server" gelten.
Die Installation durchführen
Mit der gesamten Konfiguration an Ort und Stelle können wir die Installation anstoßen. Da der Host per DHCP eine IP-Adresse erhalten hat, muss diese zunächst herausgefunden werden. Danach kann folgender Befehl ausgeführt werden:
nix run github:nix-community/nixos-anywhere -- \
--flake .#lenovo \
root@
Folgendes passiert nun:
- SSH-Verbindung: nixos-anywhere verbindet sich mit dem Ziel.
- Partitionierung: Disko wird verwendet, um die Festplatte zu löschen und Partitionen exakt wie definiert anzulegen.
- Installation: Das Flake wird lokal gebaut und das System auf das Ziel kopiert.
- Neustart: Nach Abschluss startet die Maschine neu und bootet das frisch und perfekt konfigurierte NixOS.
Nun haben wir ein vollständig funktionierendes Remote-System.
Abschluss
Es gibt einige Dinge, die man bedenken sollte:
-
Wer nix-sops verwendet, sollte auch den Host-Schlüssel zur
.sops.yamlhinzufügen, wie in meinem letzten Beitrag beschrieben. -
Sicherstellen, dass SSH keine Passwort-Authentifizierung erlaubt:
# OpenSSH-Server aktivieren. services.sshd.enable = true; services.openssh.settings = { PasswordAuthentication = false; PermitRootLogin = "no"; }; -
Die Standard-Benutzerkonten
rootundnixosabsichern:-
Für
nixoswird ein Passwort gesetzt und SSH-Schlüssel hinzugefügt:users.users.nixos = { isNormalUser = true; extraGroups = [ "wheel" "networkmanager" "video" ]; hashedPasswordFile = config.sops.secrets.default_password.path; # Den leeren String-Fallback deaktivieren initialHashedPassword = lib.mkForce null; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOrOn3Kj/+ztMtQAaq4pVvXgTsIs1ZOqQDbsA+nJMuRM nixos@homelab from clawfinger" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFTCwPNpVjW6R9vqpKgNSWgGS5hZMZcHwexAMl7E/OI2 nixos@homelab from clawfinger" ]; }; -
rootwird vollständig für den Log-in gesperrt und ebenfalls mit einem Passwort versehen:users.users.root = { openssh.authorizedKeys.keys = lib.mkForce [ ]; hashedPasswordFile = config.sops.secrets.default_root_password.path; };
-
Fazit und Ausblick
Dieser Workflow ist ein Gamechanger für mein Homelab. Ich kann meine Server jetzt von Grund auf neu installieren, ohne jemals eine direkt angeschlossene Tastatur anfassen zu müssen.
Quellen:
im Haupttext
Titelbild: https://hdqwalls.com/linux-nixos-wallpaper

Danke für den Artikel und ganz allgemein die Reihe über NixOS. Sie hat auf jeden Fall meine Neugier an der Distribution geweckt und ich werde mich sicher noch weiter einlesen. Was mir im Artikel aufgefallen ist ist, dass das Repository https://github.com/nix-community/nixos-generators, auf das unter "Manuelles Passwort-Setzen auf dem Remote-Rechner vermeiden" Bezug genommen wird, als deprecated markiert ist. Laut Kommentar im repository wurden die meisten Inhalte mit Version 25.05 nach nixpkgs überführt.
Ich habe es gewagt NixOs zu installieren, danke für deine Reihe. Es war etwas hakelig, aber ich liebe es.