This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Operating Systems

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.

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

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