Netboot: Difference between revisions
imported>Erikarvstedt Improve example: Move script definition to system build. Fix old `nix build` syntax. Add firewall commands. |
m Format the recently-added example with `nixfmt-rfc-style`. |
||
(9 intermediate revisions by 4 users not shown) | |||
Line 2: | Line 2: | ||
=== Example === | === Example === | ||
This example uses [https://github.com/danderson/netboot/tree/ | This example uses [https://github.com/danderson/netboot/tree/main/pixiecore Pixiecore] for hosting, which works in an ordinary network environment with an existing DHCP server. | ||
Create file <code>system.nix</code>: | Create file <code>system.nix</code>: | ||
Line 12: | Line 12: | ||
sys = nixpkgs.lib.nixosSystem { | sys = nixpkgs.lib.nixosSystem { | ||
system = "x86_64-linux"; | system = "x86_64-linux"; | ||
modules = [ | modules = [ | ||
({ config, pkgs, lib, modulesPath, ... }: { | |||
({ config, pkgs, lib, ... }: | imports = [ | ||
(modulesPath + "/installer/netboot/netboot-minimal.nix") | |||
]; | |||
config = { | config = { | ||
## Some useful options for setting up a new system | ## Some useful options for setting up a new system | ||
# services.getty.autologinUser = mkForce "root"; | # services.getty.autologinUser = lib.mkForce "root"; | ||
# users.users.root.openssh.authorizedKeys.keys = [ ... ]; | # users.users.root.openssh.authorizedKeys.keys = [ ... ]; | ||
# console.keyMap = "de"; | # console.keyMap = "de"; | ||
Line 29: | Line 30: | ||
}; | }; | ||
run-pixiecore = let | |||
hostPkgs = if sys.pkgs.system == builtins.currentSystem | |||
then sys.pkgs | |||
else nixpkgs.legacyPackages.${builtins.currentSystem}; | |||
build = sys.config.system.build; | |||
in hostPkgs.writers.writeBash "run-pixiecore" '' | |||
exec ${hostPkgs.pixiecore}/bin/pixiecore \ | |||
boot ${build.kernel}/bzImage ${build.netbootRamdisk}/initrd \ | |||
--cmdline "init=${build.toplevel}/init loglevel=4" \ | |||
--debug --dhcp-no-bind \ | |||
--port 64172 --status-port 64172 "$@" | |||
''; | |||
in | in | ||
run-pixiecore | |||
</syntaxHighlight> | </syntaxHighlight> | ||
Line 55: | Line 52: | ||
# Open required firewall ports | # Open required firewall ports | ||
sudo iptables -I nixos-fw -p udp -m multiport --dports 67,69,4011 -j ACCEPT | sudo iptables -w -I nixos-fw -p udp -m multiport --dports 67,69,4011 -j ACCEPT | ||
sudo iptables -I nixos-fw -p tcp -m tcp --dport 64172 -j ACCEPT | sudo iptables -w -I nixos-fw -p tcp -m tcp --dport 64172 -j ACCEPT | ||
# Run pixiecore | # Run pixiecore | ||
Line 62: | Line 59: | ||
# Close ports | # Close ports | ||
sudo iptables -D nixos-fw -p udp -m multiport --dports 67,69,4011 -j ACCEPT | sudo iptables -w -D nixos-fw -p udp -m multiport --dports 67,69,4011 -j ACCEPT | ||
sudo iptables -D nixos-fw -p tcp -m tcp --dport 64172 -j ACCEPT | sudo iptables -w -D nixos-fw -p tcp -m tcp --dport 64172 -j ACCEPT | ||
</syntaxHighlight> | |||
=== Another example === | |||
{{file|netboot.nix|nix| | |||
<nowiki> | |||
{ | |||
name ? "netboot", | |||
arch ? "x86_64-linux", | |||
configuration ? _: { }, # --arg configuration 'import ./netboot-config.nix' | |||
legacy ? false, # variation with pxelinux and dnsmasq for older systems | |||
cmdline ? [ ], | |||
loglevel ? 4, | |||
pixiecoreport ? 64172, | |||
proxynets ? [ "192.168.0.0" ], | |||
serialconsole ? false, | |||
serialport ? 0, | |||
serialspeed ? 9600, | |||
nixpkgs ? import <nixpkgs> { }, | |||
... | |||
}: | |||
with nixpkgs; | |||
with lib; | |||
let | |||
example-configuration = | |||
{ pkgs, config, ... }: | |||
with pkgs; | |||
{ | |||
config = { | |||
environment.systemPackages = [ | |||
mtr | |||
bridge-utils | |||
vlan | |||
ethtool | |||
jwhois | |||
sipcalc | |||
netcat-openbsd | |||
tsocks | |||
psmisc | |||
pciutils | |||
usbutils | |||
lm_sensors | |||
dmidecode | |||
microcom | |||
unar | |||
mkpasswd | |||
ripgrep | |||
wget | |||
rsync | |||
sshfs-fuse | |||
iperf3 | |||
mc | |||
mutt | |||
borgbackup | |||
rxvt_unicode.terminfo | |||
]; | |||
# users.users.nixos.openssh.authorizedKeys.keys = [ … ]; | |||
# services.openssh = { ports = [2]; settings.PasswordAuthentication = false; }; | |||
# virtualisation.lxc.enable = true; | |||
}; | |||
}; | |||
config = import <nixpkgs/nixos/lib/eval-config.nix> { | |||
# see <nixpkgs/nixos/release.nix> | |||
system = arch; | |||
modules = [ | |||
<nixpkgs/nixos/modules/installer/netboot/netboot-minimal.nix> | |||
version-module | |||
example-configuration | |||
configuration | |||
]; | |||
}; | |||
version-module = | |||
{ config, ... }: | |||
{ | |||
system.stateVersion = config.system.nixos.version; # be quiet | |||
system.nixos.tags = [ name ]; | |||
}; | |||
run-pixiecore = writeShellScript "${name}-run-pixiecore" '' | |||
exec ${pixiecore}/bin/pixiecore \ | |||
boot ${kernel} ${initrd} \ | |||
--cmdline "${cmd-line}" \ | |||
--debug --dhcp-no-bind --log-timestamps \ | |||
--port ${toString pixiecoreport} \ | |||
--status-port ${toString pixiecoreport} "$@" | |||
''; | |||
run-dnsmasq = writeShellScript "${name}-run-dnsmasq" '' | |||
exec ${dnsmasq}/bin/dnsmasq \ | |||
-d -k --no-daemon -C "${dnsmasq-conf}" "$@" | |||
''; | |||
tftp-root = linkFarm "${name}-tftp-root" ( | |||
mapAttrsToList (name: path: { inherit name path; }) { | |||
"pxelinux.cfg/default" = pxelinux-cfg; | |||
"pxelinux.0" = "syslinux/pxelinux.0"; | |||
"syslinux" = "${syslinux}/share/syslinux"; | |||
"bzImage" = kernel; | |||
"initrd" = initrd; | |||
} | |||
); | |||
dnsmasq-conf = writeText "${name}-dnsmasq-conf" '' | |||
pxe-prompt="Booting NixOS..",1 | |||
local-service=net | |||
dhcp-boot=pxelinux.0 | |||
${flip concatMapStrings proxynets (net: '' | |||
dhcp-range=${net},proxy | |||
'')} | |||
dhcp-no-override | |||
dhcp-leasefile=/dev/null | |||
log-dhcp | |||
enable-tftp | |||
tftp-port-range=6900,6999 | |||
tftp-root=${tftp-root} | |||
''; | |||
cmd-line = concatStringsSep " " ( | |||
[ | |||
"init=${build.toplevel}/init" | |||
"loglevel=${toString loglevel}" | |||
] | |||
++ optional serialconsole "console=ttyS${toString serialport},${toString serialspeed}" | |||
++ cmdline | |||
); | |||
pxelinux-cfg = writeText "${name}-pxelinux.cfg" '' | |||
${optionalString serialconsole "serial ${toString serialport} ${toString serialspeed}"} | |||
console 1 | |||
prompt 1 | |||
timeout 37 | |||
default NixOS | |||
label NixOS | |||
kernel bzImage | |||
append initrd=initrd ${cmd-line} | |||
''; | |||
build = config.config.system.build; | |||
kernel = "${build.kernel}/${kernel-target}"; | |||
kernel-target = config.pkgs.stdenv.hostPlatform.linux-kernel.target; | |||
initrd = "${build.netbootRamdisk}/initrd"; | |||
in | |||
if legacy then run-dnsmasq else run-pixiecore | |||
</nowiki> | |||
}} | |||
Usage example: | |||
<syntaxHighlight lang=bash> | |||
# Build pixiecore runner | |||
nix build -f netboot.nix -o /tmp/run-pixiecore | |||
# Build dnsmasq + pxelinux runner | |||
nix build -f netboot.nix --arg legacy true -o /tmp/run-dnsmasq | |||
# Build for some ancient system with a serial console | |||
nix build -f netboot.nix --arg name '"ancient-netboot"' -o /tmp/run-netboot \ | |||
--arg configuration 'import ./ancient-config.nix' \ | |||
--arg legacy true --arg proxynets '["10.2.1.0"]' \ | |||
--arg serialconsole true --arg serialport 3 --arg serialspeed 115200 | |||
</syntaxHighlight> | </syntaxHighlight> | ||
=== See also === | === See also === | ||
NixOS: [https://search.nixos.org/options?channel= | NixOS: [https://search.nixos.org/options?channel=23.11&from=0&size=30&sort=relevance&type=packages&query=services.pixiecore Pixiecore module]. | ||
NixOS manual: [https://nixos.org/nixos/manual/index.html#sec-booting-from-pxe PXE booting]. | NixOS manual: [https://nixos.org/nixos/manual/index.html#sec-booting-from-pxe PXE booting]. | ||
Line 76: | Line 238: | ||
<b>Note:</b> Your iPXE must be recent enough to support https:// links | <b>Note:</b> Your iPXE must be recent enough to support https:// links | ||
[[Category:Booting]] |
Latest revision as of 14:48, 30 October 2024
Building and serving a netboot image
Example
This example uses Pixiecore for hosting, which works in an ordinary network environment with an existing DHCP server.
Create file system.nix
:
let
# NixOS 22.11 as of 2023-01-12
nixpkgs = builtins.getFlake "github:nixos/nixpkgs/54644f409ab471e87014bb305eac8c50190bcf48";
sys = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
({ config, pkgs, lib, modulesPath, ... }: {
imports = [
(modulesPath + "/installer/netboot/netboot-minimal.nix")
];
config = {
## Some useful options for setting up a new system
# services.getty.autologinUser = lib.mkForce "root";
# users.users.root.openssh.authorizedKeys.keys = [ ... ];
# console.keyMap = "de";
# hardware.video.hidpi.enable = true;
system.stateVersion = config.system.nixos.release;
};
})
];
};
run-pixiecore = let
hostPkgs = if sys.pkgs.system == builtins.currentSystem
then sys.pkgs
else nixpkgs.legacyPackages.${builtins.currentSystem};
build = sys.config.system.build;
in hostPkgs.writers.writeBash "run-pixiecore" ''
exec ${hostPkgs.pixiecore}/bin/pixiecore \
boot ${build.kernel}/bzImage ${build.netbootRamdisk}/initrd \
--cmdline "init=${build.toplevel}/init loglevel=4" \
--debug --dhcp-no-bind \
--port 64172 --status-port 64172 "$@"
'';
in
run-pixiecore
Run pixiecore:
# Build pixiecore runner
nix build -f system.nix -o /tmp/run-pixiecore
# Open required firewall ports
sudo iptables -w -I nixos-fw -p udp -m multiport --dports 67,69,4011 -j ACCEPT
sudo iptables -w -I nixos-fw -p tcp -m tcp --dport 64172 -j ACCEPT
# Run pixiecore
sudo $(realpath /tmp/run-pixiecore)
# Close ports
sudo iptables -w -D nixos-fw -p udp -m multiport --dports 67,69,4011 -j ACCEPT
sudo iptables -w -D nixos-fw -p tcp -m tcp --dport 64172 -j ACCEPT
Another example
netboot.nix
{
name ? "netboot",
arch ? "x86_64-linux",
configuration ? _: { }, # --arg configuration 'import ./netboot-config.nix'
legacy ? false, # variation with pxelinux and dnsmasq for older systems
cmdline ? [ ],
loglevel ? 4,
pixiecoreport ? 64172,
proxynets ? [ "192.168.0.0" ],
serialconsole ? false,
serialport ? 0,
serialspeed ? 9600,
nixpkgs ? import <nixpkgs> { },
...
}:
with nixpkgs;
with lib;
let
example-configuration =
{ pkgs, config, ... }:
with pkgs;
{
config = {
environment.systemPackages = [
mtr
bridge-utils
vlan
ethtool
jwhois
sipcalc
netcat-openbsd
tsocks
psmisc
pciutils
usbutils
lm_sensors
dmidecode
microcom
unar
mkpasswd
ripgrep
wget
rsync
sshfs-fuse
iperf3
mc
mutt
borgbackup
rxvt_unicode.terminfo
];
# users.users.nixos.openssh.authorizedKeys.keys = [ … ];
# services.openssh = { ports = [2]; settings.PasswordAuthentication = false; };
# virtualisation.lxc.enable = true;
};
};
config = import <nixpkgs/nixos/lib/eval-config.nix> {
# see <nixpkgs/nixos/release.nix>
system = arch;
modules = [
<nixpkgs/nixos/modules/installer/netboot/netboot-minimal.nix>
version-module
example-configuration
configuration
];
};
version-module =
{ config, ... }:
{
system.stateVersion = config.system.nixos.version; # be quiet
system.nixos.tags = [ name ];
};
run-pixiecore = writeShellScript "${name}-run-pixiecore" ''
exec ${pixiecore}/bin/pixiecore \
boot ${kernel} ${initrd} \
--cmdline "${cmd-line}" \
--debug --dhcp-no-bind --log-timestamps \
--port ${toString pixiecoreport} \
--status-port ${toString pixiecoreport} "$@"
'';
run-dnsmasq = writeShellScript "${name}-run-dnsmasq" ''
exec ${dnsmasq}/bin/dnsmasq \
-d -k --no-daemon -C "${dnsmasq-conf}" "$@"
'';
tftp-root = linkFarm "${name}-tftp-root" (
mapAttrsToList (name: path: { inherit name path; }) {
"pxelinux.cfg/default" = pxelinux-cfg;
"pxelinux.0" = "syslinux/pxelinux.0";
"syslinux" = "${syslinux}/share/syslinux";
"bzImage" = kernel;
"initrd" = initrd;
}
);
dnsmasq-conf = writeText "${name}-dnsmasq-conf" ''
pxe-prompt="Booting NixOS..",1
local-service=net
dhcp-boot=pxelinux.0
${flip concatMapStrings proxynets (net: ''
dhcp-range=${net},proxy
'')}
dhcp-no-override
dhcp-leasefile=/dev/null
log-dhcp
enable-tftp
tftp-port-range=6900,6999
tftp-root=${tftp-root}
'';
cmd-line = concatStringsSep " " (
[
"init=${build.toplevel}/init"
"loglevel=${toString loglevel}"
]
++ optional serialconsole "console=ttyS${toString serialport},${toString serialspeed}"
++ cmdline
);
pxelinux-cfg = writeText "${name}-pxelinux.cfg" ''
${optionalString serialconsole "serial ${toString serialport} ${toString serialspeed}"}
console 1
prompt 1
timeout 37
default NixOS
label NixOS
kernel bzImage
append initrd=initrd ${cmd-line}
'';
build = config.config.system.build;
kernel = "${build.kernel}/${kernel-target}";
kernel-target = config.pkgs.stdenv.hostPlatform.linux-kernel.target;
initrd = "${build.netbootRamdisk}/initrd";
in
if legacy then run-dnsmasq else run-pixiecore
Usage example:
# Build pixiecore runner
nix build -f netboot.nix -o /tmp/run-pixiecore
# Build dnsmasq + pxelinux runner
nix build -f netboot.nix --arg legacy true -o /tmp/run-dnsmasq
# Build for some ancient system with a serial console
nix build -f netboot.nix --arg name '"ancient-netboot"' -o /tmp/run-netboot \
--arg configuration 'import ./ancient-config.nix' \
--arg legacy true --arg proxynets '["10.2.1.0"]' \
--arg serialconsole true --arg serialport 3 --arg serialspeed 115200
See also
NixOS: Pixiecore module.
NixOS manual: PXE booting.
netboot.xyz
There is now official netboot.xyz support. Just select NixOS from Linux installs and you should be ready to go.
Note: Your iPXE must be recent enough to support https:// links