config

NixOS config
Log | Files | Refs | README | LICENSE

default.nix (7789B) - Raw


      1 {
      2   config,
      3   pkgs,
      4   lib,
      5   ...
      6 }:
      7 let
      8   cfg = config.mj.services.ipxe;
      9   ipxeMenu = pkgs.writeText "boot.ipxe" ''
     10     #!ipxe
     11 
     12     # Ensure network is configured
     13     dhcp || echo DHCP failed, trying to continue anyway
     14 
     15     :menu
     16     menu PXE Boot Menu
     17     item debian-shell-toram Boot Debian Live ${pkgs.mrescue-debian-xfce.version} Shell to RAM
     18     item debian-shell-nfs Boot Debian Live ${pkgs.mrescue-debian-xfce.version} Shell via NFS
     19     item debian-xfce-toram Boot Debian Live ${pkgs.mrescue-debian-xfce.version} XFCE to RAM
     20     item debian-xfce-nfs Boot Debian Live ${pkgs.mrescue-debian-xfce.version} XFCE via NFS
     21     item nixos Boot NixOS ${pkgs.mrescue-nixos.version}
     22     item alpine Boot Alpine Linux ${pkgs.mrescue-alpine.version}
     23     item netbootxyz Boot netboot.xyz
     24     item shell iPXE Shell
     25     item tips mrescue tips
     26     choose --default debian-shell-toram --timeout 10000 selected || goto menu
     27     goto ''${selected}
     28 
     29     :debian-shell-toram
     30     kernel http://10.14.143.1/boot/debian-xfce/live/vmlinuz boot=live components fetch=http://10.14.143.1/boot/debian-xfce/live/filesystem.squashfs systemd.unit=multi-user.target ''${cmdline}
     31     initrd http://10.14.143.1/boot/debian-xfce/live/initrd.img
     32     boot
     33 
     34     :debian-shell-nfs
     35     kernel http://10.14.143.1/boot/debian-xfce/live/vmlinuz boot=live components netboot=nfs nfsroot=10.14.143.1:/boot/debian-xfce systemd.unit=multi-user.target ''${cmdline}
     36     initrd http://10.14.143.1/boot/debian-xfce/live/initrd.img
     37     boot
     38 
     39     :debian-xfce-toram
     40     kernel http://10.14.143.1/boot/debian-xfce/live/vmlinuz boot=live components fetch=http://10.14.143.1/boot/debian-xfce/live/filesystem.squashfs ''${cmdline}
     41     initrd http://10.14.143.1/boot/debian-xfce/live/initrd.img
     42     boot
     43 
     44     :debian-xfce-nfs
     45     kernel http://10.14.143.1/boot/debian-xfce/live/vmlinuz boot=live components netboot=nfs nfsroot=10.14.143.1:/boot/debian-xfce ''${cmdline}
     46     initrd http://10.14.143.1/boot/debian-xfce/live/initrd.img
     47     boot
     48 
     49     :nixos
     50     # kernel params copied from https://github.com/nix-community/nixos-images/releases/download/nixos-25.11/netboot-x86_64-linux.ipxe
     51     kernel http://10.14.143.1/boot/nixos/kernel init=/nix/store/lillmv6sbjxgyyyn1ilkica21q3hmpya-nixos-system-nixos-kexec-25.11beta-193477.gfedcba/init initrd=initrd-x86_64-linux nohibernate loglevel=4 lsm=landlock,yama,bpf ''${cmdline}
     52     initrd http://10.14.143.1/boot/nixos/initrd
     53     boot
     54 
     55     :alpine
     56     kernel http://10.14.143.1/boot/alpine/kernel ''${cmdline}
     57     initrd http://10.14.143.1/boot/alpine/initrd
     58     boot
     59 
     60     :netbootxyz
     61     isset ''${platform} && iseq ''${platform} pcbios && chain --autofree https://boot.netboot.xyz/ipxe/netboot.xyz.kpxe ||
     62     chain --autofree https://boot.netboot.xyz/ipxe/netboot.xyz.efi
     63 
     64     :shell
     65     shell
     66     goto menu
     67 
     68     :tips
     69     echo
     70     echo To add kernel command line arguments:
     71     echo   1. Select 'iPXE Shell' from menu
     72     echo   2. Run: set cmdline systemd.unit=multi-user.target
     73     echo   3. Type 'exit' to return to menu
     74     echo   4. Select your OS to boot with custom args
     75     echo
     76     echo More useful commands:
     77     echo  set cmdline console=ttyS0
     78     echo
     79     prompt Press any key to return to menu...
     80     goto menu
     81   '';
     82 
     83   # Custom iPXE with embedded menu (UEFI)
     84   customIpxeEfi = pkgs.ipxe.override {
     85     embedScript = ipxeMenu;
     86   };
     87 
     88   # Custom iPXE with embedded menu (BIOS)
     89   customIpxeBios = pkgs.ipxe.override {
     90     embedScript = ipxeMenu;
     91   };
     92 
     93   exportsFile = pkgs.writeText "unfs3-exports" ''
     94     /boot 10.14.143.0/24(ro,no_subtree_check,no_root_squash,insecure) localhost(ro,no_subtree_check,no_root_squash,insecure)
     95   '';
     96 
     97   # TFTP root directory with all boot files
     98   tftp-root = pkgs.runCommand "tftp-root" { } ''
     99     mkdir -p $out/alpine
    100     mkdir -p $out/debian-xfce
    101     mkdir -p $out/nixos
    102 
    103     cp ${customIpxeEfi}/ipxe.efi $out/boot.efi
    104     cp ${customIpxeBios}/undionly.kpxe $out/boot.kpxe
    105 
    106     # Alpine
    107     cp ${pkgs.mrescue-alpine}/kernel $out/alpine/kernel
    108     cp ${pkgs.mrescue-alpine}/initrd $out/alpine/initrd
    109 
    110     # Debian XFCE (full ISO contents)
    111     cp -r ${pkgs.mrescue-debian-xfce}/* $out/debian-xfce/
    112 
    113     # NixOS
    114     cp ${pkgs.mrescue-nixos}/kernel $out/nixos/kernel
    115     cp ${pkgs.mrescue-nixos}/initrd $out/nixos/initrd
    116   '';
    117 in
    118 {
    119   options.mj.services.ipxe = with lib.types; {
    120     enable = lib.mkEnableOption "enable ipxe boot stuff";
    121     ifWan = lib.mkOption { type = str; };
    122   };
    123 
    124   config = lib.mkIf cfg.enable {
    125 
    126     services = {
    127 
    128       rpcbind.enable = true;
    129 
    130       dnsmasq = {
    131         enable = true;
    132         settings = {
    133           dhcp-range = [ "10.14.143.100,10.14.143.200" ];
    134           dhcp-option = "66,\"0.0.0.0\"";
    135           enable-tftp = true;
    136           tftp-root = "${tftp-root}";
    137           interface = "br0";
    138 
    139           dhcp-match = [
    140             "set:efi-x86_64,option:client-arch,7" # EFI BC (x86-64)
    141             "set:efi-x86_64,option:client-arch,9" # EFI x86-64
    142             "set:efi-x86,option:client-arch,6" # EFI IA32
    143             "set:bios,option:client-arch,0" # BIOS x86
    144           ];
    145 
    146           dhcp-boot = [
    147             "tag:efi-x86_64,boot.efi" # UEFI x86-64 clients
    148             "tag:efi-x86,boot.efi" # UEFI IA32 clients
    149             "tag:bios,boot.kpxe" # BIOS clients
    150             "boot.efi" # Default to UEFI if undetected
    151           ];
    152         };
    153       };
    154 
    155       nginx = {
    156         enable = true;
    157         defaultListenAddresses = [ "0.0.0.0" ];
    158         virtualHosts = {
    159           "_" = {
    160             default = true;
    161             root = "/var/run/nginx/motiejus";
    162             locations."/".extraConfig = ''
    163               autoindex on;
    164             '';
    165             locations."/boot/" = {
    166               alias = "${tftp-root}/";
    167               extraConfig = ''
    168                 autoindex on;
    169               '';
    170             };
    171           };
    172         };
    173       };
    174     };
    175 
    176     systemd.services = {
    177       unfs3 = {
    178         description = "Userspace NFSv3 server";
    179         after = [
    180           "network.target"
    181           "rpcbind.service"
    182         ];
    183         requires = [ "rpcbind.service" ];
    184         wantedBy = [ "multi-user.target" ];
    185         serviceConfig = {
    186           ExecStart = "${pkgs.unfs3}/bin/unfsd -e ${exportsFile} -s -d -n 2049 -m 20048";
    187           BindReadOnlyPaths = [ "${tftp-root}:/boot" ];
    188           DynamicUser = true;
    189           ProtectHome = true;
    190           ProtectSystem = "strict";
    191         };
    192       };
    193     };
    194 
    195     environment = {
    196       systemPackages = with pkgs; [
    197         OVMF
    198         libnfs # nfs-ls
    199         dnsmasq
    200       ];
    201     };
    202 
    203     networking = {
    204       bridges.br0 = {
    205         interfaces = [ ];
    206       };
    207 
    208       interfaces.br0 = {
    209         ipv4.addresses = [
    210           {
    211             address = "10.14.143.1";
    212             prefixLength = 24;
    213           }
    214         ];
    215       };
    216 
    217       nat = {
    218         enable = true;
    219         externalInterface = cfg.ifWan;
    220         internalInterfaces = [ "br0" ];
    221         internalIPs = [ "10.14.143.0/24" ];
    222       };
    223 
    224       firewall = {
    225         rejectPackets = true;
    226         interfaces.br0 = {
    227           allowedTCPPorts = [
    228             53 # DNS
    229             80 # HTTP for boot files
    230             111 # rpcbind
    231             2049 # NFS
    232             20048 # mountd
    233           ];
    234           allowedUDPPorts = [
    235             53 # DNS
    236             67 # DHCP
    237             69 # TFTP
    238             111 # rpcbind
    239             20048 # mountd
    240           ];
    241         };
    242         extraCommands = ''
    243           # Allow only through WiFi interface (to gateway and internet)
    244           iptables -A FORWARD -s 10.14.143.0/24 -o ${cfg.ifWan} -j ACCEPT
    245 
    246           # Allow established connections back
    247           iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
    248 
    249           # Block everything else from 10.14.143.0/24
    250           iptables -A FORWARD -s 10.14.143.0/24 -j DROP
    251         '';
    252       };
    253 
    254     };
    255 
    256   };
    257 
    258 }