Skip to content

Latest commit

 

History

180 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lan-ipxe

A personal homelab network-boot environment: iPXE menu generation for live-booting Linux distros over the LAN, a custom Arch Linux live image, a Windows 11 iSCSI-boot image builder, idempotent workstation setup scripts, and Mellanox NIC firmware tooling.

Architecture

Three roles, three sets of scripts:

Host Role Runs
PXE server (Fedora Linux, 192.168.1.11) TFTP (/srv/tftp), HTTP on :81 (/srv/http/pxe), iSCSI target (LIO/targetcli) update-pxe-images.sh, build_archiso.sh
Windows build machine Builds the Win11 iSCSI boot image build_win11pxe.ps1 + the Get-*.ps1 scrapers
Clients UEFI/BIOS PXE boot into the generated menu

Boot flow: DHCP → TFTP (ipxe.efi / undionly.kpxe) → default.ipxe menu → live boot from public mirrors / netboot.xyz assets / local HTTP artifacts / Windows 11 via iSCSI sanboot.

Components

PXE menu generator — update-pxe-images.sh

Scrapes the Purdue PLUG mirror for the current Debian, Fedora, Rocky, and Ubuntu LTS live ISOs (x86_64 and ARM64), resolves matching netboot.xyz kernel/initrd release assets via the GitHub API, and generates /srv/tftp/default.ipxe with per-distro menu entries plus Clonezilla, netboot.xyz, and an iPXE shell. Finishes with a HEAD-check pass over the embedded URLs.

Feature toggles (edit the variables at the top of the script):

  • ENABLE_TFTP_BOOTSTRAP — download iPXE binaries (snponly.efi saved as ipxe.efi, undionly.kpxe, ARM64 EFI) into the TFTP dir.
  • ENABLE_LOCAL_ARCH — copy a local Arch kernel/initramfs from /srv/arch and add an NBD-root boot entry.
  • ENABLE_CUSTOM_ARCHISO — add menu entries for the custom archiso image (below).
  • ENABLE_WIN11_PXE — add the Windows 11 iSCSI sanboot entry.

If /srv/http/pxe or /srv/tftp is not writable (e.g. run without root), the script falls back to ./pxe_test/ — useful as a dry run.

Windows 11 iSCSI boot ("Win2Go") — build_win11pxe.ps1

Run as Administrator with PowerShell 7 on a Windows machine:

.\build_win11pxe.ps1 -IsoPath .\Win11_25H2_English_x64.iso -OutPath .\win11_netboot.vhdx -ImageIndex 6 [-Drivers] [-Updates]

Creates a dynamic VHDX (GPT: ESP / MSR / NTFS), applies the Windows image with DISM, writes boot files with bcdboot, then edits the offline SYSTEM/SOFTWARE hives: promotes iSCSI/NIC/storage services to boot-start, sets the SAN policy, disables BitLocker auto-encryption, injects LabConfig hardware-check bypasses and BypassNRO, and drops an unattend.xml (local lan admin account with autologon) plus a SetupComplete.cmd that disables supported NIC sleep features without restarting adapters. The helper logs errors to %SystemRoot%\Logs\DisableNetPower.log; SetupComplete logs to DisableNetPower-setup.log in the same directory. OEM-keyed editions can skip SetupComplete, so confirm execution on the target.

  • -Drivers runs every NIC/Wi-Fi Get-*Drivers.ps1 scraper in parallel (the Get-*GraphicsDrivers.ps1 shims are excluded — see -GraphicsDrivers) and injects the results with DISM /Add-Driver.
  • -DriverPath .\drivers\boot-nic injects extracted, tested driver packages from a local directory (recursively) or an individual INF. Multiple paths are allowed. Use it instead of -Drivers to avoid changing the NIC package on each catalog refresh; it can still be combined with -GraphicsDrivers. The original driver directory is never deleted. DISM servicing failures stop the build.
  • -GraphicsDrivers Intel|AMD|NVIDIA|All additionally injects GPU display drivers (also catalog-sourced) into the same image. GPU CABs are large (~0.6–1.2 GB each), so it is opt-in and separate from -Drivers; All injects the ~3–5 GB union of all three vendors, so prefer a single vendor matching the target machine. GPU drivers are post-boot-only (a GPU never serves iSCSI boot), so they get plain DISM /Add-Driver with no boot-start promotion. A bare INF install yields a fully accelerated driver (incl. the OpenGL/Vulkan/OpenCL/D3D and CUDA/NVENC runtimes); the vendor control-panel apps (NVIDIA App, AMD Adrenalin, Intel Graphics Software — all Microsoft Store) are not installed, and Radeon Pro cards get the base WHQL driver, not the ISV-certified PRO Edition. x64 only (discrete GPUs have no ARM64 Windows driver; Qualcomm Adreno is not on the catalog). The same shims run standalone on a live system (-Installpnputil).
  • -Updates runs Get-Win11CumulativeUpdates.ps1 and injects the latest cumulative update (with checkpoint prerequisites) via folder-based DISM /Add-Package.

Serving the image: convert the VHDX to a raw image first (qemu-img convert -f vhdx -O raw win11_netboot.vhdx win11.img) and expose it as an LIO/targetcli backstore behind iqn.2026-02.lan.pxe:win11. LIO serves file bytes raw — it does not parse the VHDX container. The targetcli configuration itself is not versioned in this repo.

Boot NIC (-BootAdapterGuid): optionally run the undocumented DISM /Add-NetAdapter operation. The adapter must be present with a working driver in the Windows session running this builder. A GUID from another machine or a previous WinPE session is not a portable hardware identifier. Invalid/missing host adapters fail validation before a VHDX is created; a failed requested DISM operation stops the build.

# Run on the build host; select the intended NIC rather than the first result:
Get-CimInstance Win32_NetworkAdapter | Select-Object GUID,Name,ServiceName
.\build_win11pxe.ps1 -IsoPath .\Win11_25H2_English_x64.iso -DriverPath .\drivers\boot-nic -BootAdapterGuid '{GUID}'

GUID-less builds remain available with boot-NIC preparation marked unverified. Windows can enumerate new hardware during first boot; missing pre-existing PnP entries alone do not prove failure. Driver staging and the fallback service table also do not prove iSCSI first-boot compatibility. Different .sys binaries with the same filename now stop fallback service creation instead of selecting the first file found; byte-identical duplicates are accepted. The fallback still cannot reproduce arbitrary INF/WDF/device installation requirements.

Output and diagnostics: builds use a unique temporary VHDX beside -OutPath. The previous output is replaced only after image preparation, registry hive unloads and image dismounts succeed. Failed builds retain their temporary VHDX for inspection; a hive-unload failure deliberately leaves that disk attached. Each run writes <OutPath>.<build-id>.build.json and a DISM log alongside the output. The report includes source/serviced Windows versions, NIC package versions, native DISM results, service paths, start overrides and warnings. Complete means the build and cleanup succeeded, not that hardware boot was tested; ColdBootValidated remains false. Keep the matching report when copying an image. The large failed temporary images can be removed after inspection and successful hive/disk cleanup.

PXE interface selection: the Windows menu entry tries interfaces net0 through net63 individually, preserving existing IPv4 settings and using DHCP only when an interface lacks an address. A successful iSCSI attachment identifies the NIC whose MAC supplies the initiator IQN. For ordinary subnet/default-gateway routing, it first tests attachment without a gateway; failure restores the gateway and tries routed access. DHCP option 121 routes bypass this workaround because a no-gateway probe would not establish on-link access. Each client's ACL must map LUN 0 to a separate writable backstore; unique initiator IQNs alone do not isolate NTFS volumes. The entry closes other iPXE interfaces to prevent ambiguous routing.

Driver/update scrapers (Microsoft Update Catalog):

Script Covers
Get-IntelEthernetDrivers.ps1 Intel I210/I219/I225/I226, X540/X550, X710, E810, AVF
Get-RealtekEthernetDrivers.ps1 RTL8125/8126/8127/8168 PCIe, RTL8153/8156/8157 USB
Get-MarvellEthernetDrivers.ps1 Aquantia/Marvell AQC107/AQC113 PCIe, AQC111U USB
Get-IntelWiFiDrivers.ps1 Intel Wi-Fi 6/6E/7 (post-boot convenience)
Get-MediatekWiFiDrivers.ps1 MediaTek MT79xx Wi-Fi (post-boot convenience)
Get-QualcommWiFiDrivers.ps1 Qualcomm WCN/FastConnect Wi-Fi (post-boot convenience)
Get-IntelGraphicsDrivers.ps1 Intel Arc / Iris Xe / UHD GPU (post-boot convenience)
Get-NvidiaGraphicsDrivers.ps1 NVIDIA GeForce + RTX/Quadro GPU (post-boot convenience)
Get-AmdGraphicsDrivers.ps1 AMD Radeon RX + Radeon Pro GPU (post-boot convenience)
Get-Win11CumulativeUpdates.ps1 Latest monthly CU + checkpoint chain + SSU per Windows version

Status: offline build hardening is implemented; first boot, OOBE and subsequent cold boots still require testing on the intended NIC, firmware and Windows build. There is no automatic WinPE provisioning stage. If offline NIC preparation is insufficient, Setup over an iBFT-attached LUN remains an alternative.

Custom Arch live image — build_archiso.sh

Run as root on an Arch system with archiso installed. Clones the releng profile, applies customizations (local pacman.conf, zstd squashfs, archlinux-custom ISO name, a large multi-desktop package set), and injects a systemd generator + configure-desktop.sh that enable exactly one desktop environment per boot based on the desktop= kernel argument (gnome, kde, xfce, sway, enlightenment — selected by the corresponding iPXE menu entry). Outputs the ISO plus extracted vmlinuz-linux / initramfs-linux.img / airootfs.sfs into /srv/http/pxe/archiso (or ./archiso when not on the server) for HTTP PXE boot.

Workstation provisioning — setup-*-workstation.*

One convergent script per platform. Package-manager refreshes and updates normally run on each pass (including Arch's full pacman -Syu and AUR update). They replaced the earlier comtrya manifests; comtrya is unmaintained upstream. Run from any directory: the Linux scripts resolve their config payloads (files/) relative to their own location.

macOS now has setup-macos-workstation.sh, targeting native Apple Silicon on macOS 26 and macOS 27. Its default core profile includes Linux CLI parity, wget and Go, Python/Rust, everyday apps and the portable Bash configuration. Full adds large toolchains, Java/Maven/Gradle, stable Android SDK/build-tools/NDK, optional apps and games. All Store apps and supplemental game-data downloads are excluded. Full prints the per-engine data directories to populate manually.

Start with ./setup-macos-workstation.sh --dry-run or --check; both are offline and read-only. Apply as the console user with no arguments for core, or --profile full. --no-upgrade retains installed versions; Xcode selection, Sharing and power settings each require their explicit --with-* flag. Exit codes are 0 for satisfied/dry-run, 1 for failures and 2 for drift/manual work. See the macOS guide, approved plan and package comparison for ownership, exclusions, manual steps and validation limits. Initial validation uses mocked tests and read-only previews; a clean-machine installation smoke test remains outstanding.

Fedora and Arch install Balun alongside Tributary (balun from jmsqrd/balun COPR on Fedora, balun-bin from the AUR on Arch). Both also install Cockpit with file management, package updates, Podman containers, and storage/LVM support, and start cockpit.socket for access at https://localhost:9090.

  • setup-arch-workstation.sh — run as your normal user; sudo is used for the privileged steps (AUR builds refuse to run as root). Requires an existing GRUB installation, safely enables [multilib], runs pacman -Syu, installs the official package set and detected Intel/AMD microcode, installs dotfiles/system config and zram policy from files/, explicitly generates and validates every dracut image before removing mkinitcpio, then enables services and GDM settings. AUR work is last: a self-bootstrapped yay interactively presents PKGBUILD diffs, updates installed AUR packages (including VCS/devel packages), and installs the requested set. Arch's signed repositories provide Code OSS, OpenCode, Codex CLI, and Zed; the AUR supplies Claude Code and the native Antigravity 2.0+ desktop/CLI. The script removes VSCodium, Antigravity IDE, and any installed Antigravity 1.x package before installing their replacements. The package selection intentionally includes Intel/AMD graphics support and NVIDIA open modules for both linux and linux-lts. It installs the AUR r8152-dkms package only below kernel 7.2; on 7.2+ it purges that out-of-tree driver, regenerates the initramfs, and reports when a loaded out-of-tree module requires a reboot to activate the in-tree driver. GNOME uses Vitals for sensors, Dash to Dock from the AUR, and the bundled System Monitor extension with libgtop.
  • setup-fedora-workstation.sh — run as your normal user; Fedora 41+ (dnf5). Adds the signed third-party repos (files/etc/yum.repos.d/, the Tributary/Balun coprs, RPM Fusion, Microsoft VS Code, Chrome, Claude Code, sing-box; PowerShell/NVIDIA/Steam repos on x86_64), installs the dnf and flatpak sets (plus the x86_64-only 32-bit/Steam extras), applies available DNF/Flatpak updates, and installs Zed plus native AI tools. Both x86_64 and aarch64 are supported, including Fedora Asahi's 16K kernel variant. DNF reconciles the package/group set directly with visible output and automatic confirmation; there is no separate user-cache group query to block on hidden repository-key prompts. Chrome and GitHub CLI are installed on both architectures; ARM64 PowerShell uses Microsoft's checksum-verified release archive. Installs dnf5-plugin-automatic and enables dnf5-automatic.timer immediately, with the controller setup's apply_updates = yes and reboot = when-needed policy in /etc/dnf/automatic.conf. Antigravity 2.0+ and its CLI, OpenCode, and Zed resolve the latest stable native artifacts and their published checksums on each run; Codex uses OpenAI's checksum-verifying current-release installer; Claude Code uses Anthropic's signed RPM repository. The abandoned unsigned Antigravity 1.x RPM/repository, its exact script-managed IDE settings, and VSCodium are removed, while customized settings or repo files are preserved (and retired repos disabled). The script also installs a deliberately fixed, checksum-pinned Ookla speedtest CLI. Below kernel 7.2 it resolves the latest stable r8152 USB NIC driver release to one upstream commit per run and installs it via DKMS; on 7.2+ it purges the out-of-tree driver, reconciles every installed-kernel initramfs, and reports when a loaded out-of-tree module requires a reboot to activate the in-tree driver. The script then applies dotfiles, zram policy, services, and GDM settings. Secure Boot hosts are warned when the DKMS MOK still needs enrollment.
  • setup-win11-workstation.ps1 — run from an elevated PowerShell (5.1 is enough): powershell -ExecutionPolicy Bypass -File .\setup-win11-workstation.ps1. Sets up OpenSSH Server via enable-openssh-win11.ps1, then installs the winget package set. Every managed package is checked for upgrades on every run unless explicitly marked presence-only; the deliberately fixed Speedtest CLI is currently the only such package. The highest stable Python 3 minor-package channel is resolved from WinGet rather than hard-coded. Antigravity IDE and VSCodium are removed, with Microsoft VS Code kept as the supported Windows editor. One winget export snapshot decides the remaining state; --include-unknown keeps versionless registrations from silently freezing, so those vendor installers may run again. "Already installed" / "reboot required" results count as success, and any other failure is reported at the end (exit code 1) without stopping the run. -HyperV additionally enables the supported Windows optional feature on Pro, Enterprise, or Education; Windows 11 Home is rejected.

Missing package-set entries are installed and existing Arch/AUR packages are updated. Config files are rewritten only when their content, type, mode, or ownership differs; follow-ups (grub-mkconfig, sysctl, dconf update, DKMS/dracut builds) run only when their inputs or validation require them. Workstation zram uses zstd, priority 100, and min(RAM, 8 GiB). Linux systemd services are enabled, not started, and come up on the next boot. The Windows OpenSSH helper starts sshd immediately and opens Microsoft's standard inbound TCP/22 firewall rule on all profiles; narrow that rule separately if the workstation's policy requires it.

Windows helpers (called by setup-win11-workstation.ps1, also usable standalone):

  • enable-openssh-win11.ps1 — installs the OpenSSH Server capability, starts/enables sshd, ensures the firewall rule, sets PowerShell as the default SSH shell.
  • enable-hyperv-win11.ps1 — enables Hyper-V through the supported optional-feature API on eligible Windows editions and refuses the unsupported Windows 11 Home hack.

files/ — config payloads

Dotfiles and system config consumed by the workstation setup scripts: bashrc, vimrc, grub defaults, etc/locale.conf, etc/sysctl.d/99-inotify.conf, etc/systemd/zram-generator.conf, etc/cron.daily/pacman-update (unattended Arch updates + reboot scheduling), etc/dnf/automatic.conf (Fedora automatic updates + reboot when needed), etc/dconf/db/gdm.d/10-font-settings, Fedora repo definitions under etc/yum.repos.d/, and the Fedora Antigravity desktop entry under usr/share/applications/. etc/pacman.conf is kept for reference only — the Arch script deliberately does not install it.

Mellanox firmware tool — mlnx-fw-flash-update.sh

Interactive detector/cross-flasher for ConnectX-3 through ConnectX-7 NICs. Queries devices with mstflint, downloads stock NVIDIA firmware, flashes (including OEM→stock cross-flash with -allow_psid_change after explicit confirmation), and configures UEFI/legacy boot ROM options via mstconfig. Requires root, mstflint, and pciutils. Firmware flashing is inherently risky — read every prompt.

Typical run order

  1. One-time: point DHCP at the TFTP server (ipxe.efi for UEFI, undionly.kpxe for BIOS); set ENABLE_TFTP_BOOTSTRAP=true for the first run to fetch the binaries.
  2. Periodically (cron or manual): ./update-pxe-images.sh on the server to refresh distro versions and regenerate the menu.
  3. Optional: sudo ./build_archiso.sh to rebuild the custom Arch image; enable ENABLE_CUSTOM_ARCHISO.
  4. Optional: build the Win11 VHDX on the Windows machine, convert to raw, configure the iSCSI target, enable ENABLE_WIN11_PXE.
  5. After installing an OS on a workstation: run the matching setup-*-workstation.* script (re-run any time to converge).

Notes

  • update-pxe-images.sh writes to the live server paths and needs root; pass --test (or DRY_RUN=true) to generate into ./pxe_test/ instead. It publishes default.ipxe atomically and keeps a .bak of the previous menu. Set GITHUB_TOKEN to avoid the 60-req/hr unauthenticated GitHub API rate limit.
  • CI discovers every Bash and PowerShell/data file instead of relying on a hand-kept list. It runs actionlint on workflows, Bash syntax + ShellCheck, PowerShell parsing + PSScriptAnalyzer with a no-growth warning baseline, imports every .psd1, and parses/tests the Windows workstation helpers under both PowerShell Core and an actual Windows PowerShell 5.1 runner. It also runs the catalog, WinGet-inventory, Hyper-V state, file-convergence, Arch kernel-reboot, and zram-generator tests under tests/. The test scripts can be run locally; the zram test requires systemd-zram-generator and the static checks require ShellCheck and PSScriptAnalyzer 1.25.0.
  • Build artifacts (*.vhdx, *.iso, *.img, *.raw, pxe_test/, archiso/, custom_archiso/) are gitignored.
  • Server address/ports, mirror URLs, and the iSCSI IQN namespace (iqn.2026-02.lan.pxe) are currently hard-coded constants at the top of update-pxe-images.sh and inside the Win11 stanza.
  • The Win11 image intentionally trades security for LAN convenience (blank-password autologon admin, hardware-check bypasses, no CHAP on the target) — do not expose any of this beyond a trusted network.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages