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
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
or7zip
, 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
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
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 -> .
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
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
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
Note: In Debian itself and in some other Debian Linux distributions,
filesystem.squashfs
might be located in different location such aslive
orinstall
. 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
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:/#
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
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
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
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
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)
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.
And checking inside squashfs-root, I do not find that path
Any suggestion what I might be missing?
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 SYSLINUXif 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:
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...
Cool, installing syslinux and then change the path in the last command works.
A similar step by step instruction for a debian 12 image would be awesome. :)
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...
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!
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 filehi 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
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 🤡
Always welcome and good luck: do try to have some fun
Very informative article. Thanks 👍