How to create a customized bootable and automated debian install ?
Official documentation
- Example preseed configuration : http://debian.org/releases/buster/example-preseed.txt
- How to repack (generate) an ISO : https://wiki.debian.org/RepackBootableISO
Quick overview of the ISO creation process
We are making a initrd preseed configuration which means that upon boot, we'll select "Install" and not "Automated install".
- We start by using an official image
- We extract the image
- Create and modify the preseed configuration
- We modify the init ram disk (initrd) to add the preseed
- We repack everything into a new ISO
Everything is done using the Gitlab CI. It also can be done directly with docker.
Detailed process
The following script has to be run on a debian based system. However, it can be run in a dockerized environment (such as Gitlab CI with the debian:11.7 image)
bash
export ORIGINAL_ISO_URL=https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/archive/11.7.0+nonfree/amd64/iso-cd/firmware-11.7.0-amd64-netinst.iso
export ORIGINAL_ISO=firmware-11.7.0-amd64-netinst.iso
export REMASTERED_ISO=customized-11.7.0-amd64-netinst.iso
# 1. Download the original ISO image:
# This command downloads the official Debian ISO image from the specified URL
# and saves it as the file defined in the `ORIGINAL_ISO` variable.
wget $ORIGINAL_ISO_URL
# 2. Extract the ISO image:
# This command creates a new directory called `isofiles` and extracts the
# contents of the original ISO image into it using the `xorriso` tool.
mkdir isofiles
xorriso -osirrox on -indev $ORIGINAL_ISO -extract / isofiles/
# 3. Modify the initrd (initial ramdisk):
# These commands make the `install.amd` directory writable, decompress the
# `initrd.gz` file, add the `preseed.cfg` file to the initrd using the `cpio`
# command, compress the initrd back into a `.gz` file, and make the
# `install.amd` directory read-only again.
chmod +w -R isofiles/install.amd/
gunzip isofiles/install.amd/initrd.gz
echo preseed.cfg | cpio -H newc -o -A -F isofiles/install.amd/initrd
gzip isofiles/install.amd/initrd
chmod -w -R isofiles/install.amd/
# 4. Update the MD5 checksums:
cd isofiles && find -follow -type f ! -name md5sum.txt -print0 | xargs -0 md5sum > md5sum.txt
chmod -w md5sum.txt
cd ..
# 5. Extract the isohdpfx.bin file from the original iso:
# This command uses the `dd` tool to extract the first 432 bytes of the original
# ISO image and save them as the `isohdpfx.bin` file, which is required for
# creating a bootable ISO image.
dd if=$ORIGINAL_ISO bs=1 count=432 of=isohdpfx.bin
# 6. Create the customized ISO image:
# This command uses the `xorriso` tool to create a new ISO image with the
# modified initrd and preseed configuration. It sets various options,
# such as the volume label, output file name, checksum algorithms, and boot
# options, to ensure the resulting ISO image is bootable and compatible
# with different systems.
mkdir -p public/
xorriso -as mkisofs \
-r -checksum_algorithm_iso sha256,sha512 \
-V 'Debian 11.7.0 amd64 n' \
-o public/$REMASTERED_ISO \
-J \
-joliet-long \
-cache-inodes \
-isohybrid-mbr isohdpfx.bin \
-b isolinux/isolinux.bin \
-c isolinux/boot.cat \
-boot-load-size 4 \
-boot-info-table \
-no-emul-boot \
-eltorito-alt-boot \
-e boot/grub/efi.img \
-no-emul-boot \
-isohybrid-gpt-basdat \
-isohybrid-apm-hfsplus isofiles
# 7. Clean up:
rm -r isofiles
The new iso image is available in the ./public/ directory
You can now flash your USB pen as usual
bash
sudo dd if=customized-11.7.0-amd64-netinst.iso of=/dev/<your usb disk>
Cheat sheet
Generate an encrypted password for users
bash
openssl passwd -6
Preseed keyboard configuration for french people
txt
d-i keyboard-configuration/xkb-keymap select fr(latin9)
Add post-install external script
txt
d-i preseed/late_command string in-target wget https://<your-host>/post-install.sh ; in-target /bin/bash post-install.sh
A configuration example
txt
# Debian autoinstaller configuration file
# Localization
d-i debian-installer/language string fr
d-i debian-installer/country string FR
d-i debian-installer/locale string fr_FR.UTF-8
# Keyboard selection.
d-i keyboard-configuration/xkb-keymap select fr(latin9)
# Network configuration
d-i netcfg/choose_interface select eno1
d-i netcfg/link_wait_timeout string 5
d-i netcfg/dhcp_timeout string 60
d-i netcfg/get_domain string netsach.com
# Users and passwords
# replace XXXXX by the output of the command openssl -6
d-i passwd/root-password-crypted password XXXXXXXX
d-i passwd/make-user boolean true
d-i passwd/user-fullname string debian
d-i passwd/username string debian
d-i passwd/user-password-crypted password XXXXX
d-i passwd/user-default-groups string sudo audio cdrom video
# Clock is UTC
d-i clock-setup/utc boolean true
d-i time/zone string UTC
# Partitioning
d-i partman-auto/method string regular
d-i partman-auto/disk string /dev/nvme0n1
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-efi/non_efi_system boolean true
d-i apt-setup/local0/repository string http://deb.debian.org/debian bullseye main contrib non-free
# Package selection
tasksel tasksel/first multiselect standard
d-i pkgsel/include string openssh-server build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev wget libbz2-dev python3 sudo wget
# Mirror settings
d-i mirror/country string France
d-i mirror/http/hostname string ftp.fr.debian.org
d-i mirror/http/directory string /debian
d-i mirror/http/proxy string
# Popularity contest
popularity-contest popularity-contest/participate boolean false
# Apt CDROM
d-i apt-setup/cdrom/set-first boolean false
d-i preseed/late_command string in-target wget https://<your-host>/post-install.sh ; in-target /bin/bash post-install.sh
Discover more content ?
Do you want to learn more and faster with dense and tailored technical resources ?