This commit is contained in:
2026-09-06 17:32:17 +02:00
commit e37e956f95
12 changed files with 956 additions and 0 deletions
+126
View File
@@ -0,0 +1,126 @@
# Serveur PXE déclaratif : DHCP-proxy (ou DHCP complet)+TFTP (dnsmasq)
# pour le premier étage iPXE, HTTP (Caddy) pour kernel/initrd/script iPXE
# (TFTP seul est trop lent pour de gros fichiers). Ce host n'a besoin
# d'aucune donnée privée : il ne sert que l'image d'installation publique
# nixos_fleet ; le repo privé nixos_users n'est fetché qu'au moment de
# l'install, directement par la machine en cours d'installation.
{ config, lib, pkgs, ... }:
let
# true = ce serveur devient l'UNIQUE serveur DHCP du réseau cible.
# false = proxyDHCP uniquement : coexiste avec le routeur/DHCP existant,
# répond seulement aux requêtes de boot PXE. C'est le mode
# recommandé si les 100 PC restent sur un réseau qui a déjà un
# DHCP (le cas le plus probable).
standaloneDhcp = false;
# À adapter à l'interface réseau réelle du serveur, et à son IP fixe
# (le script iPXE doit pointer vers une adresse stable, pas un nom
# d'interface).
interface = "eth0";
serverIp = "192.168.1.10";
fleetRepo = "git+https://gitea.miniclic.net/Damien/Nixos_Fleet.git";
webroot = "/var/www/pxe";
tftpRoot = "/var/lib/tftpboot";
in
{
networking.hostName = "pxe-server";
networking.firewall.allowedUDPPorts = [
67
69
4011
];
networking.firewall.allowedTCPPorts = [ 80 ];
services.dnsmasq = {
enable = true;
settings = {
port = 0; # pas de résolution DNS, uniquement DHCP/TFTP/PXE
inherit interface;
"enable-tftp" = true;
"tftp-root" = tftpRoot;
# Détection d'architecture + évite la boucle de chainload iPXE :
# une machine qui a déjà démarré en iPXE s'annonce via l'option 175,
# on lui sert alors le script HTTP plutôt que de rechainer le même
# binaire à l'infini.
"dhcp-match" = [
"set:ipxe,175"
"set:efi-x86_64,option:client-arch,7"
];
"dhcp-boot" = [
"tag:ipxe,http://${serverIp}/netboot.ipxe"
"tag:!ipxe,tag:efi-x86_64,ipxe.efi"
"tag:!ipxe,tag:!efi-x86_64,undionly.kpxe"
];
}
// (
if standaloneDhcp then
{ "dhcp-range" = [ "192.168.1.50,192.168.1.150,12h" ]; } # à adapter au réseau cible
else
{ "dhcp-range" = [ "192.168.1.0,proxy" ]; } # à adapter au sous-réseau existant
);
};
# `:80` explicite (pas de nom de domaine) : Caddy ne tente donc aucune
# demande de certificat ACME, il sert juste du HTTP nu en local — exactement
# ce qu'il faut pour du netboot sur un LAN.
services.caddy = {
enable = true;
virtualHosts.":80" = {
extraConfig = ''
root * ${webroot}
file_server
'';
};
};
systemd.tmpfiles.rules = [
"d ${tftpRoot} 0755 dnsmasq dnsmasq -"
"d ${webroot} 0755 caddy caddy -"
];
# Republie l'image d'installation netboot depuis le repo public. À
# relancer après chaque évolution notable de installer/ dans
# nixos_fleet (systemctl start pxe-publish), en plus du rafraîchissement
# quotidien automatique ci-dessous.
systemd.services.pxe-publish = {
description = "Publie l'image d'installation netboot Nixos_Fleet pour le PXE";
path = [ config.nix.package ];
script = ''
set -euo pipefail
kernel=$(nix build --no-link --print-out-paths "${fleetRepo}#nixosConfigurations.installer-netboot.config.system.build.kernel")
initrd=$(nix build --no-link --print-out-paths "${fleetRepo}#nixosConfigurations.installer-netboot.config.system.build.netbootRamdisk")
ipxeScript=$(nix build --no-link --print-out-paths "${fleetRepo}#nixosConfigurations.installer-netboot.config.system.build.netbootIpxeScript")
install -m 0644 "$kernel/bzImage" "${webroot}/bzImage"
install -m 0644 "$initrd/initrd" "${webroot}/initrd"
install -m 0644 "$ipxeScript/netboot.ipxe" "${webroot}/netboot.ipxe"
# Binaires iPXE premier étage (BIOS + UEFI). Noms de sortie du
# paquet pkgs.ipxe à vérifier sur la version réelle avant le pilote.
install -m 0644 "${pkgs.ipxe}/undionly.kpxe" "${tftpRoot}/undionly.kpxe" || true
install -m 0644 "${pkgs.ipxe}/ipxe.efi" "${tftpRoot}/ipxe.efi" || true
'';
serviceConfig.Type = "oneshot";
};
systemd.timers.pxe-publish = {
description = "Rafraîchit quotidiennement l'image PXE (converge avec nixos_fleet)";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
};
};
nix.settings.experimental-features = [
"nix-command"
"flakes"
];
networking.networkmanager.enable = lib.mkDefault true;
services.openssh.enable = true;
system.stateVersion = "26.05";
}