138 lines
5.0 KiB
Nix
138 lines
5.0 KiB
Nix
# 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
|
|
{
|
|
imports = [
|
|
# Généré sur le serveur réel via `nixos-generate-config`, jamais
|
|
# committé (voir .gitignore) — spécifique à cette machine.
|
|
./hardware-configuration.nix
|
|
];
|
|
|
|
boot.loader.systemd-boot.enable = true;
|
|
boot.loader.efi.canTouchEfiVariables = true;
|
|
# Si le serveur est en BIOS legacy (pas UEFI), remplacer les deux lignes
|
|
# au-dessus par boot.loader.grub.device = "/dev/sdX";
|
|
|
|
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";
|
|
}
|