This is the first page of my wiki



Stuff I have been thinking about. General Linux stuff, personal stuff, Arch Linux stuff.

Extend kernel PCR with cmdline

The kernel doesn't checksum the cmdline which would be practical when we are already doing the vmlinuz image


Rewrite efibootmgr in go with go-uefi and improve usability.


Move pacman DbPath to /usr.


Implement .d directory overrides to hooks. We want to consolidate the hooks from several packages.

Kernel module signing

Just generally; how do we solve this without getting tied to a MOK?

Archweb nvchecker integration

Consider nvchecker;

All repositories can have a .NVCHECKER file like below;

source = "github"
github = "golang/go"
prefix = "go"
use_max_tag = true
exclude_regex = ".*(release|weekly|rc|alpha|beta).*"

The top part would be $pkgbase and rest of the configuration follows the nvchecker documentation.

The implementaiton for archweb would be a timer running "python nvchecker" which iterates over all PKGBASEs archweb know about.

We'd look up the following url;

If this file exists we fetch the pkgname, pkgver and the .NVCHECKER file.

We run nvchecker (how this is done.. not sure!) on this and flag OOD if there is a change.


  • How do we deal with secrets? Do we want to deal with secrets?
  • Timer could be once pr day
  • Configurable?

Witness logs

  • monitor
  • lvfs monitor


Misc ideas for sigstore


Needs a monitor given a type and upstream

Migrate transparency log?

Needs git-push certificate support

.pkg.tar support

Native support for pacman, obviously :)

Arch Linux

  • Fix ls-tags for reference replacing

  • repo should take a build order

  • Rewrite repo and buildpkg into Python

  • borg python-packaging new dependency

  • pull-requests in repro

  • crun might need crio as makedepend


  • Missing doc in the example.preset

Python2 drop packages

  • python2-importlib-metadata - remove checkdepend
  • python2-cheroot - no tests
  • python2-requests - remove optional deps
  • python2-urllib3 - remove optional deps
  • python2-dnspython - optional deps
  • python2-cherrypy - remove
  • python2-docutils - remove
  • python2-portend - remove
  • python2-tempora - remove
  • python2-jaraco - remove
  • python2-cheroot - remove
  • python2-selectors2 - remove (after offlineimap)
  • python2-backports.unittest_mock - remove


  • seamonkey - supports python3

Package notes

Updating a go dependency in go.sum

$ go mod edit -replace
$ go mod tidy
$ git diff > go-sum.patch


Note: This is not an install guide. Purely personal notes.

Two partition: gdisk /dev/nvme0n1

  • EFI system partition (ESP)
    • 512M
    • GPT GUID: EF00
  • System partition
    • all available disk
    • GPT GUID: 8304

Important to remember GPT GUIDs since we are using systemd initramfs and discoverable partitions for booting. Relevant for the initramfs section.

  • mkfs.vfat -F32 /dev/nvme0n1p1
  • cryptsetup luksFormat /dev/nvme0n1p2
  • cryptsetup open /dev/nvme0n1p2 root
  • cryptsetup --perf-no_read_workqueue --perf-no_write_workqueue --allow-discards --persistent refresh root
  • mkfs.btrfs /dev/mapper/root

We also add support

btrfs subvolumes

This list is currently inspired by the opensuse BTRFS setup.

  • /@root
  • /home@home
  • /srv@srv
  • /var@var

Note that we are adding @root-snapshots and @home-snapshots for snapper. But later.

Now we are making all the subvolumes. I like doing them on a pivot partitions. We don't care about access time and rest of the flags should be applied by btrfs automatically.

  • mkdir /mnt_tmp
  • mount -o noatime,compress=zstd /dev/mapper/root /mnt_tmp
  • btrfs subvolume create /mnt_tmp/@root

Create for each partition under /mnt_tmp, then umount /mnt_tmp. We also use btrfs subvolume set-default 256 / for systemd initramfs to specify the root subvolume.

Later if we DO need to mount the actual root we need to specify the subvolid 5 which is a magic number: mount -osubvolid=5 /dev/mapper/root /var/btrfs

Then mount each respective directory to /mnt. Don't forget to mount /dev/nvme0n1p1 to /efi.

  • mount -o noatime,compress=zstd,subvol=@root /dev/mapper/root /mnt
  • mount -o noatime,compress=zstd,subvol=@var /dev/mapper/root /mnt/var
  • mount -o noatime,compress=zstd,subvol=@srv /dev/mapper/root /mnt/srv
  • mkdir /mnt/efi
  • mount /dev/nvme0n1p1 /mnt/efi

We mount /dev/nvme0n1p1 to /mnt/efi because we are using the new UEFI stub system for mkinitcpio. See next section :)

This is the base packages. Rest are pulled inn by my system packages.

pacstrap /mnt base base-devel linux linux-firmware btrfs-progs

Create fstab: genfstab -U /mnt >> /mnt/etc/fstab

initramfs - systemd

We do the systemd enabled initramfs. This allows us to simplify boot with discoverable partitions as we used the proper GPT GUIDs during partitioning earlier.

--- /etc/mkinitcpio.conf	2021-08-12 14:54:44.835669088 +0200
+++ /etc/mkinitcpio.conf	2021-07-22 20:30:18.593193125 +0200
@@ -49,7 +49,7 @@
 ##   NOTE: If you have /usr on a separate partition, you MUST include the
 #    usr, fsck and shutdown hooks.
-HOOKS=(base udev autodetect modconf block filesystems keyboard fsck)
+HOOKS=(base systemd autodetect modconf block keyboard sd-encrypt filesystems)

 # Use this to compress the initramfs image. By default, zstd compression

Changes to /etc/mkinitcpio.d/linux.preset. Note this requires the new mkinitcpio with UEFI stub generation! The package can be fetched from my local repo.

Note: This is all part of the mkinitcpio 31 release.

--- /etc/mkinitcpio.d/linux.preset	2021-08-13 18:54:44.835669088 +0200
+++ /etc/mkinitcpio.d/linux.preset	2021-07-22 20:30:18.593193125 +0200
@@ -2,13 +2,10 @@


- PRESETS=('default' 'fallback')
+ PRESETS=('default')

+default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

For the kernel cmdline options we are using /etc/kernel/cmdline as that is what mkinitcpio will be using to read from to create our boot entry.

$ cat /etc/kernel/cmdline
rw quiet acpi_osi= acpi_backlight=thinkpad_screen acpi.ec_no_wakeup=1 nowatchdog

Those options are for my thinkpad. Your mileage might differ. Note that we do not specify disk UUIDs because systemd is going to figure out that for us automagically.

Regenerate the linux iniramfs with mkinitcpio so we get our options mkinitcpio -P. The important part is to have the UEFI stub generation.

==> Starting build: 5.13.10-arch1-1
  -> Running build hook: [base]
  -> Running build hook: [systemd]
  -> Running build hook: [autodetect]
  -> Running build hook: [modconf]
  -> Running build hook: [block]
  -> Running build hook: [keyboard]
  -> Running build hook: [sd-encrypt]
  -> Running build hook: [filesystems]
==> Generating module dependencies
==> Creating zstd-compressed initcpio image: /boot/initramfs-linux.img
==> Image generation successful
==> Creating UEFI executable: /efi/EFI/Linux/arch-linux.efi
  -> Using UEFI stub: /usr/lib/systemd/boot/efi/linuxx64.efi.stub
  -> Using kernel image: /lib/modules/5.13.10-arch1-1/vmlinuz
  -> Using os-release file /etc/os-release
==> UEFI executable generation successful


# bootctl install
Created "/efi/loader/entries".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/efi/EFI/systemd/systemd-bootx64.efi".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/efi/EFI/BOOT/BOOTX64.EFI".
Created "/efi/60a1f123aa5f451f8af104e458838efb".
Random seed file /efi/loader/random-seed successfully written (512 bytes).
Created EFI boot entry "Linux Boot Manager".
# efibootmgr -v // verify it works
BootCurrent: 0000
Timeout: 0 seconds
BootOrder: 0000
Boot0000* Linux Boot Manager	HD(1,GPT,d78d8c94-d277-4635-a73c-a68cd6ddb6ab,0x800,0xff801)/File(\EFI\systemd\systemd-bootx64.efi)


Tips and Tricks

Run makepkg as sudo

Never actually use this: env EUID=1000 makepkg -srcf

Disable work queues for cryptsetup

cryptsetup sector size

λ ~ » sudo blockdev --getpbsz /dev/nvme0n1
λ ~ » sudo nvme id-ns -H /dev/nvme0n1
LBA Format  0 : Metadata Size: 0   bytes - Data Size: 512 bytes - Relative Performance: 0 Best (in use)
                                                      ^^^^^^^^^ sector size
λ ~ » sudo cryptsetup luksDump /dev/nvme0n1p2 | grep sector
	sector: 512 [bytes]

This should be autoselected with new cryptsetup. But not sure if this applies to NVME? Note for the future: Get a NVME which supports sector size 4096?


Test package for /etc/kernel/cmdline.d for laptop specific settings

misc stuff

xdg-mime default org.pwmt.zathura.desktop application/pdf
xdg-settings set default-web-browser org.qutebrowser.qutebrowser.desktop

Benchmarking BTRFS

This is some sporadic notes about looking at read/write speeds on btrfs with encryption and some recent features.

fio --rw={read,write} --ioengine=io_uring --bs=512k --size=100g --numjobs=1 --direct=1 --runtime=60 --name -test-btrfs

NB: Tests where just ran once or twice. Hardly science.

TL;DR: Compression doesn't matter. Any improvements in the encryption space is the important part.

No encryption

Baseline (btrfs, no compression)

Seqread: 1417 MiB/s Seqwrite: 2116 MiB/s

Btrfs + zstd:3

Seqread: 1340 MiB/s Seqwrite: 2025 MiB/s

Btrfs + zstd:1

Seqread: 1388 MiB/s Seqwrite: 2168 MiB/s



Baseline (btrfs, no compression)

Seqread: 605 MiB/s Seqwrite: 777 MiB/s

Btrfs + zstd:3

Seqread: 642 MiB/s Seqwrite: 736 MiB/s

Btrfs + zstd:1

Seqread: 605 MiB/s Seqwrite: 780 MiB/s

Encryption - --perf-no_{write,read}_workqeue

Defaults + --perf. Note: I skipped compression after this point. It doesn't matter.

Baseline (btrfs, no compression)

Seqread: 561 MiB/s Seqwrite: 808 MiB/s

Btrfs + zstd:3

Seqread: 607 MiB/s Seqwrite: 802 MiB/s

Encryption - --perf-no_{write,read}_workqeue + 4k sector size

Btrfs + zstd:3

Seqread: 746 MiB/s Seqwrite: 1500 MiB/s



Manages packages


Manages repositories


Manages builds


  • --repository

  • --commit

  • --nobump

  • --nocheck

  • buildctl rebuild [DEPENDENCY]|[SO-NAME] Flags --order

  • buildctl todo [URL]


Reduce package size

Remove test files.

Split race and dynlibs into seperate packages? This would reduce the overall size to around 200 MB.


Depends on Include = /etc/repositories.d/*.conf is appended to pacman.conf

$ prm list
Available repositories:

    Maintainer: George Rawlinson
    Description: AUR packages maintained by the user as well as some experimental packages.
    Key-ID: 9D120F4AAF400B8313A87EF2369552B2069123EE

    Maintainer: Orhun Parmaksiz
    Description: Personal repository with AUR and custom packages.
    Key-ID: N/A

$ prm select grawlinson
Writing to /etc/repositories.d/grawlinson.conf

$ prm show
Selected repositories:

* [grawlinson]


This is me learning about firewalld and networkmanager

Supply Chain Security

Research and projects around Transparency Logs


This is just some notes about my gnupg keys.

Key Setup

  • rsa4096/9C02FF419FECBE16
    • card-no: 0006 07800345
    • Certificate / Signing
  • rsa4096/DF2502D0C726D1C0
    • card-no: 0006 07800345
    • Encryption
  • rsa4096/06F6BDC766FCDC53
    • card-no: 0006 07800345
    • Auth
  • rsa4096/E742683BA08CB2FF
    • Signing

Revoked Keys

  • rsa4096/41A82494FF2B717B
    • this key was a mistake

openssl rand -hex 32 > token

ssh-keygen -Y sign -n ownership-proof -f ~/.ssh/id_ed25519 token

ssh-keygen -Y verify -n ownership-proof -f <(echo 'kyrias ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFIHU6QpZkcnicveoF7UjfhaEH93YmgrVLV6v7mXbjkJ') -I kyrias -s token.sig < token

Secure Boot

This is some notes regarding secure boot quirks and misc issues I encounter.


Microsoft Authenticode apparently relied on crc in ancient iterations. This is important because this implies padding has no effect on checksums, thus the resulting X509 certificate we append to the binaries.

However with cryptographic checksums these do affect the resulting checksum.

This is with Trammells checksum patch:

λ signtest » sbsign --hash-only ./fwupdx64.efi # No certificates
λ signtest » sbsign --hash-only ./fwupdx64.efi.signed.gosign # Has certificates

This is made more explicit with pesign:

λ signtest » pesign --hash --nopadding --in ./fwupdx64.efi
./fwupdx64.efi 788408ea495d2cd55f6d2d3b5e5d56e130c738917068f9e40b07d69ae79dfd51
λ signtest » pesign --hash --padding --in ./fwupdx64.efi
./fwupdx64.efi 33c1bfe9f9d60822df8c099f88ee841ded43f80471b71a9c2ec65a9a4a2ec132

This implies that if you where to enroll a SHA256 sum into the db security database, the checksum would be different depending if the binary has an certificate or not. "Yay".

sbverify doesn't need to care about this distinction since it will never actually have to deal with unsigned executables. Thus it can only care about the padded binaries.

Eventlogs and OpROM


Secure Boot uses two types of signatures. PKCS7 and CMS.

CMS is mandated by Microsoft Authenticode


  • Rename hook form ZZ to zz

Figure out UEFI Class 3+

We need a reliable way to tell if the CPU is post 2020'ish and carries oprom.

  • Parse TPM Eventlog
  • Scan for known issues?
  • Laptop models

Subcommand: expert

Debug information. Read out variables WIP/POC functionality

Should be hidden by default?

sbctl expert enroll
    --pk, --kek, --db, --dbx

sbctl expert print
sbctl enroll-keys --vendor-keys="vendor microsoft"
sbctl enroll-keys --enroll-oprom

Subcommand: setup

Subcommand: rotate-key

resolved and dns-sd

Some quick notes about how to resolve dns-sd services with resolved. This is mostly handy for scripting things like chromecast lookups without having to have avahi and such installed.

λ bin » resolvectl --type=PTR query _googlecast._tcp.local
_googlecast._tcp.local IN PTR Chromecast-Ultra-e6437103e5d642323014c80ddffc76dc._googlecast._tcp.local -- link: enp0s31f6


Talks from me

This is a list of all the live records of talks I have held. Apparently there are more then one :o

Slides for my presentations can be found in my talks repository.


Open Source Firmware Conference

BSides Oslo




Bergen Linux User Group




# sudo modprobe v4l2loopback video_nr=4,5 max_buffers=2 exclusive_caps=1,1
# gphoto2 --set-config /main/actions/autofocus=1
# gphoto2 --stdout --capture-movie | gst-launch-1.0 fdsrc ! decodebin3 name=dec ! queue !  videoconvert ! v4l2sink device=/dev/video4

gstreamer notes

Split one v4l2 device into two other video devices:

λ ~ » gst-launch-1.0 v4l2src device=/dev/video0 ! tee name=t \
t. ! queue ! videoconvert ! v4l2sink device=/dev/video4 \
t. ! queue ! videoconvert ! v4l2sink device=/dev/video5

Usecase: Record webcam/camera in OBS while also having it in video conferencing

Using v4l2loopback to make new devices.

sudo modprobe v4l2loopback video_nr=4,5 max_buffers=2 exclusive_caps=1,1

Capture video from gphoto2

$ gphoto2 --stdout --capture-movie | gst-launch-1.0 fdsrc ! decodebin3 ! queue !  videoconvert ! v4l2sink device=/dev/video4