DEV Community

Alex M. Schapelle for Vaiolabs

Posted on • Edited on

How to Create Custom Debian Based ISO

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 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.
  • 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 provided. Let's begin by downloading the ISO file:

curl -X GET -OL https://releases.ubuntu.com/20.04.4/ubuntu-20.04.4-live-server-amd64.iso
Enter fullscreen mode Exit fullscreen mode

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:

 sudo apt-get update && sudo apt-get install -y xorriso
Enter fullscreen mode Exit fullscreen mode

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:

xorriso -osirrox on -indev "ubuntu-20.04.4-live-server-amd64.iso" -extract / iso && chmod -R +w iso
Enter fullscreen mode Exit fullscreen mode

The output of which will create iso folder into which all internals of files provided in the command. But, what do we have inside?

 

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 -> .
Enter fullscreen mode Exit fullscreen mode

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:

sudo apt-get install -y squashfs-tools syslinux syslinux-efi isolinux
Enter fullscreen mode Exit fullscreen mode

once installed we can copy, for caution, the filesystem.squashfs file into different file and adjust its parameters there.

 cp iso/casper/filesystem.squashfs .
 cd ~
 sudo unsquashfs filesystem.squashfs
Enter fullscreen mode Exit fullscreen mode

Output of which should look like this:

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
Enter fullscreen mode Exit fullscreen mode

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

sudo apt-get install -y fakeroot
Enter fullscreen mode Exit fullscreen mode

fakeroot Enables us to user chroot commands, which changes our root by posing us as a fake root user of GNU/Linux system. So …

 sudo chroot squashfs-root/
[sudo] password for aschapelle: 
root@vaio3lap:/#
Enter fullscreen mode Exit fullscreen mode

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

 

 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:

 apt-get update && apt-get install htop vim atop cloud-init
Enter fullscreen mode Exit fullscreen mode

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 :

 echo ' ' > /etc/resolv.conf
 apt-get clean
 history -c
 exit
Enter fullscreen mode Exit fullscreen mode

After exiting from chroot environment, we need to squash back the file system, which can be attained as follows:

 sudo mksquashfs  squashfs-root/ filesystem.squashfs -comp xz -b 1M -noappend
Enter fullscreen mode Exit fullscreen mode

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:

 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
Enter fullscreen mode Exit fullscreen mode

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

Top comments (10)

Collapse
 
jkristia profile image
Jesper Kristiansen • Edited

Thanks for a great article.
I do have one problem. I think I have followed the steps exactly as given, but for the last step I get this error.

xorriso : FAILURE : Given path does not exist on disk: -boot_image system_area='/usr/lib/syslinux/bios/isohdpfx.bin'
xorriso : UPDATE :    1005 files added in 1 seconds
Enter fullscreen mode Exit fullscreen mode

And checking inside squashfs-root, I do not find that path

jesper@debian:~/squashfs-root/usr/lib$ ll | grep sy
drwxr-xr-x  2 root root   4096 Feb 23  2022 rsyslog
drwxr-xr-x  2 root root   4096 Feb 23  2022 sysctl.d
drwxr-xr-x 17 root root   4096 Feb 23  2022 systemd
drwxr-xr-x  2 root root   4096 Feb 23  2022 sysusers.d
Enter fullscreen mode Exit fullscreen mode

Any suggestion what I might be missing?

Collapse
 
silent_mobius profile image
Alex M. Schapelle • Edited

Hi @jkristia
I think its a package path issue. Syslinux package suppose to be installed on your system, not in squashfs.
Try using ls on your system with path SYSLINUX

ls /usr/lib/SYSLINUX/ 
Enter fullscreen mode Exit fullscreen mode

if you are on Debian and have installed the dependencies it should be there. In case of Ubuntu it still needs to be on your system.

In case you are missing it, try adding the packages with:

sudo apt-get install -y syslinux isolinux
Enter fullscreen mode Exit fullscreen mode
Collapse
 
silent_mobius profile image
Alex M. Schapelle

Well,
The process is similar, but I might interest you in tool that does it all for you...
I have developed a shell based script that allows you to configure the ISO to your requirements and I am writing an article about it. if you have bash scripting capabilities and want to add your features, you are welcome to join me
Once the last functions will be cleared out, I'll release the article and start rewriting the tool in Go or Rust, which ever will be easier for me...

Collapse
 
jkristia profile image
Jesper Kristiansen

Cool, installing syslinux and then change the path in the last command works.

/usr/lib/ISOLINUX/isohdppx.bin
Enter fullscreen mode Exit fullscreen mode

A similar step by step instruction for a debian 12 image would be awesome. :)

Thread Thread
 
silent_mobius profile image
Alex M. Schapelle

Well,
The process is similar, but I might interest you in tool that does it all for you...
I have developed a shell based script that allows you to configure the ISO to your requirements and I am writing an article about it. if you have bash scripting capabilities and want to add your features, you are welcome to join me
Once the last functions will be cleared out, I'll release the article and start rewriting the tool in Go or Rust, which ever will be easier for me...

Collapse
 
biraj21 profile image
Biraj • Edited

hello! what if i just want to automate the account creation part?

i am customizing ubuntu server 20.04 iso using Cubic. i want the user to be able to choose & configure language, network, partition & everything else except for account creation. i would like a root account to be created automatically with some name, username & password that i write in some preseed file.

any idea on how to do this?

thanks!

Collapse
 
silent_mobius profile image
Alex M. Schapelle

Hi Biraj,
The user root is created whether you want it or not, the question is, whether you'd like to have other with UID,GID of 0? That unfortunately is not possible because there can be only one user with UID,GID 0. It is possible to manipulate OS in a manner that will allow you to set different user with UID,GID 0, but it usually creates problems with different utilities that seek user root by name and not by UID,GID.
In vase you wish to setup only user with sudo permissions that has already setup password, you could do use user command and set it up in next manner in your cloud init config file

#cloud-config
autoinstall:
  version: 1
  identity: {hostname: HOSTNAME, password: "ENCRYPTED-PASSWORD", username: USERNAME}
Enter fullscreen mode Exit fullscreen mode

[+] note: you need to generate encrypted password with ssl, and insert it in to meta-data file in your iso.
Hope this is helpful

Collapse
 
biraj21 profile image
Biraj • Edited

hi Alex

yeah it was my bad... when i said root user, i meant to say a user with sudo permission (which is what we get if we create account during installation)

this is what i did

  • customized Ubuntu Server 20.04 iso using Cubic as per my needs
  • created a user-data file like this:
  #cloud-config
  autoinstall:
    version: 1
    identity:
      hostname: my-hostname
      password: "a crypted password generated with mkpasswd"
      username: my-username
Enter fullscreen mode Exit fullscreen mode

it automatically installed Ubuntu Server 20.04 in my vm with the user just like i wanted! although i expected it to ask for other things like keyboard, language & stuff but ig it just used default. so i'l have to learn more about clout-init & its config to let the user configure & choose stuff which i didn't configure in the iso.

thanks for your reply 🤝

ps: as you might have guessed i'm still a beginner in servers & cloud, hence root user 🤡

Thread Thread
 
silent_mobius profile image
Alex M. Schapelle

Always welcome and good luck: do try to have some fun

Collapse
 
shaikuzi profile image
shai-talent-fabric

Very informative article. Thanks 👍