# Network booting without GRUB https://www.youtube.com/watch?v=U3RC20ANomk `apt install dnsmasq` `/etc/dnsmasq.conf` ``` interface=,lo bind-interfaces dhcp-range=,192.168.11.101,192.168.11.200 dhcp-boot=pxelinux.0 dhcp-match=set:efi-x86_64,option:client-arch,7 dhcp-boot=tag:efi-x86_64,syslinux.efi enable-tftp tftp-root=/srv/tftp ``` `mkdir -p /srv/tftp` `apt install syslinux-common syslinux-efi` `cd /usr/lib/syslinux/modules/efi64` `cp ldlinux.e64 libutil.c32 menu.c32 /srv/tftp` `cp /usr/lib/SYSLINUX.EFI/efi64/syslinux.efi /srv/tftp` `mkdir /srv/tftp/pxelinux.cfg` `/srv/tftp/pxelinux.cfg/default` ``` UI menu.c32 LABEL FIKS OS MENU LABEL FIKS KERNEL vmlinuz APPEND initrd=initrd.img debug components boot=nfs ip=dhcp root=/dev/nfs nfsroot=192.168.11.11:/srv/nfs/live/ ro TEXT HELP Lmao Yeet! ENDTEXT ``` `systemctl restart dnsmasq.service` `apt install nfs-kernel-server` `mkdir -p /srv/nfs/live` `/etc/exports` ``` /srv/nfs *(ro,sync,no_root_squash,no_subtree_check) ``` `exportfs -a` `systemctl restart nfs-kernel-server` ## Client system ### Image itself Disable systemd-resolved (requires writable /etc/resolve.conf): `systemctl mask systemd-resolved.service` `systemctl mask systemd-hostnamed.service` `systemctl mask systemd-timesyncd.service` `systemctl mask systemd-update-utmp.service` `systemctl mask systemd-update-utmp-runlevel.service` `systemctl mask ModemManager.service` `systemctl mask man-db.service` `systemctl mask logrotate.service` `systemctl mask grub-initrd-fallback.service` `systemctl mask grub-common.service` `systemctl mask snapd` `systemctl enable tmp.mount` ### Initrd `mkdir initrd-workdir && cd initrd-workdir` `unmkinitramfs /boot/initrd.img-$(uname -r) .` `cd main` `/etc/initramfs-tools/modules` ``` e1000 igb r8169 nfs nfsv3 nfsv4 sunrpc lockd fscache overlay ``` https://www.onlogic.com/blog/how-to-build-a-read-only-linux-system/ `/etc/initramfs-tools/hooks/ro_root` ```bash #!/bin/sh PREREQ='' prereqs() { echo "$PREREQ" } case $1 in prereqs) prereqs exit 0 ;; esac . /usr/share/initramfs-tools/hook-functions manual_add_modules aufs manual_add_modules tmpfs copy_exec /bin/chmod /bin ``` `/etc/initramfs-tools/scripts/init-bottom/ro_root` ```bash #!/bin/sh PREREQ='' prereqs() { echo "$PREREQ" } case $1 in prereqs) prereqs exit 0 ;; esac ro_mount_point="${rootmnt%/}.ro" rw_mount_point="${rootmnt%/}.rw" # Create mount points for the read-only and read/write layers: mkdir "${ro_mount_point}" "${rw_mount_point}" # Move the already-mounted root filesystem to the ro mount point: mount --move "${rootmnt}" "${ro_mount_point}" # Mount the read/write filesystem: mount -t tmpfs root.rw "${rw_mount_point}" # Mount the union: mount -t aufs -o "dirs=${rw_mount_point}=rw:${ro_mount_point}=ro" root.union "${rootmnt}" # Correct the permissions of /: chmod 755 "${rootmnt}" # Make sure the individual ro and rw mounts are accessible from within the root # once the union is assumed as /. This makes it possible to access the # component filesystems individually. mkdir "${rootmnt}/ro" "${rootmnt}/rw" mount --bind "${ro_mount_point}" "${rootmnt}/ro" mount --bind "${rw_mount_point}" "${rootmnt}/rw" ``` `update-initramfs -u` `scp initrd.img server@192.168.11.11:/srv/nfs/` `mksquashfs / /opt/fiks-image.squashfs -e /proc /sys /dev /tmp /run /mnt /media /var/cache /var/tmp /opt` ## Back on the server `mount -o loop /srv/nfs/fiks-image.squashfs /srv/nfs/tmp/` `cp -a /srv/nfs/tmp/* /srv/nfs/live/` `mkdir -p live/{dev,proc,run,sys,tmp}` `mkdir -p live/var/tmp` `etc/fstab` ``` 192.168.11.11:/srv/nfs/live / nfs nolock,ro 0 0 tmpfs /var/tmp tmpfs defaults,nosuid,nodev,mode=1777,size=64M 0 1 ```