For those interested: nowadays Linux has support for what is called the EFI Stub boot, which allows the kernel to be booted directly by UEFI. So in a sense steps 1-3 are rolled into the kernel, and the kernel acts as its own boot loader.
Being able to directly edit your motherboard's EFI boot order via command line is admittedly pretty neat. That said, using a traditional bootloader seems to be a popular choice still for simplicity and portability reasons. EFISTUB also can make certain crypto setups more difficult as far as I'm aware.
On Gentoo, for a couple of years, I used an initramfs compiled into the kernel to boot via EFI_STUB with full disk encryption. It's possible. It's been a while. I don't remember it being very easy to wrangle. I don't use that laptop anymore, but I still boot via EFI_STUB on my desktop. It's super simple to set up when you're not using FDE.
I don't remember there being any specific problem that make some crypto setups more difficult than others, with the caveat that implementing FDE at all makes EFI_STUB somewhat more complicated no matter what.
Like I said, it's been a couple of years since I figured all that stuff out, so the passage of time may have softened the terror of configuration and clouded my memories.
When I was first learning Linux (almost 20 years ago [yikes]), I installed it by hand using the Linux From Scratch guide. It was invaluable for learning a ton about how Linux works at a deep level. While a lot has changed since then (mainly due to UEFI), that knowledge is still valuable for understanding how a system functions.
Gentoo taught me Linux. The Handbooks are really good.
I think that much of early Gentoo ideas - the OpenRC init system, the ports system, the handbooks - were inspired by BSD traditions. OpenBSD and FreeBSD each have good documentation. Working through the FreeBSD handbook, and then study of McKusik's BSD Book [0], are a good way to get another perspective if you get into this sort of thing.
> How the initramfs /init pivots into running your real system's init daemon on your real system's root filesystem is beyond the scope of this entry. The commands may be simple (systemd just runs 'systemctl switch-root'), but how they work is complicated.
Darn, I was actually hoping this would be elaborated on. Does anyone know of other (just as understandable) sources?
For switching to the real root filesystem, you want to read about the pivot_root system call, for example http://man7.org/linux/man-pages/man2/pivot_root.2.html (the usage examples in the pivot_root(8) manpage will help).
When the initramfs PID 1 is something simple like a shell script, I believe it just exec's the real root filesystem /sbin/init after the pivot_root and that init starts from scratch. For Linuxes where systemd is the initramfs init, there's a magic internal protocol to let a running systemd re-exec a new systemd binary while preserving all of its runtime state; this is used, for example, during systemd package upgrades and can be done deliberately with 'systemctl daemon-reexec'.
Both of these share a similar premise - set up and transfer control to an in-memory root filesystem, in order to make major changes to the real root filesystem.
That will get you very verbose logging to the journal, it'll include all the dracut stuff, and systemd setting up jobs and going through all sorts of logic. To read the result:
sudo journalctl -b -o short-monotonic
I prefer monotonic time even though with these two boot options the startup will be significantly slower, it'll give you a better idea of the relative cost of everything than date/time.
dracut does the work. The reason it is complicated is because it supports booting from btrfs, DM RAID, MD RAID, LVM2, device mapper multipath I/O, dm-crypt, cifs, FCoE, iSCSI, NBD and NFS.
Hm, Dracut looks like a userspace framework for building initramfs. I was wondering more about what's going on at the kernel level to switch the root. What depends on / ? Do any processes survive whose CWD is in the initramfs? Later in the article it's pointed out that systemd(from initramfs) passes the torch to systemd(in final root) while preserving state, so are any processes/ressources from the initramfs leftover or is everything cleared?
A process spawned from initramfs can certainly live on but you wouldn't want to do that because that would prevent initramfs from being unmounted. By switching to the new root you can run real binaries. You can also not switch the root and also run real binaries from the new mount but that's not very convenient is it?
Pivoting root is not the complicated. The complicated is the process of detecting and setting up the real root filesystem which can involve loading kernel modules to dhcp negotiation to http requests and more. Dracut handles all these.
What this article fails to mention is that having an initramfs is not required. It's only necessary if additional tools are needed to mount a particular filesystem, otherwise the kernel can run init directly from the root.
I think that was the way for Linux when I were a lad - everything could be compiled into tw kernel to the point the normal / partition could be mounted. Assuming it was under 2gb?
Is it still the case, with UEFI and systemd and other modern things that the damn kids do nowadays?
Yes. I have a systemd-based embedded system that uses initramfs so that I can execute some things out of RAM when I need to erase the root filesystem. The old mechanism was initrd which was an ext2 filesystem that was baked into the kernel. The new system, initramfs uses a CPIO archive instead. But it's basically the same idea.
Early on, Linux supported initrd, which was just a ramdisk with a FS image written to it and mounted. Later, initramfs came along, which is all anyone uses anymore. It is a cpio archive that is extracted onto a special form of tmpfs. One neat trick is that you can append multiple cpio archives, and the kernel will expand them one after another, so you can easily customize your distro-provided initramfs. Only the first one can be compressed, and you have to be careful about it getting overwritten by a kernel update, but it is handy for quick experiments. There is also pivot_root and switch_root, which have man pages if you're interested in the gory details.
For all of initrd/initramfs's history, you've only needed one if your monolithic kernel couldn't mount the root filesystem. So if you needed a module, or had some special config that needed to happen that the kernel couldn't do internally.
Linux has never needed a ramdisk. If it's built with drivers for the boot device and it probes in an unambiguous manner, you can pass root=/dev/whatever99. That's as true today as it was in 1992.
Back in the day, I seem to recall having to binary patch LILO every time I installed a new kernel to tell it what partition to boot. I suppose that dates me...
It's not really that different from how things were 20 years ago. There's a few bells and whistles added now, but for the most part it's still the old sequence.
(added this comment because of the "modern" qualifier in the title)
How much things have changed depends on what level you look at the boot process at. For example, before 2.3.41 introduced the pivot_root system call, the starting process in the initial ramdisk wasn't run as PID 1 (as far as I remember and can tell from the remaining kernel code for this). The kernel also used to be far more willing to do things itself, such as assemble software RAID devices; modern Linux pushes all of that into the initial ramdisk user level code, or even later in boot.
At the broad level, though, yes absolutely. Unixes with System V init have been drawing a distinction between 'single user' boot activities like fsck'ing the filesystems and 'multi-user' ones like starting daemons for a long time, so that's a two stage boot. Linux booting became three stage once it added initial ramdisks so that the core kernel didn't have to have to build in all of the pieces necessary to get the root filesystem.
You did, however, proffer a discussion of the Linux boot process, and Linux operating systems do not and did not have AT&T System 5 init. They have/had something resembling it, written by Miquel van Smoorenburg in the 1990s. But it isn't AT&T System 5 init, and it actively diverged from it early on.
Ironically, 20 years ago was almost three years after van Smoorenburg init+rc had diverged from the old idea of one "single-user" mode and had instead taken the route of two modes, emergency and rescue. In fact, we only need to wait a year or so until it has been 20 years since those names can be found in widespread use. It has already been more than 20 years since the name "emergency" gained traction.
So whilst things are like they were 20 years ago, how things were 20 years ago isn't in fact the old AT&T System 5 world that people nowadays tell one another it was. That was the 1980s, and it wasn't Linux-based. Indeed, by 25 years ago the AT&T world itself had already introduced ideas changing the original model of multi-user login, such as the Service Access Facility.
I have my whole disk encrypted, including swap, and use LVM with BTRFS on top. My key is included in the initramfs. After I type my password in the Grub prompt, it only takes about 60 to 90 seconds to do a full boot. Although, the disk is a SSD. I'm sure if I didn't have a SSD disk, the boot process would take a very long time.
I noticed mine taking much longer than it should, and the reason seemed to be a lot of useless PKDF time. For every disk I had to decrypt, my system went through the LUKS table and tried the keyfile in order. By putting the keyfile entry first in the table and configuring it to minimum PKDF time (just for the keyfile, still millions of sha512 for passwords) my disks all decrypted in a couple seconds.
I probably over estimated a bit, and I only reboot about once a week or so.
I only have the one disk to decrypt, and one key. When I was setting it all up I did run cryptsetup benchmark to choose the best hashing algorithm for my architecture. It ended up to be aes-xts sha256. Has enough iterations for about 2.5 seconds.
I've similarly included my key in the initramfs, until I noticed the initramfs file in /boot is world-readable. (On Linux Mint.) I'm a bit over-paranoid maybe, but I don't want a compromise of my user account turning into compromising my keys. Have you had that issue, and fixed it cleanly? (I could just chmod, but I don't want to have to remember.)
For now, I just enter my password twice -- once for GRUB to load Linux, then again in Linux's early boot. I've been tempted to implement some way for GRUB to pass the key to Linux in RAM, avoiding the need for a key file.
My initramfs is only readable by root (0600). The key is also in a file only readable by root (0600). The key file is added into the initramfs image when it's built.
/boot is also fully encrypted on my system - which includes the initramfs, the backup initramfs, kernel, grub config, etc. /boot/efi is not encrypted, but only has the EFI modules.
The first stage of Grub (not sure one terminology here) knows about LUKS encrypted partitions and how to decrypt them. Only version 1 of the header though - found that out the hard way.
Not the person you're asking, but see this reddit comment[0]
>If you are using a proper private secure boot setup (not the Microsoft keys, signing keys not accessible to an attacker that remotely compromises your system), you trust that your motherboard implements it correctly, you can safely assume nobody is physically tampering with your motherboard and you're using a variant of GRUB that fully implements secure boot, ESP access gives your attacker nothing. They can't change anything there without breaking the system.
If you’re letting GRUB handle the disk decryption then that’s part of your problem. The key derivation function in GRUB is much slower than in Linux.
If possible, switch to an unencrypted boot partition (and rely on Secure Boot to ensure integrity of GRUB and kernels), and only decrypt the encrypted partitions within Linux (more specifically in the initramfs).
I just boot using full root mount encryption (but the /boot & initrd is not encrypted). So it's lame, but it boots super fast (10 seconds including password typing), the main waiting time is to type in the password.
This depends heavily on your security model... Are you trying to use just a literal 'usb key' as a fob for booting the computer?
Decrypting the LUKS key will take some time, but you can ship the key for decrypting that in the initramfs that you'd store with the kernel on the USB drive.
[1] http://holyjoe.org/poetry/foss3.htm