How to Create Custom Debian Based ISO
Tags: linux, systems, iso, custom
Published: 2022-04-23 18:48:00

Welcome dear reader, I am Silent-Mobius, your humble steel-collar automaton.

To tell the truth, I've been struggling with custom ISO all my career, that has been in motion for last 14 years. Every customer I've worked with would eventually come up with request to provide the dev-team with custom GNU/Linux OS, with all the tools and scripts that would already included in the ISO file, and to be honest, I'd always try to uses some type of tool, script or framework to by pass the task because I was never sure, if diving into GNU/Linux system internals would be correct way to choose.
As time went on, I've chosen several distributions as my favorite, and tried to become as skillful as possible with them, yet initial task mentioned before, would always evade me.
With current customer, I've decided to challenge myself, and to make an effort to learn more in regards of the matter and also share the findings with you, my gentle reader.
As such we must begin at the beginning, with getting ourselves an basic ISO file to work on, as well list of tools that we will be use in order to commence such an complicated task ahead of us.
Prerequisites and assumptions: 
- I, myself, am an Debian Distro user and has been such for last 14 years, thus I'll be using the same distribution for this task as well.
- ISO file that we shall manipulate to create custom GNU/Linux distribution for our use case, would be [Ubuntu 20.04.4](https://releases.ubuntu.com/20.04.4/ubuntu-20.04.4-live-server-amd64.iso) which we can also download from the provided link.
- Other tool installations will be shown below as we go along.
- The procedure and tools that I'll be using can be used in all other distributions, yet I only tested it on Debian and RedHat families, and due to emerged differences, decided to adhere only to Debian family.

## The Great Plan
Every process should have a plan of action, so let us present one such rule list:
We will :
- Get the ISO from [link](https://releases.ubuntu.com/20.04.4/ubuntu-20.04.4-live-server-amd64.iso).
- Decompress that ISO file.
- Decompress builtin filesystem and connect to it.
- Make required changes
- Disconnect from filesystem.
- Compress filesystem back as it was.
- Compress ISO file with all the changes.

Now, without further ado, let us delve in to the matter:
We start by downloading ISO and installing initial tools for decompressing the file, which by the way is another of compression format for archiving our data. Standard used for CD/DVD's is usually ISO 9660 which you can read about in the [link](https://releases.ubuntu.com/20.04.4/ubuntu-20.04.4-live-server-amd64.iso) provided. Let's begin by downloading the ISO file:
```sh
curl -X GET -OL https://releases.ubuntu.com/20.04.4/ubuntu-20.04.4-live-server-amd64.iso
```
Once that will be done, it is good practice to have initial tool named `xorriso` which is the tool that creates, loads, manipulates and writes ISO 9660 filesystem images.
> NOTE: We can also have used `7z` or `7zip`, a tool for compressing and decompressing files and images for this tasks, yet, it turns out, on RedHat systems it is not usable, due to corrupted version that is kept at their package repositories.

Let us execute the install:
```sh
 sudo apt-get update && sudo apt-get install -y xorriso
```
and once it will finish the installation. Alternative option is to use 7zip, but for some reason, the version I used, was failing to open ISO file. We'll be able to decompress the ubuntu file we downloaded before with this:
```sh
xorriso -osirrox on -indev "ubuntu-20.04.4-live-server-amd64.iso" -extract / iso && chmod -R +w iso
```
The output of which will create `iso` folder into which all internals of files provided in the command. But, what do we have inside? 
```sh
aschapelle@vaiolabs~/iso[]$ ls -l
total 68
drwxrwxr-x. 3 aschapelle aschapelle  4096 Feb 23 11:26 boot
drwxrwxr-x. 3 aschapelle aschapelle  4096 Feb 23 11:26 casper
drwxrwxr-x. 3 aschapelle aschapelle  4096 Feb 23 11:26 dists
drwxrwxr-x. 3 aschapelle aschapelle  4096 Feb 23 11:26 EFI
drwxrwxr-x. 2 aschapelle aschapelle  4096 Feb 23 11:26 install
drwxrwxr-x. 2 aschapelle aschapelle 12288 Feb 23 11:26 isolinux
-rw-rw-r--. 1 aschapelle aschapelle 27389 Feb 23 11:26 md5sum.txt
drwxrwxr-x. 3 aschapelle aschapelle  4096 Feb 23 11:26 pool
drwxrwxr-x. 2 aschapelle aschapelle  4096 Feb 23 11:26 preseed
lrwxrwxrwx. 1 aschapelle aschapelle     1 Apr 23 16:14 ubuntu -> .
```
Main folders to focus on would be boot, casper and isolinux .
- `boot` folder holds on the installer options of live system that is used for installation.
- `casper` holds in compresses filesystem called squashfs files as well as INITial Ram Disk (init-rd) file for loading filesystem and vmlinuz file which is essential Linux kernel.
- `isolinux` which provides configuration files for boot system among other things.

So ,now what ? 
Well, gentle reader, it solely depends on your wishes, yet from my point of view, we should disassemble, one of the filesystems in casper folder, edit it, configure it and customize it while later, patch it back for further use. 
> NOTE:  I'll be publishing other tutorials where these details can be in regards to use cases of different ISO implementations.

The disassembly tool for squashfs can be installed as follows:
```sh
sudo apt-get install -y squashfs-tools syslinux syslinux-efi isolinux
```
once installed we can copy, for caution, the filesystem.squashfs file into different file and adjust its parameters there.
```sh
 cp iso/casper/filesystem.squashfs .
 cd ~
 sudo unsquashfs filesystem.squashfs
```
Output of which should look like this:
```sh
Parallel unsquashfs: Using 4 processors
33457 inodes (38383 blocks) to write
[============================================|] 38383/38383 100%
created 29764 files
created 3675 directories
created 3572 symlinks
created 9 devices
created 0 fifos
```
> Note: In Debian itself and in some other Debian Linux distributions, `filesystem.squashfs` might be located in different location such as `live` or `install`. Please check adapt accordingly.

Eventually, we will be left with new folder name filesystem-root .
This is where learn that essentially, the architecture of live-ISO-filesystem is such of a system that includes squashed filesystem that is copied onto new media, simple SATA drive of sort, whether `hda`, `sda` or `nvme0`. once copying the filesystem is done,   `fakerooting` is commencing, meaning that system automatically chooses how to install system, what partitions to use, how to configure network and so on.
We will do the same, but without installing the system, but first, let me get a `fakeroot`
```sh
sudo apt-get install -y fakeroot
```
`fakeroot` Enables us to user chroot commands, which changes our root by posing us as a fake root user of GNU/Linux system. So …
```sh
 sudo chroot squashfs-root/
[sudo] password for aschapelle: 
root@vaio3lap:/#
```
Now, all is left is to configure stuff and then do the steps in reverse.
> NOTE: usually, due to use of chroot there is no network translation, thus nameserver needs to be configured under /etc/resolv.conf 
```sh
 echo 'nameserver 8.8.8.8' > /etc/resolv.conf
```
From here on, it is classical UNIX/Linux administration, install, configure, adjust, append, delete and clean up the system. for sake of example, I'll install few tool:
```sh
 apt-get update && apt-get install htop vim atop cloud-init
```
Essentially you can ch what ever you within the chrooted filesystem, including copy-pasting external files, saving git repositories and so on.
Before you exit the chrooted environment it would be good to clean up our work, by cleaning saved repositories files, history and storage, which in our case is translated to :
```sh
 echo ' ' > /etc/resolv.conf
 apt-get clean
 history -c
 exit
```
After exiting from chroot environment, we need to squash back the file system, which can be attained as follows:
```sh
 sudo mksquashfs  squashfs-root/ filesystem.squashfs -comp xz -b 1M -noappend
```
> NOTE: The process will use most of CPU cores, and it will take some time, depending on how many changes we did. 

After filesystem.squashfs file is created, we copy it to casper folder,change md5 signature and from there create new ISO file:
```sh
 cp filesystem.squashfs ./iso/casper/
 md5sum iso/.disk/info > iso/md5sum.txt
 sed -i 's|iso/|./|g' iso/md5sum.txt
 xorriso -as mkisofs -r -V "Ubuntu custom amd64" -o ubuntu-20.04.4-custom-amd64.iso -J -l -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e boot/grub/efi.img -no-emul-boot -isohybrid-gpt-basdat -isohybrid-apm-hfsplus -isohybrid-mbr /usr/lib/syslinux/bios/isohdpfx.bin iso/boot iso
```
Once the process ends, we'll have new ISO file name ubuntu-20.04.40-custom-amd64.iso which we can burn to usb and test it out.

## Conclusion
Dear gentle reader, thank you for  hovering through with me till the end. Hope you have extended your knowledge to new limits and that this article was informative for you, and remember: Do Try To Have Fun.
Thank you