Installing Debian on scubed3 (debian-installer) =============================================== partman-scubed3 adds scubed3 to the partitioner of the debian-installer, in the same way as software RAID, LVM and encrypted volumes: - "Use as:" of a partition has "base device for scubed3 (hidden encrypted partitions)" - the main menu of the partitioner has "Configure scubed3 (hidden encrypted partitions)", next to "Configure software RAID", "Configure the Logical Volume Manager" and "Configure encrypted volumes" (without a base device it says how to make one) "Configure scubed3" writes the partition table, fills the base device with random data (or uses an existing scubed3 store, with its salt), starts the daemon, makes a key store with the boot passphrase and shows a menu to create and open scubed3 partitions (their keys go into the key store). The LUKS volumes on them (/dev/mapper/HOSTNAME-NAME, with the hostname that was asked before partitioning, as LVM names its volumes HOSTNAME--vg-NAME) become disks in the partitioner, the root file system goes on the partition root. At the end of the installation the installed system gets scubed3, its configuration, the key store and an initramfs that asks the boot passphrase as for an encrypted disk and opens the partitions (contrib/initramfs-tools). Files: build-udebs.sh builds the packages (see below) partman-scubed3/lib/scubed3-base.sh functions (sizes, the key store, passphrases, LUKS) partman-scubed3/choose_partition/scubed3 "Configure scubed3" partman-scubed3/choose_method/scubed3 "Use as: base device for scubed3" partman-scubed3/init.d/scubed3 the LUKS volumes become disks partman-scubed3/update.d/scubed3_visuals "scubed3" in the list of partitions partman-scubed3/check.d/scubed3_check no swap or /boot on scubed3, / on root, other file systems on it need / on it partman-scubed3/finish-install.d/08scubed3 scubed3 in the installed system partman-scubed3/templates the questions (English only) dev/installertest.sh tests the scripts in a simulated installer. Installing on scubed3, step by step ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. Partition disks, manual: make a /boot partition (about 1 GB, ext4, not on scubed3: the kernel and the initramfs are read from it), and a partition for scubed3; set "Use as:" of the latter to "base device for scubed3". (An EFI system partition as usual.) 2. Configure scubed3: - the partition table is written - a new store: the partition is filled with random data (from /dev/urandom, with a progress bar; the messages, and an error, are in /var/log/syslog, "partman-scubed3"), a random salt is made and shown (keep a copy); an existing store: its salt and the number of iterations are asked - the key store (it becomes /etc/scubed3.keys): the boot passphrase is asked (twice), the passphrase you type at boot, as for an encrypted disk; it is never generated (the keys of the partitions and of the LUKS volumes are: random, in the key store); then a note: make a backup of the key store and of the configuration (not on this disk) - the menu: create partitions (name, size, LUKS yes/no, which passphrase of the key store, a passphrase of the partition: with it the partition also opens without the key store, both fields empty: a random key, 256 bits), and open existing ones (name, passphrase, the passphrase of the LUKS volume, which passphrase). The keys go into the key store: in the view of the boot passphrase (opened at boot, their LUKS volumes too), or in the view of a hidden passphrase (asked once, twice the first time; another hidden passphrase is another view). The root file system goes on the partition "root", with LUKS: create it (always in the view of the boot passphrase). On an existing store, open ALL its partitions FIRST (a partition that is not open has blocks that look unclaimed: a new partition can get them, and in paranoia level 2 and 3 they are overwritten); an existing partition can be opened with the name root. Create the hidden partitions you want now too. "Show the layout": the base device, the partitions (size, view, LUKS), the unclaimed blocks and the slots of the views in the key store. - finish: the paranoia level during the installation (0, the fastest, to 3; 2 is recommended) and of the installed system; the unclaimed blocks are lent to root (see below); LUKS on the partitions that get it: its passphrase is asked, the one keyslot of the volume (any length; both fields empty: a random key that is not kept), its volume key (random, 512 bits) goes into the key store; the LUKS volumes of the view of the boot passphrase are opened (with the volume key: no KDF) - the KDF of a passphrase takes long (seconds, minutes without KVM): the installer computes it once per passphrase of the key store (keystorectl derive) and keeps the key in its memory (the commands get it with keystorectl -k and scubed3ctl -k: keystorectl changes the key store, with -c save, scubed3ctl uses the keys of one view to create and luksformat the partitions), a message is shown while it runs (also while a partition is opened and while LUKS is set up), its bar moves: to 90% at the duration of the last time (10 seconds the first time), then slower - "Configure scubed3" again: the boot passphrase and the hidden passphrases are asked again (a change of the key store needs all of them) 3. The LUKS volume of root is a disk in the partitioner, with one partition: format with the default file system, mount point /. The other LUKS volumes of the boot passphrase are disks too: a file system on them can be mounted at /home, /srv, ... (they need / on scubed3; the installer shows a note about them, see below). Finish partitioning and install as usual. 4. At the end of the installation (finish-install): - scubed3 in the installed system: the package scubed3 if apt finds it (put it in a local repository, see below), otherwise the programs of the installer are copied to /usr/local/sbin and the initramfs-tools scripts to /etc/initramfs-tools; cryptsetup, cryptsetup-initramfs (with CRYPTSETUP=y in /etc/cryptsetup-initramfs/conf-hook; its askpass asks the boot passphrase) - /etc/scubed3.conf (salt, iterations, paranoia level), the key store /etc/scubed3.keys, and /etc/scubed3/initramfs.conf (BASE, by /dev/disk/by-partuuid if there is one, and the options of the daemon) - update-initramfs - the lent blocks are given back - a note: keep a copy of /etc/scubed3.conf, the options and the key store 5. At boot the initramfs asks one passphrase, as cryptroot asks it for an encrypted disk ("Please unlock disk vda3_crypt:", see contrib/initramfs-tools/README): the boot passphrase. It opens all partitions of the boot passphrase, their LUKS volumes (root, and those of /etc/fstab), switches the paranoia level and boots from root. With hidden partitions: in paranoia level 2 and 3 they must be opened too, type their passphrase first (you get the message of a wrong passphrase, the view is unlocked anyway), then the boot passphrase. /etc/fstab is on the root file system: whoever has the boot passphrase sees that the partitions of the other file systems exist (the key store shows them anyway). Use them for data you can admit to; hidden partitions are never in /etc/fstab. Install on a big partition, give the blocks back afterwards ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In paranoia level 2 and 3 a partition with a fraction f of the blocks of the base device needs on average 1/f block writes for a block of its own data, and the garbage collector copies less when a partition has more free blocks. An installation writes some gigabytes: on a root partition with a tenth of the blocks that is ten times as many block writes. Installing is much faster on a partition that has (almost) all blocks. But a partition cannot simply be made smaller afterwards: shrinking a scubed3 partition cuts off the end of the file system on it, and the root file system cannot be shrunk while it is mounted. So the installer LENDS the blocks: when the menu is finished, the blocks that no partition claims are added to root, the partition you install on, as extra reserved blocks (scubed3 command resize-internal NAME BLOCKS RESERVED with both numbers increased). Its size, and the size of the file system on it, stays what you chose; the extra blocks are room for the garbage collector. At the end of the installation they are given back (resize-internal with the old numbers): the garbage collector of the installed system removes them from the partition in the background, one with every write (in level 3 the clock writes all the time, in level 2 only when the system writes). "scubed3ctl p" shows (shrinking root, N blocks still to be removed) until it is done; then the blocks are unclaimed again, for other (hidden) partitions. Blocks that were never written are given back at once. So: give the root partition the size it needs, with room to grow, not more (it can be enlarged later, also while it is mounted: scubed3ctl resize, losetup -c on the loop device under its LUKS volume, cryptsetup resize, resize2fs); create hidden partitions with the sizes they need; the rest of the base device is lent during the installation. The same works by hand, outside the installer (scubed3 allows a resize of a partition that is in use, as long as it does not become smaller): # scubed3ctl -c "info root" (no_macroblocks=B, reserved_macroblocks=R) # scubed3ctl -c "resize-internal root $((B+N)) $((R+N))" ... write a lot ... # scubed3ctl -c "resize-internal root B R" Building the packages ~~~~~~~~~~~~~~~~~~~~~ On a Debian system of the release you install (the udebs must match the libraries of its installer): # apt install build-essential autoconf automake pkg-config \ libfuse3-dev libgcrypt20-dev libgpg-error-dev \ libreadline-dev dpkg-dev $ contrib/debian-installer/build-udebs.sh OUTDIR builds, with dpkg-deb (no debhelper needed): scubed3-udeb_VERSION_ARCH.udeb the daemon, scubed3ctl and keystorectl (built --without-readline, statically linked: configure --enable-static-programs) and the initramfs-tools scripts, for the installer partman-scubed3_VERSION_all.udeb the partitioner part scubed3_VERSION_ARCH.deb scubed3 for the installed system (the initramfs-tools scripts in /usr/share/initramfs-tools) The programs of scubed3-udeb are statically linked (the static libraries are in libfuse3-dev, libgcrypt20-dev and libgpg-error-dev), so the udeb depends on no library udebs (their names differ between releases); with STATIC=no build-udebs.sh links them dynamically, then scubed3-udeb depends on libfuse3-*-udeb, libgcrypt20-udeb and libgpg-error0-udeb (from dpkg-shlibdeps). partman-scubed3 depends on partman-crypto-dm (cryptsetup, dmsetup, the dm-crypt modules). The kernel modules fuse and loop are not a dependency (the names of their udebs change with the kernel, and they are often in the installer already): "Configure scubed3" loads them (modprobe, or insmod), and says so if fuse is missing. Getting it into the installer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - A custom installer image: put the two udebs in build/localudebs/ of the source of the debian-installer package and build the image (they are then on the image, and the dependencies come from the mirror or the image); or add them to an image made with debian-cd or simple-cdd. - For testing, in a normal installer (expert mode): after the mirror is configured, in a shell (Alt-F2), with the udebs on a USB stick: # anna-install partman-crypto-dm cryptsetup-udeb # udpkg -i /media/scubed3-udeb_*.udeb /media/partman-scubed3_*.udeb # modprobe fuse; modprobe loop (if that fails: insmod fuse, insmod loop) (with STATIC=no also the library udebs, see the Depends of scubed3-udeb). udpkg installs no dependencies: without cryptsetup "Configure scubed3" runs anna-install cryptsetup-udeb (and dmsetup-udeb, crypto-dm-modules), if that fails it says so (LUKS on root needs it). It loads dm-crypt (and xts, aes) itself: a module udeb that anna installs later is not in modules.dep, the kernel cannot load it on demand ("device-mapper: table: crypt: unknown target type"); it runs depmod -a and modprobe, or insmod of the file of the module. Then start "Partition disks" again. The running debconf of the installer may not have the templates of a udeb that is installed by hand (partman then says "partman/method_long/scubed3 doesn't exist"); partman-scubed3 loads them itself, from its copy in /usr/share/partman-scubed3/templates. - The package scubed3 for the installed system: in a local repository that the installer knows (preseed apt-setup/local0/repository), or on the image. Without it, finish-install copies the programs of the installer into the target (they work, scubed3ctl without line editing); install the package later, it replaces them (remove /usr/local/sbin/scubed3* and the scripts in /etc/initramfs-tools then). Preseeding: partman-scubed3/options (the options of the daemon, -m and -M, default: chosen for the size of the base device), partman-scubed3/level, partman-scubed3/boot_level. The passphrases are always asked. Limitations ~~~~~~~~~~~ - This was tested in a simulated installer (dev/installertest.sh: the scripts with stand-ins for debconf, partman's library and cryptsetup), NOT in a real installation yet; please report problems. - Other file systems on scubed3 (/home, ...) need the root file system on scubed3 (the initramfs starts scubed3 only then). No swap and no /boot on scubed3. - One base device. The base device cannot be changed after "Configure scubed3" (the daemon runs on it). - The partition you install on is root, with LUKS on it (the LUKS volume is the disk in the partitioner). - The passphrases of the key store are kept in memory while "Configure scubed3" runs (they are asked again when it is chosen again); the LUKS passphrase of an existing partition is in a file in /var/lib/partman for a moment (it is checked with cryptsetup). - The shell of the installer must have 64 bit arithmetic (busybox with FEATURE_SH_MATH_64, the default), partman-scubed3 checks it. - The questions are in English only. - See also Limitations in contrib/initramfs-tools/README (no swap on scubed3, avoid running out of memory, level 3 limits the root file system too).