This is the multi-page printable view of this section. Click here to print.
Operating Systems
- 1: Debian
- 1.1: Packaging
- 2: NetBoot
- 2.1: Boot Server
- 2.2: menu
- 2.3: netboot.xyz
- 2.4: menu-old
- 2.5: windows
- 2.6: Legacy
- 3: Windows
- 3.1: Server Core
- 3.2: Windows Zero Touch Install
1 - Debian
Random guy on the Internet:
Fun fact: Debian’s pronunciation in Chinese means poo
Response:
Wrong, at least in Mandarin. Poop is ‘dà biàn‘’. It’s two words with a ah sound instead of an eh sound.
That back and forth pretty much sums up the rest of the internet.
1.1 - Packaging
Building Debian packages is the first-half of distributing software in their ecosystem. In private use, it’s how you can build it in one place and and install it somewhere else. Keeps you from installing a bunch of build-tools (which can get big) everywhere.
Here’s an example with libTorrent and rTorrent.
LibTorrent
I’ll use the example of libtorrent here.
Prerequisites
# Install the deb build basics, plus a couple things the source needs
sudo apt install git debhelper devscripts dh-make libcppunit-dev pkg-config
# We want the latest release so check GitHub as needed
git clone https://github.com/rakshasa/libtorrent --branch v0.16.6 --depth 1 libtorrent-0.16.6
# If you cloned head for some reason, you can set the package version explicitly
# dh_make --createorig -s -y -p libtorrent_0.16.6
dh_make --createorig -s -y
# The readme says it needs (in addition to make and autoconf) curl-libcurlpp-dev
sudo apt install libcurlpp-dev
# Create the Debian template files
cd libtorrent-*
dh_make --createorig -s -y
Edit the control file with the build details. This git project will actually build three packages;
| libtorrent36 | The main package you’re building |
| libtorrent | The source package. The other packages will use this when they build |
| libtorrent-dev | The development files for anyone else building with libTorrent |
Notice that we put 36 at the end of the package. The the Debian Policy Manual says to add the SONAME (shared object name) to the end to keep things separate.
You can get that from the LibTool number in the autoconf file: grep LIBTORRENT_CURRENT= libtorrent*/configure. You can consult the Debian Library Packaging Guide for more info.
vi debian/control
Source: libtorrent
Section: libs
Priority: optional
Maintainer: you <[email protected]>
Rules-Requires-Root: no
Build-Depends: debhelper-compat (= 13),
pkg-config,
libtool,
automake,
autoconf,
libcppunit-dev,
libcurlpp-dev,
libcurl4-openssl-dev,
libssl-dev,
zlib1g-dev
Standards-Version: 4.7.2
Homepage: https://github.com/rakshasa/libtorrent
Package: libtorrent36
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: BitTorrent library with focus on high performance (Rakshasa version)
libtorrent is a BitTorrent library written in C++ with a focus on
high performance and good code. This package contains the shared
library (SONAME 36).
Package: libtorrent-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libtorrent36 (= ${binary:Version}),
libsigc++-2.0-dev,
libssl-dev,
${misc:Depends}
Description: development files for libtorrent (Rakshasa version)
This package contains the header files and static libraries for
developing applications that use Rakshasa's libtorrent.
Add a rule to handle the lack of a Makefile and make sure it looks in tmp for files it will need between the packages
vi debian/rules
...
...
%:
dh $@
# This override runs BEFORE the automatic configuration step
override_dh_autoreconf:
autoreconf -ivf
dh_autoreconf
# dh_make generated override targets.
# This is an example for Cmake (see <https://bugs.debian.org/641051>).
# Force installation to debian/tmp so multiple packages can pick from it
override_dh_auto_install:
dh_auto_install --destdir=debian/tmp
Create some install files so the packager knows what output files go with what package
vi debian/libtorrent36.install
usr/lib/*/libtorrent.so.36*
vi debian/libtorrent-dev.install
usr/include/torrent/*
usr/lib/*/libtorrent.so
usr/lib/*/pkgconfig/libtorrent.pc
The project builds a ’libtool archive’ file that the packager frowns upon. Add a rule so it knows explicitly that we are going to package it.
echo "usr/lib/*/libtorrent.la" > debian/not-installed
Run the build
debuild -us -uc
Install with
sudo dpkg -i libtorrent36_0.16.6-1_amd64.deb libtorrent-dev_0.16.6-1_amd64.deb
Troubleshooting
You may need to clean up, add an ignore file and re-build
# Create a ignore file so the builder is OK with the directory have a previous build product in it
vi debian/source/options
extend-diff-ignore = "(^|/)(Makefile\.in|config\.h\.in|scripts/.*\.m4|configure|aclocal\.m4|compile|depcomp|install-sh|missing|ltmain\.sh|config\.sub|config\.guess)$"
debian/rules clean
debuild -us -uc
RTorrent
You’ll need libTorrent, but hopefully you’ve just built it. If you haven’t installed it, do that now.
Note: You probably want XPC enabled as per https://github.com/rakshasa/rtorrent-doc/blob/master/RPC-Setup-XMLRPC.md. We’ll add a configure flag for that.
# Check the current version before you clone
git clone https://github.com/rakshasa/rtorrent --branch v0.16.6 --depth 1 rtorrent-0.16.6
sudo apt install libncurses-dev
# Create the Debian template files
cd rtorrent-*
dh_make --createorig -s -y
Change the debian/control file to be
Source: rtorrent
Section: net
Priority: optional
Maintainer: you <[email protected]>
Rules-Requires-Root: no
Build-Depends:
debhelper-compat (= 13),
pkg-config,
libtool,
automake,
autoconf,
libtorrent-dev,
libncursesw5-dev,
libcurl4-openssl-dev,
libcppunit-dev,
libxmlrpc-c++9-dev
Standards-Version: 4.7.2
Homepage: https://github.com/rakshasa/rtorrent
#Vcs-Browser: https://salsa.debian.org/debian/rtorrent
#Vcs-Git: https://salsa.debian.org/debian/rtorrent.git
Package: rtorrent
Architecture: any
Depends:
${shlibs:Depends},
${misc:Depends},
adduser,
tmux
Description: ncurses BitTorrent client based on libtorrent
rtorrent is a BitTorrent client that uses ncurses and aims to be a
lean, yet powerful terminal application.
Make the debian/rules like this:
#!/usr/bin/make -f
# See debhelper(7) (uncomment to enable).
# Output every command that modifies files on the build system.
#export DH_VERBOSE = 1
# See FEATURE AREAS in dpkg-buildflags(1).
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
# See ENVIRONMENT in dpkg-buildflags(1).
# Package maintainers to append CFLAGS.
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
# Package maintainers to append LDFLAGS.
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
%:
dh $@
# Generate the configure script before building
override_dh_autoreconf:
autoreconf -ivf
dh_autoreconf
# dh_make generated override targets.
# This is an example for Cmake (see <https://bugs.debian.org/641051>).
#override_dh_auto_configure:
# dh_auto_configure -- \
# -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH)
override_dh_auto_configure:
dh_auto_configure -- --with-xmlrpc-c
Include a service unit file
vi debian/rtorrent.service
[Unit]
Description=rTorrent System Service
After=network.target
[Service]
Type=forking
User=rtorrent
Group=rtorrent
WorkingDirectory=/var/lib/rtorrent
# Capture the stdin and out to send to the journal
ExecStart=/usr/bin/tmux new-session -d -s rtorrent 'rtorrent 2>&1'
StandardOutput=journal
StandardError=journal
SyslogIdentifier=rtorrent
ExecStop=/usr/bin/tmux send-keys -t rtorrent C-q
TimeoutStopSec=30
Restart=on-failure
[Install]
WantedBy=multi-user.target
Add a template file.
vi debian/rtorrent.rc
# rTorrent System Configuration
directory.default.set = /var/lib/rtorrent/downloads
session.path.set = /var/lib/rtorrent/.session
# Set port statically for VPN incomming
network.port_range.set = 50000-50000
network.port_random.set = no
protocol.encryption.set = allow_incoming,try_outgoing,enable_retry
dht.mode.set = auto
# Adjust as needed for a remote web server if used. But secure thoroughly as
# this interface allows for remote code execution (I've read)
network.scgi.open_port = 0.0.0.0:8080
# Use a unix domain socket if possible.
# Make sure the webserver and rtorrent share a group and set permissions for that
#network.scgi.open_local = /home/user/rtorrent/rpc.socket
#schedule2 = scgi_permission,0,0,"execute.nothrow=chmod,\"g+w,o=\",/home/user/rtorrent/rpc.socket"
# Redirect all 'info', 'error', and 'critical' logs to the tmux screen (stdout) if desired.
log.add_output = "info", "stdout"
log.add_output = "error", "stdout"
log.add_output = "critical", "stdout"
Create debian/install so the template file is included
vi debian/install
debian/rtorrent.rc etc/
Create a post install to create a user and dirs
vi debian/postinst
#!/bin/sh
set -e
if [ "$1" = "configure" ]; then
# Create system user if missing
if ! getent passwd rtorrent >/dev/null; then
adduser --system --group --home /var/lib/rtorrent \
--shell /bin/false --quiet rtorrent
fi
# Create required directories
mkdir -p /var/lib/rtorrent/downloads
mkdir -p /var/lib/rtorrent/.session
# Link the global config to the user's home
if [ ! -f /var/lib/rtorrent/.rtorrent.rc ]; then
ln -sf /etc/rtorrent.rc /var/lib/rtorrent/.rtorrent.rc
fi
# Fix permissions
chown -R rtorrent:rtorrent /var/lib/rtorrent
fi
#DEBHELPER#
exit 0
Make it executable
chmod +x debian/postinst
Build as before
debuild -us -uc
And install
sudo dpkg -i rtorrent_0.16.6-1_amd64.deb
Start and attach with
sudo -u rtorrent tmux -L rtorrent attach -t rtorrent
Note:
To install on other servers
sudo apt install ./libtorrent* ./rtorrent_0.16.6-1_amd64.deb
2 - NetBoot
Most computers come with something called firmware. This is just software written semi-permanently on a chip in the PC. This is the first thing loaded at power-on. Modern versions include a GUI interface to change settings and test hardware. But it’s most important job is to load the main operating system from storage.
The main OS is normally loaded from a local disk, but it can also be loaded over the network. There are usually two goals;
- Provision New Systems
- Thin Clients or Disk-less Workstations
Provisioning New Systems
This saves you from carrying around a boot disk. But most importantly, it allows unattended deployment. You can remotely re-image workstations without a tech on-site. As great as this sounds, it’s not easy and requires solid user management to make it useful. So there hasn’t been wide adoption outside of line-of-business situations. Though it does make updating install sources easier.
Thin or Disk-less Stations
This seems like a good idea, and it works at scale. But the cost of a thin client is usually more than an equivalent PC so it’s mostly limited to line-of-business again. And the cost of storage is so cheap that a technical investment in netboot rarely pays off. But it can work when repurposing old PCs with worn out drives for kiosk use.
Boot Server
Either way, you’ll need a boot server
2.1 - Boot Server
NetBoot systems rely on the network DHCP (Dynamic Host Configuration Protocol) to request info on how to load an OS. So your first step is a DHCP server. Since you probably already have one, and would prefer not to break it while testing out netboot, let’s use a feature that allows the netboot server to work alongside your existing DHCP server; PXE Proxy
This server adds additional DHCP services and HTTP/TFTP related to PXE without interfering with your main IP allocation services.
Installation
dnsmasq supports both DHCP, for telling clients about itself, and TFTP, for getting the files to them. We’ll also add lighttpd for HTTP support. That protocol is much faster for systems that can use it.
sudo apt install dnsmasq lighttpd
Configuration
Server
Use a static IP and a hostname for the server that resolves correctly. We use the server name netboot.lan.
Lighttpd
No configuration is needed. It serves up content from /var/www/html folder by default.
Dnsmasq
When configured in proxy dhcp mode: “…dnsmasq simply provides the information given in –pxe-prompt and –pxe-service to allow netbooting”. So only certain settings are available. This is a bit vague, but testing reveals that you must set the boot file name with the dhcp-boot directive, rather than setting it with the more general DHCP option ID 67, for example.
# Add a file in the drop folder
sudo vi /etc/dnsmasq.d/netboot.conf
# Disable DNS
port=0
# Set for DHCP PXE Proxy mode. It will only answer request from this range.
dhcp-range=192.168.1.0,proxy
# Respond to clients that use 'HTTPClient' or 'PXEClient' to identify themselves.
dhcp-pxe-vendor=PXEClient,HTTPClient
# Send the BOOTP information for the clients using HTTP
dhcp-boot="http://netboot.lan/debian.iso"
# Specify a boot menu option for PXE clients. If there is only one, it's booted immediately.
pxe-service=x86-64_EFI,"Network Boot"
pxe-service=x86-64_EFI,"Network Boot (UEFI)",boot/bootmgfw.efi
pxe-service=x86-64_EFI,"iPXE (UEFI)", "ipxe.efi"
# Enable TFTP for the PXE clients.
enable-tftp
tftp-root=/var/www/html
# Restart DNSMasq to enable
sudo systemctl restart dnsmasq.service
Installation Source
The simplest thing possible is to just drop an ISO on the web server. Take a look at the current debian ISO (the numbering changes) at https://www.debian.org/CD/netinst and download.
sudo wget https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-13.1.0-amd64-netinst.iso -P /var/www/html -O debian.iso
Client
Clients may need to have the “Enable UEFI Network Stack” enabled in thier firmware setup. The debian boot loader is signed and works with secure boot.
Next Steps
You didn’t get any choices when booting. A menu with some options is a good thing to add next.
Troubleshooting
dnsmasq
A good way to see what’s going on is to enable dnsmasq logging.
# Add these to the dnsmasq config file
log-queries
log-dhcp
# Restart and follow to see what's happening
sudo systemctl restart dnsmasq.service
sudo journalctl -u dnsmasq -f
If you’ve enabled logging in dnsmasq and it’s not seeing any requests, you may need to look at your networking. Some virtual environments suppress DHCP broadcasts when they are managing the IP range. You can also have an issue with the client resolving DNS. Test with IPs if needed.
PXEClient:Arch:00007:UNDI:003016
If you see this the client isn’t attempting HTTPBoot. Dells specifically lack this feature even circa 2019
lighttpd
You can also see what’s being requested from the web server if you enable access logs.
cd /etc/lighttpd/conf-enabled
sudo ln -s ../conf-available/10-accesslog.conf
sudo systemctl restart lighttpd.service
sudo cat /var/log/lighttpd/access.log
Notes
In addition to ISOs, you can also specify .efi binaries like grubx64.efi. This allows you to extract the files and add a pre-seed. Some distributions support this, though Debian itself may have issues.
2.2 - menu
For a simple menu use the pxe-service built into dnsmasq.
Configuration
dnsmasq
Configure dnsmasq to serve up the ipxe.efi binary for both types of clients.
# add to the settings from the last example
pxe-service=X86-64_EFI,"Network Boot UEFI x86_64",grub/grubx64.efi
2.3 - netboot.xyz
You can add netboot.xyz to your iPXE menu to run Live CDs, OS installers and utilities they provide. This can save a lot of time and their list is always improving.
Installation
You’re going to connect to the web for this, so there’s nothing to install. You can download their efi bootloader manually if you’d like to keep things HTTPS, but they update it regularly so you may fall behind.
Configuration
Autoexec.ipxe
Add a menu item to your autoexec.ipxe. When you select it, iPXE will chainload (in their parlance) the netboot.xyz bootloader.
#!ipxe
echo ${cls}
:MAIN
menu Local Netboot Menu
item --gap Local Network Installation
item WINDOWS ${space} Windows 11 LTSC Installation
item DEBIAN ${space} Debian Installation
item --gap Connect to Internet Sources
item NETBOOT ${space} Netboot.xyz
choose selection && goto ${selection} || goto ERROR
:WINDOWS
echo Some windows things here
sleep 3
goto MAIN
:DEBIAN
dhcp
imgfree
set base http://netboot/debian-installer/amd64
kernel ${base}/linux
initrd ${base}/initrd.gz
boot || goto ERROR
:NETBOOT
dhcp
chain --autofree http://boot.netboot.xyz || goto ERROR
:ERROR
echo There was a problem with the selection. Exiting...
sleep 3
exit
Local-vars
Netboot.xyz detects that it’s working with a Proxy PXE server and behaves a little differently. For example, you can’t insert your own local menu.ipxe. One helpful addition is a local settings file to speed up boot.
sudo vi /var/www/html/local-vars.ipxe
#!ipxe
set use_proxydhcp_settings true
Operation
You can choose the new menu item and load netboot.xyz. It will take you out the web for more selections. Not everything will load on every client, of course. But it gives you a lot of options.
Next Steps
We glossed over how to install Windows. That’s a useful item.
Troubleshooting
Wrong TFTP Server
tftp://192.168.0.1/local-vars.ipxe....Connection timed out
Local vars file not found... attempting TFTP boot...
DHCP proxy detected, press p to boot from 192.168.0.2...
If your boot client is attempting to connect to the main DHCP server, that server is probably sending value next server: 192.168.0.1 in it’s packets. This isn’t a DNS option per say, but it affects netboot. Dnsmasq does this though Kea doesn’t.
sudo systemctl -u dnsmasq -f
...
...
next server: 192.168.0.1
...
...
The boot still works, it’s just annoying. You can usually ignore the message and don’t have to hit ‘p’.
Exec Format Error
Could not boot: Exec format error (https://ipxe.org/2e008081)
You may see this flash by. Check your menus and local variables file to make sure you’ve in included the #!pxe shebang.
No Internet
You can also host your own local instance.
2.4 - menu-old
It would be useful to have some choices when you netboot. You can use the pxe-service built into dnsmasq but a more flexible option is the menu system provided by the iPXE project.
Installation
Set up a http/pxe net-boot server if you haven’t already.
Configuration
dnsmasq
Configure dnsmasq to serve up the ipxe.efi binary for both types of clients.
# Disable DNS
port=0
# Use in DHCP PXE Proxy mode
dhcp-range=192.168.0.0,proxy
# Tell dnsmasq to provide proxy PXE service to both PXE and HTTP clients
dhcp-pxe-vendor=PXEClient,HTTPClient
# Send the BOOTP information for the clients using HTTP
dhcp-boot="http://netboot/ipxe.efi"
# Specify a boot menu option for PXE clients. If there is only one, it's booted immediately.
pxe-service=x86-64_EFI,"iPXE (UEFI)", "ipxe.efi"
# We also need to enable TFTP for the PXE clients
enable-tftp
tftp-root=/var/www/html
Custom Menu
Change the autoexec.ipxe to display a menu.
sudo vi /var/www/html/autoexec.ipxe
#!ipxe
echo ${cls}
:MAIN
menu Local Netboot Menu
item --gap Local Network Installation
item WINDOWS ${space} Windows 11 LTSC Installation
item DEBIAN ${space} Debian Installation
choose selection && goto ${selection} || goto ERROR
:WINDOWS
echo Some windows things here
sleep 3
goto MAIN
:DEBIAN
dhcp
imgfree
set base http://netboot/debian-installer/amd64
kernel ${base}/linux
initrd ${base}/initrd.gz
boot || goto ERROR
:ERROR
echo There was a problem with the selection. Exiting...
sleep 3
exit
Operation
You’ll doubtless find additional options to add. You may want to add the netboot.xyz project to your local menu too.
2.5 - windows
To install windows, have iPXE load wimboot then WinPE. From there you can connect to a samba share and start the Windows installer. Just like back in the gold-ole administrative installation point days.
Getting a copy of WinPE the official way is a bit of a hurdle, but definitely less work than setting up a full Windows imaging solution.
Installation
Samba and Wimboot
On the netboot server, install wimboot and Samba.
sudo wget https://github.com/ipxe/wimboot/releases/latest/download/wimboot -P /var/www/html
sudo apt install samba
Window ADK
On a Windows workstation, download the ADK and PE Add-on and install as per Microsoft’s ADK Install Doc.
Configuration
Samba
Prepare the netboot server to receive the Windows files.
sudo vi /etc/samba/smb.conf
[global]
map to guest = bad user
log file = /var/log/samba/%m.log
[install]
path = /var/www/html
browseable = yes
read only = no
guest ok = yes
guest only = yes
sudo mkdir /var/www/html/winpe
sudo mkdir /var/www/html/win11
sudo chmod o+w /var/www/html/win*
sudo systemctl restart smbd.service
Window ADK Config
On the Windows workstation, start the deployment environment as an admin and create the working files as below. More info is in Microsoft’s Create Working Files document.
- Start -> All Apps -> Windows Kits -> Deployment and Imaging Tools Environment (Right Click, More, Run As Admin)
copype amd64 c:\winpe\amd64
Add the required additions for Windows 11 with the commands below. These are the optional components WinPE-WMI and WinPE-SecureStartup and more info is in Microsoft’s Customization Section.
mkdir c:\winpe\offline
dism /mount-Image /Imagefile:c:\winpe\amd64\media\sources\boot.wim /index:1 /mountdir:c:\winpe\offline
dism /image:c:\winpe\offline /add-package /packagepath:"..\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-WMI.cab" /packagepath:"..\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-SecureStartup.cab"
dism /unmount-image /mountdir:c:\winpe\offline /commit
Make the ISO in case you want to HTTP Boot from it later and keep the shell open for later.
MakeWinPEMedia /ISO C:\winpe\amd64 C:\winpe\winpe_amd64.iso
WinPE
Now that you’ve got a copy of WinPE, copy it to the netboot server.
net use q: \\netboot\install
xcopy /s c:\winpe\* q:\winpe
Also create some auto-start files for setup. The first is part to the WinPE system and tells it (generically) what to do after it starts up.
notepad q:\winpe\amd64\winpeshl.ini
[LaunchApps]
"install.bat"
This the second is more specific and associated with the thing you are installing. We’ll mix and match these in the PXE menu later so we can install different things.
notepad q:\win11\install.bat
wpeinit
net use \\netboot
\\netboot\install\win11\setup.exe
pause
Win 11
You also need to obtain the latest ISO and extract the contents.
- https://massgrave.dev/windows_ltsc_links
- Double-click on the ISO
- Copy contents to q:\win11
Wimboot
Bck on the netboot server, customize the WINDOWS section of your autoexex.ipxe like this.
:WINDOWS
dhcp
imgfree
set winpe http://netboot/winpe/amd64
set source http://netboot/win11
kernel wimboot
initrd ${winpe}/media/sources/boot.wim boot.wim
initrd ${winpe}/media/Boot/BCD BCD
initrd ${winpe}/media/Boot/boot.sdi boot.sdi
initrd ${winpe}/winpeshl.ini winpeshl.ini
initrd ${source}/install.bat install.bat
boot || goto MAIN
You can add other installs by copying this block and changing the :WINDOWS header and source variable.
Next Steps
Add some more installation sources and take a look at the Windows zero touch install.
Troubleshooting
System error 53 has occurred. The network path was not found
A given client may be unable to connect to the SMB share, or it may fail once, but then connect on a retry a moment later. I suspect it’s because the client doesn’t have an IP yet, though I’ve not looked at it closely. You can usually just retry.
You can also comment out the winpeshl.ini line and you’ll boot to a command prompt that will let you troubleshoot. Sometimes you just don’t have an IP yet from the DHCP server and you can edit the install.bat file to add a sleep or other things. See then [zero touch deployment] page for some more ideas.
Access is denied
This may be related to the executable bit. If you’ve copied from the ISO they should be set. But if after that you’ve changed anything you could have lost the x bit from setup.exe. It’s hard to know what’s supposed to be set once it’s gone, so you may want to recopy the files.
2.6 - Legacy
Many older systems can’t HTTP Boot so let’s add PXE support with some dnsmasq options.
Installation
Dnsmasq
Install as in the httpboot page.
The Debian Installer
Older clients don’t handle ISOs well, so grab and extract the Debian netboot files.
sudo wget http://ftp.debian.org/debian/dists/bookworm/main/installer-amd64/current/images/netboot/netboot.tar.gz -O - | sudo tar -xzvf - -C /var/www/html
Grub is famous for ignoring proxy dhcp settings, so let’s start off the boot with something else; iPXE. It can do a lot, but isn’t signed so you must disable secure boot on your clients.
sudo wget https://boot.ipxe.org/ipxe.efi -P /var/www/html
Configuration
iPXE
Debian is ready to go, but you’ll want to create an auto-execute file for iPXE so you don’t have to type in the commands manually.
sudo vi /var/www/html/autoexec.ipxe
#!ipxe
set base http://netboot/debian-installer/amd64
dhcp
kernel ${base}/linux
initrd ${base}/initrd.gz
boot
Dnsmasq
HTTP and PXE clients need different information to boot. We handle this by adding a filename to the PXE service option. This will override the dhcp-boot directive for PXE clients.
sudo vi /etc/dnsmasq.d/netboot.conf
# Disable DNS
port=0
# Use in DHCP PXE Proxy mode
dhcp-range=192.168.0.0,proxy
# Respond to both PXE and HTTP clients
dhcp-pxe-vendor=PXEClient,HTTPClient
# Send the BOOTP information for the clients using HTTP
dhcp-boot="http://netboot/debian.iso"
# Specify a boot menu option for PXE clients. If there is only one, it's booted immediately.
pxe-service=x86-64_EFI,"iPXE (UEFI)", "ipxe.efi"
# We also need to enable TFTP for the PXE clients
enable-tftp
tftp-root=/var/www/html
Client
Both types of client should now work. The debian installer will pull the rest of what it needs from the web.
Next Steps
You can create a boot-menu by adding multiple pxe-service entries in dnsmasq, or by customizing the iPXE autoexec.ipxe files. Take a look at that in the menu page.
Troubleshooting
Text Flashes by, disappears, and client reboots
This is most often a symptom of secure boot still being enabled.
Legacy Clients
These configs are aimed at UEFI clients. If you have old BIOS clients, you can try the pxe-service tag for those.
pxe-service=x86-64_EFI,"iPXE (UEFI)", "ipxe.efi"
pxe-service=x86PC,"iPXE (UEFI)", "ipxe.kpxe"
This may not work and there’s a few client flavors so enable the dnsmasq logs to see how they identify themselves. You can also try booting pxelinux as in the Debian docs.
DHCP Options
Dnsmasq also has a whole tag system that you can set and use similar to this:
dhcp-match=set:PXE-BOOT,option:client-arch,7
dhcp-option=tag:PXE-BOOT,option:bootfile-name,"netboot.xyz.efi"
However, dnsmasq in proxy mode limits what you can send to the clients, so we’ve avoided DHCP options and focused on PXE service directives.
Debian Error
*ERROR* CPU pipe B FIFO underrun
You probably need to use the non-free firmware
No Boot option
Try entering the computers bios setup and adding a UEFI boot option for the OS you just installed. You may need to browse for the file \EFI\debian\grubx64.efi
Sources
https://documentation.suse.com/sles/15-SP2/html/SLES-all/cha-deployment-prep-uefi-httpboot.html https://github.com/ipxe/ipxe/discussions/569 https://linuxhint.com/pxe_boot_ubuntu_server/#8
It’s possible to use secure boot if you’re willing to implement a chain of trust. Here’s an example used by FOG to boot devices.
https://forums.fogproject.org/topic/13832/secureboot-issues/3
3 - Windows
3.1 - Server Core
Installation Notes
If you’re deploying Windows servers, Server Core is best practice1. Install from USB and it will offer that as a choice - it’s fairly painless. But these instances are designed to be remote-managed so you’ll need to perform a few post-install tasks to help with that.
Server Post-Installation Tasks
Set a Manual IP Address
The IP is DHCP by default and that’s fine if you create a reservation at the DHCP server or just use DNS. If you require a manual address, however:
# Access the PowerShell interface (you can use the server console if desired)
# Identify the desired interface's index number. You'll see multiple per adapter for IP4 and 6 but the interface index will repeat.
Get-NetIPInterface
# Set a manual address, netmask and gateway using that index (12 in this example)
New-NetIPaddress -InterfaceIndex 12 -IPAddress 192.168.0.2 -PrefixLength 24 -DefaultGateway 192.168.0.1
# Set DNS
Set-DNSClientServerAddress –InterfaceIndex 12 -ServerAddresses 192.168.0.1
Allow Pings
This is normally a useful feature, though it depends on your security needs.
Set-NetFirewallRule -Name FPS-ICMP4-ERQ-In -Enabled True
Allow Computer Management
Server core allows ‘Remote Management’ by default2. That is specifically the Server Manager application that ships with Windows Server versions and is included with the Remote Server Admin Tools on Windows 10 professional3 or better. For more detailed work you’ll need to use the Computer Management feature as well. If you’re all part of AD, this is reported to Just Work(TM). If not, you’ll need to allow several ports for SMB and RPC.
# Port 445
Set-NetFirewallRule -Name FPS-SMB-In-TCP -Enabled True
# Port 135
Set-NetFirewallRule -Name WMI-RPCSS-In-TCP -Enabled True
maybe
FPS-NB_Name-In-UDP
NETDIS-LLMNR-In-UDP
Configuration
Remote Management Client
If you’re using windows 10/11, install it on a workstation by going to System -> Optional features -> View features and enter Server Manager in the search box to select and install.
With AD
When you’re all in the same Domain then everything just works (TM). Or so I’ve read.
Without AD
If you’re not using Active Directory, you’ll have to do a few extra steps before using the app.
Trust The Server
Tell your workstation you trust the remote server you are about to manage4 (yes, seems backwards). Use either the hostname or IP address depending on how your planning to connect - i.e. if you didn’t set up DNS use IPs. Start an admin powershell and enter:
Set-Item wsman:\localhost\Client\TrustedHosts 192.168.5.1 -Concatenate -Force
Add The Server
Start up Server Manager and select Manage -> Add Servers -> DNS and search for the IP or DNS name. Pay attention the server’s name that it detects. If DNS happens to reslove the IP address you put in, as server-1.local for example, you’ll need to repeat the above TrustedHosts command with that specific name.
Manage As…
You may notice that after adding the server, the app tries to connect and fails. You’ll need to right-click it and select Manage As… and enter credentials in the form of server-1\Administrator and select Remember me to have this persist. Here you’ll need to use the actual server name and not the IP. If unsure, you can get this on the server with the hostname command.
Starting Performance Counters
The server you added should now say that it’s performance counters are not started. Right-click to and you can select to start them. The server should now show up as Online and you can perform some basic tasks.
server-1.local\Administrator
Server Manager is the default management tool and newer servers allow remote management by default. The client needs a few things, however.
- Set DNS so you can resolve by names
- Configure Trusted Hosts
On the system where you start the the Server Manager app - usually where you are sitting - ensure you can resolve the remote host via DNS. You may want to edit your hosts file if not.
notepad c:\Windows\System32\drivers\etc\hosts
You can now add the remote server.
Manage -> Add Servers -> DNS -> Search Box (enter the other servers hostname) -> Magnifying Glass -> Select the server -> Right Arrow Icon -> OK
(You man need to select Manage As on it)
Allow Computer Management
You can right-click on a remote server and select Computer Management after doing this
MISC
Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled False
-
https://learn.microsoft.com/en-us/windows-server/get-started/install-options-server-core-desktop-experience ↩︎
-
https://learn.microsoft.com/en-us/windows-server/administration/server-core/server-core-sconfig#configure-remote-management ↩︎
-
https://www.microsoft.com/en-us/download/details.aspx?id=45520 ↩︎
-
https://learn.microsoft.com/en-us/windows-server/administration/server-manager/configure-remote-management-in-server-manager#to-enable-server-manager-remote-management-by-using-the-windows-interface ↩︎
3.2 - Windows Zero Touch Install
The simplest way to zero-touch install Windows is with a web-generated answer file. Go to a site like schneegans and just create it. This removes the need for the complexity of MDS WDS SCCM etc. systems for normal deployments.
Create An Answer File
Visit schneegans. Start with some basic settings, leaving most at the default, and increase complexity with successive iterations. A problematic setting will just dump you out of the installer and it can be hard to determine what went wrong.
Download the file and use it one of the following ways;
USB
After creating the USB installer, copy the file (autounattend.xml) to the root of the USB drive (or one of these locations) and setup will automatically detect it.
Netboot
For a netboot install, copy the file to the sources folder of the Windows files.
scp autounattend.xml netboot:/var/www/html/win11/sources
Additionally, some scripting elements of the install don’t support UNC paths so we must map a drive. Back in the Windows netboot page, we created an install.bat to start the installation. Let’s modify that like so
vi /var/www/html/win11/install.bat
wpeinit
SET SERVER=netboot
:NET
net use q: \\%SERVER%\install
REM If there was a problem with the net use command,
REM ping, pause and loop back to try again
IF %ERRORLEVEL% NEQ 0 (
ping %SERVER%
pause
GOTO NET
) ELSE (
q:
cd win11
setup.exe
)
Add Packages
The installer can also add 3rd party software packages by adding commands in the Run custom scripts section to run at initial log-in. We’ll use HTTP to get the files as some versions of windows block anonymous SMB.
Add Package Sources
On the netboot server, create an apps folder for your files and download packages there.
mkdir /var/www/html/apps; cd /var/www/html/apps
wget https://get.videolan.org/vlc/3.0.9.2/win64/vlc-3.0.9.2-win64.msi
wget https://statics.teams.cdn.office.net/production-windows-x64/enterprise/webview2/lkg/MSTeams-x64.msix
Add to Autounattend.xml
It’s easiest to add this in the web form rather than try and edit the XML file. Go to this section and add a line like this one to the third block of custom scripts. It must run at initial user login as the network isn’t available before that.
Navigate to the block that says:
Scripts to run when the first user logs on after Windows has been installed
For MSI Files
These and handled as .cmd files as in field 1.
msiexec /package http://netboot/apps/GoogleChromeStandaloneEnterprise64.msi /quiet
msiexec /package http://netboot/apps/vlc-3.0.9.2-win64.msi /quiet
For MSIX Files
These are handled as .ps1 files as in field 2.
Add-AppPackage -path http://netboot/apps/MSTeams-x64.msix
For EXE files
These are are also handled in the .ps1 files in field 2. They require more work however, as you must download, run, then remove them.
(New-Object System.Net.WebClient).DownloadFile("http://netboot/apps/WindowsSensor.MaverickGyr.exe","$env:temp\crowd.exe")
Start-Process $env:temp\crowd.exe -ArgumentList "/install /quiet CID=239023847023984098098" -wait
Remove-Item "$env:temp\crowd.exe"
Troubleshooting
Select Image Screen
Specifying the KMS product key won’t always allow you to skip the “Select Image” screen. This may be due to an ISO being pre-licensed or have something to do with Windows releases. To fix this, add an InstallFrom stanza to the OSImage block of your unattended.xml file.
<ImageInstall>
<OSImage>
<InstallTo>
<DiskID>0</DiskID>
<PartitionID>3</PartitionID>
</InstallTo>
<InstallFrom>
<MetaData wcm:action="add">
<Key>/Image/Description</Key>
<Value>Windows 11 Enterprise</Value>
</MetaData>
</InstallFrom>
</OSImage>
</ImageInstall>
https://www.tenforums.com/installation-upgrade/180022-autounattend-no-product-key.html
Notes
Windows Product Keys https://gist.github.com/rvrsh3ll/0810c6ed60e44cf7932e4fbae25880df