<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>systemd &amp;mdash; Sebastian Wiesner</title>
    <link>https://swsnr.writeas.com/tag:systemd</link>
    <description>System engineer for satellite mission planning. Gnome. Rust. Arch.  </description>
    <pubDate>Mon, 10 Aug 2026 08:53:58 +0000</pubDate>
    <image>
      <url>https://i.snap.as/9knB2j11.jpg</url>
      <title>systemd &amp;mdash; Sebastian Wiesner</title>
      <link>https://swsnr.writeas.com/tag:systemd</link>
    </image>
    <item>
      <title>logcontrol – an underappreciated systemd feature</title>
      <link>https://swsnr.writeas.com/logcontrol-an-underappreciated-systemd-feature?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[#systemd #rust&#xA;&#xA;Systemd has this feature which lets you change the log level of a service on the fly.  You can actually do this:&#xA;&#xA;$ sudo systemctl service-log-level systemd-resolved.service debug&#xA;$ resolvectl query some-funky-domain.example.com&#xA;$ sudo systemctl service-log-level systemd-resolved.service info&#xA;&#xA;to get a debug log of systemd-resolved trying to resolve a specific domain.&#xA;&#xA;This is backed by dbus: If a service listens on dbus and has its bus name defined in its unit file then it can expose the log control interface on its bus connection to let systemctl change its log level and log target.&#xA;&#xA;All of systemd&#39;s own services support this interface, but unfortunately it hasn&#39;t seen wide-spread adoption outside systemd yet.  Which is kinda sad, because it&#39;s really a great feature for debugging.&#xA;&#xA;I certainly plan to use it more, so I put up logcontrol.rs on crates.io.&#xA;&#xA;a href=&#34;https://remark.as/p/swsnr/logcontrol-an-underappreciated-systemd-feature&#34;Discuss.../a]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://swsnr.writeas.com/tag:systemd" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">systemd</span></a> <a href="https://swsnr.writeas.com/tag:rust" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">rust</span></a></p>

<p>Systemd has this feature which lets you change the log level of a service on the fly.  You can actually do this:</p>

<pre><code class="language-console">$ sudo systemctl service-log-level systemd-resolved.service debug
$ resolvectl query some-funky-domain.example.com
$ sudo systemctl service-log-level systemd-resolved.service info
</code></pre>

<p>to get a debug log of systemd-resolved trying to resolve a specific domain.</p>

<p>This is backed by dbus: If a service listens on dbus and has its bus name defined in its unit file then it can expose the <a href="https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.LogControl1.html" rel="nofollow">log control interface</a> on its bus connection to let systemctl change its log level and log target.</p>

<p>All of systemd&#39;s own services support this interface, but unfortunately it hasn&#39;t seen wide-spread adoption outside systemd yet.  Which is kinda sad, because it&#39;s really a great feature for debugging.</p>

<p>I certainly plan to use it more, so I put up <a href="https://github.com/swsnr/logcontrol.rs" rel="nofollow">logcontrol.rs</a> on crates.io.</p>

<p><a href="https://remark.as/p/swsnr/logcontrol-an-underappreciated-systemd-feature" rel="nofollow">Discuss...</a></p>
]]></content:encoded>
      <guid>https://swsnr.writeas.com/logcontrol-an-underappreciated-systemd-feature</guid>
      <pubDate>Wed, 25 Oct 2023 19:00:18 +0000</pubDate>
    </item>
    <item>
      <title>Install Arch with Secure boot, TPM2-based LUKS encryption, and systemd-homed</title>
      <link>https://swsnr.writeas.com/install-arch-with-secure-boot-tpm2-based-luks-encryption-and-systemd-homed?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[#archlinux #systemd #secureboot #dracut #sbctl&#xA;&#xA;a href=&#34;https://remark.as/p/swsnr/install-arch-with-secure-boot-tpm2-based-luks-encryption-and-systemd-homed&#34;Discuss.../a &#xA;&#xA;Update: I no longer use dracut, and the corresponding part of this blog&#xA;post no longer reflects my setup.&#xA;&#xA;This article describes my Arch Linux setup which combines Secure Boot with custom keys, TPM2-based full disk encryption and systemd-homed into a fully encrypted and authenticated, yet convenient Linux system.&#xA;&#xA;This setup draws inspiration from Authenticated Boot and Disk Encryption on Linux and Unlocking LUKS2 volumes with TPM2, FIDO2, PKCS#11 Security Hardware on systemd 248 by Lennart Poettering, and combines my previous posts on these topics.&#xA;&#xA;!--more--&#xA;&#xA;What this setup does&#xA;&#xA;Authenticate the boot loader, kernel, initramfs, microcode with Secure Boot, using my own custom keys.  Nothing can boot which wasn’t signed by my keys.&#xA;Everything is either authenticated with my keys (kernel, initramfs, microcode) or encrypted (system partition).&#xA;Encrypt the system partition, and unlock it automatically if the boot process was authenticated, by means of a TPM2 key bound to the secure boot state.&#xA;Give every user their own dedicated encrypted home directory, which gets unlocked at login and locked again at logout.&#xA;&#xA;What it doesn’t&#xA;&#xA;Show an ugly LUKS password prompt at boot (even with Plymouth it’s not really pretty).&#xA;Leave some parts unencrypted and unauthenticated (conventional installations often fail to consider the initramfs).&#xA;Ask me twice for my password, once at boot to unlock the disk and then again at login.&#xA;Encrypt data of all users with a shared key.&#xA;&#xA;Tools used&#xA;&#xA;Archlinux&#xA;systemd   = 250&#xA;systemd-boot as bootloader&#xA;systemd in initramfs to automatically discover and mount the root filesystem&#xA;dracut to generate the initramfs and build signed UEFI binaries&#xA;sbctl to create and enroll Secure Boot keys, and sign binaries&#xA;systemd-homed to manage user accounts with per-user encrypted home directories&#xA;systemd-cryptenroll to add TPM2 and recovery keys tokens to a LUKS partition&#xA;&#xA;The setup&#xA;&#xA;Install the system&#xA;&#xA;We follow the Installation Guide up to and including section “Update the system clock”. Then we partition the disk (/dev/nvme0n1 in our case); we need an EFI system partition of about 500MB and a root partition spanning the rest of the disk. The EFI partition must be unencrypted and have a FAT filesystem; for the root file system we choose btrfs on top of an encrypted partition.&#xA;&#xA;First we partition the disk and reload the partition table; we take care to specify proper partition types (-t option) so that systemd can automatically discover and mount our filesystems without further configuration in /etc/crypttab or /etc/fstab (see Discoverable Partitions Specification (DPS)):&#xA;&#xA;$ targetdevice=/dev/nvme0n1&#xA;$ sgdisk -Z &#34;$targetdevice&#34;&#xA;$ sgdisk -n1:0:+550M -t1:ef00 -c1:EFISYSTEM -N2 -t2:8304 -c2:linux &#34;$targetdevice&#34;&#xA;$ sleep 3&#xA;$ partprobe -s &#34;$targetdevice&#34;&#xA;$ sleep 3&#xA;&#xA;Then we setup the encrypted partition for the root file system. We get asked for an encryption password where we pick a very simple encryption password (even “password” is good enough for now, really) to save some typing during installation, as we’ll later replace the password with TPM2 key and a random recovery key:&#xA;&#xA;$ cryptsetup luksFormat --type luks2 /dev/disk/by-partlabel/linux&#xA;$ cryptsetup luksOpen /dev/disk/by-partlabel/linux root&#xA;$ rootdevice=/dev/mapper/root&#xA;&#xA;Now we create the filesystems:&#xA;&#xA;$ mkfs.fat -F32 -n EFISYSTEM /dev/disk/by-partlabel/EFISYSTEM&#xA;$ mkfs.btrfs -f -L linux &#34;$rootdevice&#34;&#xA;&#xA;Now we can mount the filesystems and create some basic btrfs subvolumes:&#xA;&#xA;$ mount &#34;$rootdevice&#34; /mnt&#xA;$ mkdir /mnt/efi&#xA;$ mount /dev/disk/by-partlabel/EFISYSTEM /mnt/efi&#xA;$ for subvol in var var/log var/cache var/tmp srv home; do btrfs subvolume create &#34;/mnt/$subvol&#34;; done&#xA;&#xA;Now we’re ready to bootstrap Arch Linux: We generate a mirrorlist and install essential packages:&#xA;&#xA;$ reflector --save /etc/pacman.d/mirrorlist --protocol https --latest 5 --sort age&#xA;$ pacstrap /mnt base linux linux-firmware intel-ucode btrfs-progs dracut neovim&#xA;&#xA;This takes a while to download and installation all packages; afterwards we configure some essential settings. Choose locale settings and the $newhostname according to your personal preferences.&#xA;&#xA;$ ln -sf /usr/share/zoneinfo/Europe/Berlin /mnt/etc/localtime&#xA;$ sed -i -e &#39;/^#enGB.UTF-8/s/^#//&#39; /mnt/etc/locale.gen&#xA;$ echo &#39;LANG=enGB.UTF-8&#39;   /mnt/etc/locale.conf&#xA;$ echo &#39;KEYMAP=us&#39;   /mnt/etc/vconsole.conf&#xA;$ echo &#34;$newhostname&#34;   /mnt/etc/hostname&#xA;&#xA;Now we enter the new system and finish configuration by generating locales, enabling a few essential services and setting a root password:&#xA;&#xA;$ arch-chroot /mnt&#xA;$ locale-gen&#xA;$ systemctl enable systemd-homed&#xA;$ systemctl enable systemd-timesyncd&#xA;$ passwd root&#xA;&#xA;Still in chroot we now build unified EFI kernel images (including initrd and kernel) for booting and install the systemd-boot boot loader:&#xA;&#xA;$ pacman -S --noconfirm --asdeps binutils elfutils&#xA;$ dracut -f --uefi --regenerate-all&#xA;$ bootctl install&#xA;&#xA;We do not need to create /etc/fstab or /etc/crypttab; as we assigned the appropriate types to each partition and installed systemd-boot a systemd-based initramfs can automatically determine the disk the system was booted from, and discover all relevant partitions.  It can then use superblock information to automatically open encrypted LUKS devices and mount file systems.&#xA;&#xA;At this point we also need to take care to install everything we need for network configuration after reboot.  For desktop systems I prefer network manager because it integrates well into Gnome:&#xA;&#xA;$ pacman -S networkmanager&#xA;&#xA;We have finished the basic setup from the live disk now; let’s leave chroot and reboot:&#xA;&#xA;$ exit&#xA;$ reboot&#xA;&#xA;After reboot we can complete the system installation, by adding a desktop environment, applications, command line tools, etc.&#xA;&#xA;I like to automate this, and have two bash scripts in my dotfiles, one for boostrapping a new system from a live disk (arch/bootstrap-from-iso.bash) and another one for installing everything after the initial bootstrapping (arch/install.bash).&#xA;&#xA;Create homed user&#xA;&#xA;With the installation finished we create our user account with homectl; let’s name it foo for the purpose of this article. First we should disable copy on write for /home, because this file system feature doesn’t work well with large files frequently updated in place, such as disk images of virtual machines or loopback files as created by systemd-homed:&#xA;&#xA;$ chattr +C /home/&#xA;&#xA;We now create the foo user with an encrypted home directory backed by LUKS and btrfs:&#xA;&#xA;$ homectl create foo --storage luks --fs-type btrfs&#xA;&#xA;By default systemd assigns 85% of the available disk space to the user account, and will balance available space among all user accounts (based on a weight we can configure with —rebalance-weight). On a single user system we may prefer to set an explicit quota for the user account:&#xA;&#xA;$ homectl resize foo 50G&#xA;&#xA;We can also add some additional metadata to the user account:&#xA;&#xA;homectl update foo --real-name &#39;Foo&#39; --email-address foo@example.org --language enGB.UTF-8 --member-of wheel&#xA;&#xA;man homectl provides a complete list of flags; in particular it also offers support for various kinds of security tokens (e.g. FIDO2) for user authentication, provides plenty of means for resource accounting (e.g. memory consumption) for the user account, and supports different kinds of password policies.&#xA;&#xA;Finally we may run into systemd issues with home areas on btrfs (see below); if login fails with a “Operation on home failed: Not enough disk space for home” message we need to enable LUKS discard:&#xA;&#xA;homectl update foo --luks-discard=true&#xA;&#xA;This flag is not safe (heed the warning in man homectl), but until systemd improves its behaviour on btrfs we have no choice unfortunately.&#xA;&#xA;Setup secure boot&#xA;&#xA;First let’s check the secure boot state. We must be in Setup Mode in order to enroll our own keys:&#xA;&#xA;$ sbctl status&#xA;Installed:&#x9;✓ sbctl is installed&#xA;Owner GUID:&#x9;REDACTED&#xA;Setup Mode:&#x9;✗ Enabled&#xA;Secure Boot:&#x9;✗ Disabled&#xA;&#xA;To enable secure boot we need some keys which we generate with sbctl.  For historical reasons sbctl creates these keys in /usr/share/secureboot but plans exists to change this to a more appropriate place (see Github issue 57).&#xA;&#xA;$ sbctl create-keys&#xA;&#xA;Now we tell dracut how to sign the UEFI binaries it builds and rebuild our kernel images to get them signed:&#xA;&#xA;$ cat   /etc/dracut.conf.d/50-secure-boot.conf &lt;&lt;EOF&#xA;uefisecurebootcert=&#34;/usr/share/secureboot/keys/db/db.pem&#34;&#xA;uefisecurebootkey=&#34;/usr/share/secureboot/keys/db/db.key&#34;&#xA;EOF&#xA;$ dracut -f --uefi --regenerate-all&#xA;&#xA;Next we need to sign the bootloader.  With -s we ask sbctl to remember this file in its database which later lets us check signatures with sbctl verify and automatically update all signatures with sbctl sign-all. The sbctl package includes a pacman hook which automatically updates signatures when an EFI binary on /efi or in /usr/lib changed. Note that we do not sign the boot loader on /efi but instead place a signed copy in /usr/lib.  Starting with systemd 250 bootctl will pick up the signed copy when updating the boot loader.  Hence we reinstall the bootloader afterwards to put the signed copy on /efi.&#xA;&#xA;$ sbctl sign -s -o /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed /usr/lib/systemd/boot/efi/systemd-bootx64.efi&#xA;$ bootctl install&#xA;&#xA;We should also do the same for the firmware update to enable seamless firmware updates under secure boot.  Again we use -s to remember this file in the sbtctl database:&#xA;&#xA;$ sbctl sign -s -o /usr/lib/fwupd/efi/fwupdx64.efi.signed /usr/lib/fwupd/efi/fwupdx64.efi&#xA;&#xA;Now let’s verify that we have all signatures in place and enroll keys if everything’s properly signed:&#xA;&#xA;$ sbctl verify&#xA;Verifying file database and EFI images in /efi...&#xA;✓ /usr/lib/fwupd/efi/fwupdx64.efi.signed is signed&#xA;✓ /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed is signed&#xA;✓ /efi/EFI/BOOT/BOOTX64.EFI is signed&#xA;✓ /efi/EFI/Linux/linux-5.15.12-arch1-1-19ea0ebee1ea4de086128ce1a8e2197b-rolling.efi is signed&#xA;✓ /efi/EFI/systemd/systemd-bootx64.efi is signed&#xA;$ sbctl enroll-keys&#xA;&#xA;After a reboot we can check the secure boot state again; we’ll see that setup mode is now disabled, secure boot is on, and everything was properly enrolled:&#xA;&#xA;$ reboot&#xA;$ sbctl status&#xA;Installed:&#x9;✓ sbctl is installed&#xA;Owner GUID:&#x9;REDACTED&#xA;Setup Mode:&#x9;✓ Disabled&#xA;Secure Boot:&#x9;✓ Enabled&#xA;&#xA;Enroll TPM2 keys&#xA;&#xA;With the boot process secured we can now configure automatic unlocking of the root filesystem, by binding a LUKS key to the TPM.&#xA;&#xA;We enable the tpm2-tss module in the Dracut configuration, install the dependencies of this dracut module, and regenerate our UEFI kernel images (which will again be signed for secure boot):&#xA;&#xA;$ cat   /etc/dracut.conf.d/50-tpm2.conf &lt;&lt;EOF&#xA;adddracutmodules+=&#34; tpm2-tss &#34;&#xA;EOF&#xA;$ pacman -S tpm2-tools&#xA;$ dracut -f --uefi --regenerate-all&#xA;&#xA;Now we can enroll a TPM2 token (bound to the secure boot measurement in PCR 7) and a recovery key to our root filesystem. This prompts for an existing passphrase each time.  Store the recovery key at a safe place outside of this disk, to have it at hand if TPM2 unlocking ever breaks.&#xA;&#xA;$ systemd-cryptenroll /dev/gpt-auto-root-luks --recovery-key&#xA;$ systemd-cryptenroll /dev/gpt-auto-root-luks --tpm2-device=auto&#xA;&#xA;Now reboot and enjoy: The boot process goes straight all t