[TUHS] Unix install & "standalone" package

Steffen Nurpmeso steffen at sdaoden.eu
Sun Sep 10 08:43:12 AEST 2023


Steffen Nurpmeso wrote in
 <20230908233854.Xni_j%steffen at sdaoden.eu>:
 |Michael Kjörling wrote in
 | <f948d06c-14f4-40bd-8e32-4db1c5b1dd21 at home.arpa>:
 ||On 5 Sep 2023 17:53 +0200, from steffen at sdaoden.eu (Steffen Nurpmeso):
 ...
 ||> Of course i am no real Linux expert but only a do-it-yourself guy.
 ||
 ||If your need is restricted to a highly specific use case and you are
 ||trying to keep it as small as possible, then it should be possible to
 ...

Actually maybe someone may find it funny, even though it is
neither historic nor very sophisticated.  Let me post it.
In the end it takes some time to get there.


I would expect almost all of you will not be interested in the
lengthy rest of this mail.
Ciao, and a nice Sunday i wish from Germany!


All you need are statically linked busybox (and cryptsetup with
encryption), and a kernel with EFI_STUB on the EFI partition, so
it can be booted directly.  The distribution kernels i have
(ArchLinux, AlpineLinux) have it enabled; if your EFI is large
enough you could simply copy it and all its masses of modules to
EFI.

Otherwise the kernel needs all the firmware and modules to boot
and to access all filesystems where the real stuff is.  My own
kernel has a lot of things statically built-in, but it can load
more via modules (stage2 uses "the same" kernel later, and does).
Kernels on stage2 need kexec, i have

  CONFIG_KEXEC=y
  CONFIG_KEXEC_FILE=y
  CONFIG_ARCH_HAS_KEXEC_PURGATORY=y
  # CONFIG_KEXEC_SIG is not set
  CONFIG_KEXEC_CORE=y

-s1.sh and -s2.sh are docu-commented at the top; they can also be
used to create the necessary environment.  If i recall correctly

  cd /boot
  sh linit-init-s2.sh PATH-TO-BUSYBOX PATH-TO-CRYPTSETUP
  mount EFI-PARTITION
  cd EFI-PARTITION
  sh linit-init-s1.sh PATH-TO-BUSYBOX PATH-TO-CRYPTSETUP

This only creates files and directories etc, and beat me if it
does any harm otherwise.

I use a specific naming scheme, the script reacts in particular
on -old and -new to select sensible defaults.

  #?0|kent:/boot# ll ideapad*.efi
  -rwxr-xr-x 1 root root 10112672 Aug 26 18:44 ideapad-stage1.efi*
  -rw-r--r-- 1 root root 10120512 Sep  2 19:52 ideapad-6_1.efi
  -rw-r--r-- 1 root root 10120512 Sep  9 18:18 ideapad-6_1-old.efi
  -rw-r--r-- 1 root root 10121376 Sep  9 18:18 ideapad-6_1-new.efi

That very kernel (series) is in fact shared in between several
computers of a similar series, kent is the one i write this on:

  #?1|kent:/boot# v kent.sh
  #!/busybox.static sh
  #@ kent, step 1., via EFI.
  PART_ROOT=/dev/nvme0n1p?
  ROOT_DECRYPT='-t btrfs -o defaults,subvol=/crux/kent/root'
  	PART_ROOT1=/dev/nvme0n1p8
  	ROOT_DECRYPT1='-t btrfs -o defaults,subvol=/crux/kent/root.old'
  INIT_S2=/boot/kent-2.sh
  . /linux-init-s1.sh

  #?0|kent:/boot# v kent-2.sh
  #@ kent, stage 2
  KERNEL_ID=ideapad

^ restrict kernel selection for kexec:
^      	[ "${k##*$KERNEL_ID-*.efi}" != "$k" ] || continue

  PART_SWAP=/dev/nvme0n1p6
  SWAP_INPUT=y

^ you can have additional interactive random for swap encryption
^ (it is a lie i use that in practice)

  INITRD_PATH=/boot/.kent.initrd
  KEXEC_ARGS="--append=\"rtw88_pci.disable_aspm=1 rc.hostname=kent\""
  FILE_CHECK='kent-direct.sh kent.sh ideapad-stage1.efi'
  SWITCH_ROOT=media/initrd

Stage 2 config file is sourced automatically, so no need to source
linux-init-s2.sh yourself (stage 2 uses switch_root).
I also have a direct boot, but have not used it for long:

  #?0|kent:~# v /boot/kent-direct.sh
  #!/busybox.static sh
  #@ kent-direct, sole step 1., via EFI.
  PART_ROOT=/dev/nvme0n1p8
  ROOT_DECRYPT='-t btrfs -o defaults,subvol=/crux/kent/root'
  	PART_ROOT1=/dev/nvme0n1p8
  	ROOT_DECRYPT1='-t btrfs -o defaults,subvol=/crux/kent/root.old'
  PART_SWAP=/dev/nvme0n1p6
  PIVOT_OLDROOT=media/initrd
  . /linux-init-s1.sh

This does not use kexec, but only pivot_root's to the decrypted
filesystem, starting sbin/init there.  The kernel from EFI
continues to run.

It is pretty cool how i now can drive several computers easily
simply by creating a shell script with some variable assignments.
In fact the filesystem is shared in between multiple computers
(with only selective partitions being truly unique, but still
backed up everywhere), and all those text configs are in /boot.
Only the VFAT EFI partition is truly system-specific (ie, in that
it only holds the stage1 config file for $HOSTNAME).

I like that very much, and hope Linux continues to be so flexible.
(Not that one day you need systemd-early to get into Linux to get
to systemd-later, or something.)

The EFI boot is driven via efibootmgr(8) and has config like

  #@ /root/hosts/self/efiboot
  d=/dev/nvme0n1p1
  maxno=1

  b1=0x01  L1=kent  l1=ideapad-stage1
  u1='root='${d}' rootfstype=vfat init=/kent.sh'

driven by /root/bin/efiboot.sh (shortened):

  #!/bin/sh
  : ${HOSTNAME:=$(uname -n)}
  : ${DBG:=}
  if [ -f /root/hosts/${HOSTNAME}/efiboot ]; then
          . /root/hosts/${HOSTNAME}/efiboot
  else
          echo >&2 "MISS /root/hosts/${HOSTNAME}/efiboot"
          exit 1
  fi
  if [ "$1" = create ]; then
          obo=$(efibootmgr | grep -E ^BootOrder: | sed -E 's/^BootOrder:[[:space:]]*//')
          if [ -z "$obo" ]; then
                  echo >&2 'Cannot determine previous boot order'
                  exit 1
          fi
          nbo= i=1
          while [ $i -le $maxno ]; do
                  eval ${DBG} efibootmgr -c -b \$b$i -L \\\"\$L$i\\\" -d \$d$i -l \\\"\$l$i.efi\\\" -u \\\"\$u$i\\\" #>/dev/null
                  [ -n "$nbo" ] && nbo=$nbo,
                  eval nbo=\$nbo\$b$i
                  i=$((i + 1))
          done
          ${DBG} efibootmgr -o $nbo,$obo #> /dev/null
  elif [ "$1" = delete ]; then
          i=1
          while [ $i -le $maxno ]; do
                  eval ${DBG} efibootmgr -B -b \$b$i #>/dev/null
                  i=$((i + 1))
          done
  else
          echo >&2 'Synsopsis: efiboot.sh create|delete'
          exit 1
  fi

  ${DBG} efibootmgr -v -u

This is of course git managed, so i can distribute it easily.
(Further even, the entire ideapad series configurations differ in
only 193 lines, and most of those are the different SSH keys.
The rest are different device names, ie network, display, volume
etc, disk partitions, host names.)

I am pretty lucky i found a way to manage my systems like this.
I have several git branches in root.git, linux.kconfig, bin,
iwd.network, and one for each computer.  I can then "git merge"
selectively together what is necessary.  For example my web
vserver only needs bin and its own configuration, whereas the
laptops also need iwd.network.  Etc etc.  Like this every computer
only knows the selective minimum.  The full git repo is on an
encrypted volume stored away.
And it is not Puppet or Ansible or any of those programs, it is
nothing but git and its branches.
But now i really left manually driven cryptsetup by far.
Ciao!

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: linux-init-s1.sh
Type: application/x-sh
Size: 4596 bytes
Desc: not available
URL: <http://www.tuhs.org/pipermail/tuhs/attachments/20230910/029cbe2a/attachment.sh>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: linux-init-s2.sh
Type: application/x-sh
Size: 7186 bytes
Desc: not available
URL: <http://www.tuhs.org/pipermail/tuhs/attachments/20230910/029cbe2a/attachment-0001.sh>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: linux-init-lib.sh
Type: application/x-sh
Size: 3646 bytes
Desc: not available
URL: <http://www.tuhs.org/pipermail/tuhs/attachments/20230910/029cbe2a/attachment-0002.sh>


More information about the TUHS mailing list