- Shell 100%
| boot.ipxe | ||
| install-and-setup.sh | ||
| preseed-vps.cfg | ||
| preseed.cfg | ||
| README.md | ||
| tftp-config | ||
iPXE
start by running ./install-and-setup.sh (sah faut check ligne par ligne je le trust pas mon truc)
This sets up a TFTP & HTTP server. TFTP is used by legacy BIOS systems, and HTTP is used by UEFI. The HTTP server is powered by nginx and TFTP by tftp-hda, to make things simpler TFTP is configured to fetch files from the default directory used by nginx.
Adding an Image
To add a image first edit boot.ipxe and add a menu entry. It is not recommended to directly add ISOs as this is slow and doesn't work in my experience, regardless you can do it by adding this to the boot.ipxe file:
:ubuntu
kernel http://10.64.0.10/ubuntu/vmlinuz ip=dhcp url=http://10.64.0.10/ubuntu-22.04.iso
initrd http://10.64.0.10/ubuntu/initrd
boot
If you wish to directly boot of an ISO (not recommended):
:ubuntu-iso
sanboot http://10.64.0.10/ubuntu.iso
The recommended way is to use a netboot installer, this a lot lighter than using the ISO and thus a lot faster, you can do this by adding (and of cours replacing the URL with the actual one:
:ubuntu-netboot
kernel http://archive.ubuntu.com/ubuntu/dists/jammy/main/installer-amd64/linux
initrd http://archive.ubuntu.com/ubuntu/dists/jammy/main/installer-amd64/initrd.gz
boot
The linux & initrd.gz must be located in /var/www/html/path/to/file.
Preseeding images
Preseeding images is useful for unattended installs. The preseed configuration we use is based off of the default preseed provided by debian here. For some obscure reason nginx doesn't know how to handle .cfg files and thus parses them as octet-streams, which can result to breaking behaviour. the fix is available here. We use preseed.cfg & preseed-vps.cfg, the only difference is that preseed-vps.cfg doesn't set a normal user and rather prompts the user for the details (see account creation).
Locales
d-i debian-installer/language string en
d-i debian-installer/country string FR
d-i debian-installer/locale string en_US
d-i keyboard-configuration/xkb-keymap select us
These lines setup the system to be in english using a qwerty keyboard but sets the contry to france to get correct system time and to use the best mirror (currently doesn't work see Mirrors).
Mirrors
d-i mirror/country string manual
d-i mirror/http/hostname string deb.debian.org
d-i mirror/http/directory string /debian
d-i mirror/http/proxy string
The first line tells debian that we want to setup the mirror ourselves, omitting this line will ignore the following lines. Here we use deb.debian.org which is a US based mirror as i couldn't get it working with a french based mirror. We set the directory to debian as it is how mirrors are structured, however this is probably default behaviour and could be omitted. Finally the last line tells debian to not use an HTTP proxy, if you which too use one you can append the url & user at the end.
Account creation
d-i passwd/root-login boolean true
d-i passwd/root-password-crypted password $y$j9T$mfsE.kF7o9u9dOXGHPHCo/$V6ILe4EKgrtyee0TpLS/1d2HaVDQ8CLtybYAsDF7Lm3
d-i passwd/user-fullname string moot
d-i passwd/username string moot
d-i passwd/user-password-crypted password $y$j9T$mfsE.kF7o9u9dOXGHPHCo/$V6ILe4EKgrtyee0TpLS/1d2HaVDQ8CLtybYAsDF7Lm3
The first 2 lines create the root user & set the password hash, you can learn about generating the hash here. The next 3 lines are omitted from preseed-vps.cfg which is the only difference between the 2 files. These lines create a normal user with a name & username (in most cases these values will be the same) and sets the password once again using a hash. When creating a VPS we want to be able to specify these values manually as having a user called moot wouldn't make sens to our clients.
Time zone
d-i time/zone string Europe/Paris
This simply sets the timezone to the french one to make it easier, it can also fix weird behaviour in some applications (though rare; these are mostly undocumented)
Disks
d-i partman-auto/method string regular
d-i partman-auto/choose_recipe select atomic
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
These lines set up the disk and rely heavily on the assumption that there will only be one disk (other than the media device used to boot the installer, which in this case is none because we are booting from the network). Setting the method to regular disables RAID & LVM or any other weird tech. Atomic simply means that we will be putting everything in a single partition (ie. / & /home will be in the same partition). The rest of the config allows debian to write these changes to disk without needing user confirmation.
Packages
tasksel tasksel/first multiselect standard, ssh-server
d-i pkgsel/include string vim sudo
The first line tells debian to not install any graphical interface and only install the bare minimum as well as an SSH server. The second line installs QOL packages, sudo is mostly used for VPSs but can still be useful for classical VMs
GRUB
d-i grub-installer/only_debian boolean true
d-i grub-installer/bootdev string /dev/sda
d-i finish-install/reboot_in_progress note
Finally this installs GRUB to the primary device (once again assuming there is only one disk) and reboots into the new system
FAQ/Troubleshooting
Nginx not handling .cfg files properly
Edit /etc/nginx/mime.types find the text/plain line and add cfg to the list, if for some reason the file is empty here is a template:
types {
text/html html;
text/plain txt cfg;
}
However a more complete list can probably be found online.
You may also need to restart nginx sudo systemctl restart nginx.
You can check this works by running: curl -I http://10.64.0.10/debian/preseed.cfg, if you see any other than Content-Type: text/plain, it didn't work.
Creating a password hash
To get a password hash you can simply use mkpasswd, if you need to be able to see what you are typing you can pass the -s flag. You can also read more here: crypt(3)
The TFTP user doesn't exist
check if the user exists by running id tftp, if it doesn't create it like so: sudo useradd -r -s /usr/sbin/nologin tftp. You will also need to set permissions:
sudo chown -R tftp:tftp /var/lib/tftpboot
sudo chmod -R 755 /var/lib/tftpboot
and restart tftp: sudo systemctl restart tftpd-hpa
iPXE boot looping
remove "boot-file-name": "undionly.kpxe" from /etc/kea/kea-dhcp4.conf (The line may not be exactly the same but you should remove boot-file-name from the subnet regardless of the value set)
Nothing to boot: no such file or directory
same fix as above
Debian failed to process preconfiguration file
Check the url field in boot.ixpe you can also add a preseed/url field, if it still doesn't work try the fix from above