[
  {
    "path": "README.md",
    "content": "# Raspberry Pi Encrypted Boot with SSH\n\n> ⚠️ This guide is only tested on the [Raspberry Pi 5](https://www.raspberrypi.com/products/raspberry-pi-5/) with [Raspberry Pi OS Lite 64-bit 2023-12-11](https://www.raspberrypi.com/software/operating-systems/). \\\n> Other platforms and distributions may work, but there may be unexpected issues or side effects.\n\n## Introduction\n\nThis guide will show you how to encrypt your Raspberry Pi's root partition and set up an [initramfs](https://en.wikipedia.org/wiki/Initial_ramdisk) that will prompt for the password, decrypt the partition and gracefully resume boot. You will also learn how to enable SSH during this pre-boot stage, allowing you to unlock the partition remotely. There are also optional steps for WiFi setup.\n\nThis guide operates directly on an image file and therefore does not require an SD card for the setup. The resulting image can be flashed to an SD card as usual.\n\n## Table of Content\n\n- [Raspberry Pi Encrypted Boot with SSH](#raspberry-pi-encrypted-boot-with-ssh)\n  - [Introduction](#introduction)\n  - [Table of Content](#table-of-content)\n  - [Requirements](#requirements)\n  - [On the host](#on-the-host)\n  - [In the chroot](#in-the-chroot)\n    - [Prepare](#prepare)\n    - [Device configuration](#device-configuration)\n    - [Cryptsetup](#cryptsetup)\n    - [SSH](#ssh)\n    - [WiFi support](#wifi-support)\n      - [Raspberry Pi OS](#raspberry-pi-os)\n      - [Ubuntu (obsolete)](#ubuntu-obsolete)\n    - [Build initramfs](#build-initramfs)\n    - [Finish](#finish)\n  - [On the host](#on-the-host-1)\n  - [On the Raspberry Pi](#on-the-raspberry-pi)\n  - [Avoiding SSH key collisions](#avoiding-ssh-key-collisions)\n  - [Resources](#resources)\n\n## Requirements\n\n- A Raspberry Pi Linux image (e.g. [Raspberry Pi OS Lite 64-bit 2023-12-11](https://www.raspberrypi.com/software/operating-systems/))\n- A computer (host) running Linux (e.g. [Kali Linux 2023.2](https://www.kali.org/get-kali/#kali-platforms))\n\n  > :warning: **NOTE:** Your host's Linux should be as similar as possible to the Raspberry Pi's Linux. If you are preparing Debian 12/kernel 6.1 for the Raspberry Pi, use similar versions on the host, otherwise you may encounter issues inside the chroot.\n\n## On the host\n\nInstall dependencies:\n\n- You can skip `binfmt-support` and `qemu-user-static` if your host Linux's architecture matches that of the Raspberry Pi's Linux image.\n- If your host Linux doesn't use systemd, such as WSL on Windows, you need to manually run `update-binfmts --enable` after installing `binfmt-support`.\n\n```sh\napt update\napt install -y parted kpartx cryptsetup-bin rsync binfmt-support qemu-user-static\n```\n\nCreate two copies of the Raspberry Pi's Linux image — one to read from (base), and one to write to (target):\n\n- pi-base.img\n- pi-target.img\n\nIncrease the size of the target image or you may run into issues:\n\n```bash\ndd if=/dev/zero bs=1G count=1 >> pi-target.img\nparted pi-target.img resizepart 2 100%\n```\n\nMap both images as devices, ensuring the base is readonly:\n\n```sh\nkpartx -ar \"$PWD/pi-base.img\"\nkpartx -a \"$PWD/pi-target.img\"\n```\n\nIf your system automatically mounted any partitions, unmount them:\n\n```sh\numount /media/**/*\n```\n\nRun [lsblk](https://linux.die.net/man/8/lsblk) and verify the process was successful — you should see two loopback devices, each with two partitions:\n\n```sh\nNAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT # COMMENT\nloop0       7:0    0  3.3G  0 loop            # pi-base.img\n├─loop0p1 253:0    0  256M  0 part            # ├─ boot\n└─loop0p2 253:1    0    3G  0 part            # └─ root\nloop1       7:1    0  3.3G  1 loop            # pi-target.img\n├─loop1p1 253:2    0  256M  1 part            # ├─ boot\n└─loop1p2 253:3    0    3G  1 part            # └─ root\n```\n\nMount the base image's root partition:\n\n```sh\nmkdir -p /mnt/original/\nmount /dev/mapper/loop0p2 /mnt/original/\n```\n\nReplace the target image's root partition with a new, encrypted partition:\n\n> :warning: **NOTE:**\n>\n> The default encryption algorithm is `aes-xts-plain64`, which is fast only on the Raspberry Pi 5 due to its hardware AES acceleration. If you have an older generation, then use [aes-adiantum](https://github.com/google/adiantum) instead via `-c xchacha20,aes-adiantum-plain64`. It is much faster than AES in software.\n>\n> By default cryptsetup will [benchmark](https://man7.org/linux/man-pages/man8/cryptsetup-luksformat.8.html) your host and use a memory-hard PBKDF algorithm that can require up to 4GB of RAM. If these settings exceed your Raspberry Pi's available RAM, it will make it impossible to unlock the partition. To work around this, set the [--pbkdf-memory](https://man7.org/linux/man-pages/man8/cryptsetup-luksformat.8.html) and [--pbkdf-parallel](https://man7.org/linux/man-pages/man8/cryptsetup-luksformat.8.html) arguments so when you multiply them, the result is less than your Pi's total RAM. For example: `--pbkdf-memory 512000 --pbkdf-parallel=1`\n\n```sh\ncryptsetup luksFormat /dev/mapper/loop1p2\n```\n\nOpen (decrypt) the new partition:\n\n```\ncryptsetup open /dev/mapper/loop1p2 crypted\n```\n\nThen format and mount it:\n\n```\nmkfs.ext4 /dev/mapper/crypted\nmkdir -p /mnt/chroot/\nmount /dev/mapper/crypted /mnt/chroot/\n```\n\nCopy the base image's root partition files to the target image's new, encrypted root partition. You can use [dd](https://linux.die.net/man/1/dd), but [rsync](https://linux.die.net/man/1/rsync) is faster:\n\n```sh\nrsync --archive --hard-links --acls --xattrs --one-file-system --numeric-ids --info=\"progress2\" /mnt/original/* /mnt/chroot/\n```\n\nSet up a [chroot](https://linux.die.net/man/1/chroot) by mounting the target image's boot partition and required virtual filesystems from the host:\n\n```sh\nmkdir -p /mnt/chroot/boot/\nmount /dev/mapper/loop1p1 /mnt/chroot/boot/\nmount -t proc none /mnt/chroot/proc/\nmount -t sysfs none /mnt/chroot/sys/\nmount -o bind /dev /mnt/chroot/dev/\nmount -o bind /dev/pts /mnt/chroot/dev/pts/\n```\n\nEnter the chroot:\n\n```sh\nLANG=C chroot /mnt/chroot/ /bin/bash\n```\n\n## In the chroot\n\n### Prepare\n\nInstall the dependencies:\n\n```sh\napt update\napt install -y busybox cryptsetup dropbear-initramfs\n```\n\n### Device configuration\n\nEdit [/etc/fstab](https://linux.die.net/man/5/fstab) and replace the root entry with your decrypted (virtual) partition's device name:\n\n```sh\n# Original:\nPARTUUID=e8af6eb2-02 / ext4 defaults,noatime          0 1\n# Replace with:\n/dev/mapper/crypted  / ext4 defaults,noatime          0 1\n```\n\nRun [blkid](https://linux.die.net/man/8/blkid) and note the details of your encrypted partition:\n\n```sh\nblkid | grep crypto_LUKS\n\n/dev/mapper/loop1p2: UUID=\"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa\" TYPE=\"crypto_LUKS\" PARTUUID=\"cccccccc-cc\"\n```\n\nEdit [/etc/crypttab](https://linux.die.net/man/5/crypttab) and add an entry with your encrypted (raw) partition's UUID:\n\n```sh\ncrypted UUID=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa none luks,initramfs\n```\n\nEdit `/boot/cmdline.txt` and update the root entry:\n\n```sh\n# Original:\nroot=PARTUUID=21e60f8c-02\n# Replace with:\nroot=/dev/mapper/crypted cryptdevice=UUID=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:crypted\n```\n\n### Cryptsetup\n\nEdit the cryptsetup initramfs hook to ensure cryptsetup ends up in the initramfs:\n\n```sh\necho \"CRYPTSETUP=y\" >> /etc/cryptsetup-initramfs/conf-hook\n```\n\nThe [initramfs-tools](https://manpages.ubuntu.com/manpages/xenial/man8/initramfs-tools.8.html) `cryptroot` hook will resolve any UUIDs to device names during initramfs generation. This is a problem because the device names will likely differ between the host and the Raspberry Pi, resulting in failure to boot. To work around this, apply the following patch:\n\n```patch\npatch --no-backup-if-mismatch /usr/share/initramfs-tools/hooks/cryptroot << 'EOF'\n--- cryptroot\n+++ cryptroot\n@@ -33,7 +33,7 @@\n         printf '%s\\0' \"$target\" >>\"$DESTDIR/cryptroot/targets\"\n         crypttab_find_entry \"$target\" || return 1\n         crypttab_parse_options --missing-path=warn || return 1\n-        crypttab_print_entry\n+        printf '%s %s %s %s\\n' \"$_CRYPTTAB_NAME\" \"$_CRYPTTAB_SOURCE\" \"$_CRYPTTAB_KEY\" \"$_CRYPTTAB_OPTIONS\" >&3\n     fi\n }\nEOF\n```\n\nThe default timeout when waiting for decryption (10 seconds) may be too short and result in a timeout error. To work around this, bump the value:\n\n```sh\nsed -i 's/^TIMEOUT=.*/TIMEOUT=100/g' /usr/share/cryptsetup/initramfs/bin/cryptroot-unlock\n```\n\n### SSH\n\nWrite your SSH public key inside dropbear's and your decrypted OS's `authorized_keys` and fix permissions:\n\n```sh\nmkdir -p /root/.ssh && chmod 0700 /root/.ssh\necho \"/REDACTED/\" | tee /etc/dropbear/initramfs/authorized_keys /root/.ssh/authorized_keys\nchmod 0600 /etc/dropbear/initramfs/authorized_keys /root/.ssh/authorized_keys\n```\n\n### WiFi support\n\nThis step is optional. If you want the Raspberry Pi to be decryptable over WiFi, check out the guides below. Note that the differences between distros is very small, so you can easily adapt any particular guide.\n\n#### Raspberry Pi OS\n\n- [Wireless-USB2.md](Wireless-USB2.md)\n\n#### Ubuntu (obsolete)\n\n- [Wireless-Builtin.md](Wireless-Builtin.md)\n- [Wireless-USB.md](Wireless-USB.md)\n\n### Build initramfs\n\n\nNote your kernel version. If there are multiple, choose the one you want to run. The `2712` suffix is for Raspberry Pi 5, while `v8` is for all previous generations:\n\n```sh\nls /lib/modules/\n```\n\n> :warning: **NOTE:**\n>\n> Starting with the Raspberry Pi 5, the default kernel page size is 16K instead of 4K. This breaks some software, but more importantly, is experimental in btrfs with 4K sector size disks:\n>\n> > BTRFS warning (device dm-1): read-write for sector size 4096 with page size 16384 is experimental\n>\n> For this reason, you may want to switch back to the old kernel by adding the following to your `/boot/config.txt`:\n>\n> ```sh\n> echo \"kernel=kernel8.img\" >> /boot/config.txt\n> echo \"initramfs initramfs8 followkernel\" >> /boot/config.txt\n> ```\n\nBuild the new initramdisk using the kernel version from above. The `initramfs-tools` package parses the compression method from a file that doesn't exist, so we need to create it:\n\n```sh\nkversion=\"6.1.0-rpi7-rpi-v8\" # \"6.1.0-rpi7-rpi-2712\" for 16k pages\necho \"CONFIG_RD_ZSTD=y\" > /boot/config-$kversion\nmkinitramfs -o /boot/initramfs8 $kversion # \"initramfs_2712\" for 16K pages\nrm /boot/config-$kversion\n```\n\nCustomize first run/init in `/boot/cmdline.txt` as it will break the encrypted setup and prevent booting:\n\n```sh\n# Original:\n[...] quiet init=/usr/lib/raspberrypi-sys-mods/firstboot\n# Replace with:\n[...] systemd.run=/boot/firstrun.sh systemd.run_success_action=reboot systemd.unit=kernel-command-line.target\n```\n\nCreate `/boot/firstrun.sh` and customize it for your needs. Most of these scripts allow additional configuration, so feel free to check their source:\n\n```sh\n#!/bin/bash\nset +e\n\n/usr/lib/raspberrypi-sys-mods/imager_custom enable_ssh\n/usr/lib/raspberrypi-sys-mods/regenerate_ssh_host_keys\n/usr/lib/userconf-pi/userconf 'pi'\n/usr/lib/raspberrypi-sys-mods/imager_custom set_wlan 'MyWiFi' 'pass1234' 'GB'\n\nrm -f /boot/firstrun.sh\nsed -i 's| systemd.run.*||g' /boot/cmdline.txt\nexit 0\n```\n\nMake sure the newly created file is executable:\n\n```sh\nchmod +x /boot/firstrun.sh\n```\n\n### Finish\n\n\nSync and exit the chroot:\n\n```sh\nsync\nhistory -c && exit\n```\n\n## On the host\n\nUnmount everything and clean up any remaining artifacts:\n\n```sh\numount /mnt/chroot/boot\numount /mnt/chroot/sys\numount /mnt/chroot/proc\numount /mnt/chroot/dev/pts\numount /mnt/chroot/dev\numount /mnt/chroot\ncryptsetup close crypted\numount /mnt/original\nrm -d /mnt/chroot\nrm -d /mnt/original\nkpartx -d \"$PWD/pi-base.img\"\nkpartx -d \"$PWD/pi-target.img\"\n```\n\nYou are now ready to flash `pi-target.img` to an SD card.\n\n## On the Raspberry Pi\n\nBoot the Raspberry Pi with the new SD card. It will obtain an IP address from the DHCP server and start listening for SSH connections. To decrypt the root partition and continue boot, from any shell, simply run `cryptroot-unlock`.\n\nThe first time only:\n\n1. Once decrypted, the system will power off. The reason for this is currently unknown. Restart the device and decrypt again.\n2. The decrypted system will run the init script from before and reboot back into the initramfs. Proceed to decrypt one last time.\n\nOnce booted into the decrypted system, you will notice that the root partition is still sized at ~3GB, no matter how much space you have on the SD card. To fix this, resize the partition:\n\n```sh\nparted /dev/mmcblk0 resizepart 2 100%\ncryptsetup resize crypted\nresize2fs /dev/mapper/crypted\n```\n\nFinally, reboot the system one last time for good measure:\n\n```sh\nreboot\n```\n\n## Avoiding SSH key collisions\n\nTo avoid host key collisions you can configure a separate trusted hosts store in the `~/.ssh/config` of your client:\n\n```ssh\nHost box\n\tHostname 192.168.0.30\n\tUser root\n\nHost box-initramfs\n\tHostname 192.168.0.30\n\tUser root\n\tUserKnownHostsFile ~/.ssh/known_hosts.initramfs\n```\n\n## Resources\n\n- https://www.kali.org/docs/arm/raspberry-pi-with-luks-disk-encryption/\n- https://wiki.archlinux.org/index.php/Dm-crypt/Specialties\n- https://wiki.gentoo.org/wiki/Custom_Initramfs\n- https://www.raspberrypi.org/forums/viewtopic.php?t=252980\n- https://thej6s.com/articles/2019-03-05__decrypting-boot-drives-remotely/\n- https://www.pbworks.net/ubuntu-guide-dropbear-ssh-server-to-unlock-luks-encrypted-pc/\n- https://raspberrypi.stackexchange.com/questions/92557/how-can-i-use-an-init-ramdisk-initramfs-on-boot-up-raspberry-pi/\n- https://www.raspberrypi.com/documentation/computers/configuration.html#setting-up-a-headless-raspberry-pi\n"
  },
  {
    "path": "Wireless-Builtin.md",
    "content": "# WiFi Support\n\nThis guide will show you how to set up the Raspberry Pi's built-in WiFi module for use during initramfs. The steps here are intended for Ubuntu, slight changes will be necessary for Raspberry Pi OS.\n\n## Set up initramfs\n\nCreate the following files and customize them if necessary:\n\n- `/etc/initramfs-tools/scripts/init-premount/a_enable_wireless`\n\n  ```bash\n  #!/bin/sh\n  PREREQ=\"\"\n  prereqs()\n  {\n      echo \"$PREREQ\"\n  }\n\n  case $1 in\n  prereqs)\n      prereqs\n      exit 0\n      ;;\n  esac\n  \n  echo \"Waiting for wlan device to come up...\"\n  while [ ! -d \"/sys/class/net/wlan0\" ]; do\n      sleep 1\n  done\n  \n  echo \"Initializing wpa-supplicant...\"\n  /sbin/wpa_supplicant -i wlan0 -c /etc/wpa_supplicant.conf -P /run/initram-wpa_supplicant.pid -B\n  ```\n\n- `/etc/initramfs-tools/hooks/enable-wireless`\n\n  ```bash\n  #!/bin/sh\n  set -e\n  PREREQ=\"\"\n  prereqs()\n  {\n      echo \"${PREREQ}\"\n  }\n  case \"${1}\" in\n      prereqs)\n          prereqs\n          exit 0\n          ;;\n  esac\n\n  . /usr/share/initramfs-tools/hook-functions\n\n  copy_exec /sbin/wpa_supplicant\n\n  # copy WiFi driver\n  copy_modules_dir kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac\n  # copy additional firmware files, ignoring error if they are already copied\n  for f in /lib/firmware/brcm/brcmfmac*; do\n  \tcopy_file firmware \"$f\" || true\n  done\n\n  copy_file config /etc/initramfs-tools/wpa_supplicant.conf /etc/wpa_supplicant.conf\n  ```\n\n- `/etc/initramfs-tools/scripts/init-bottom/kill_wireless`\n\n  ```bash\n  #!/bin/sh\n  PREREQ=\"\"\n  prereqs()\n  {\n      echo \"$PREREQ\"\n  }\n\n  case $1 in\n  prereqs)\n      prereqs\n      exit 0\n      ;;\n  esac\n\n  # allow the decrypted OS to handle WiFi on its own\n  echo \"Stopping wlan device...\"\n  kill $(cat /run/initram-wpa_supplicant.pid)\n  ip link set wlan0 down\n  # created by initramfs\n  # for some reason it lists wlan0 as ethernet, which breaks netplan - remove it\n  rm -f /run/netplan/wlan0.yaml\n  ```\n\n- `/etc/initramfs-tools/wpa_supplicant.conf`\n\n  ```bash\n  ctrl_interface=/tmp/wpa_supplicant\n  country=GB\n  \n  network={\n      ssid=\"Foo\"\n      scan_ssid=1\n      psk=\"Bar\"\n      key_mgmt=WPA-PSK\n  }\n  ```\n\nChmod all scripts you just created:\n\n```bash\nchmod +x /etc/initramfs-tools/scripts/init-premount/a_enable_wireless\nchmod +x /etc/initramfs-tools/hooks/enable-wireless\nchmod +x /etc/initramfs-tools/scripts/init-bottom/kill_wireless\n```\n\nSet up WiFi for the decrypted OS. On Ubuntu, you do this by creating e.g. `/etc/netplan/10-user.yaml`:\n\n```yaml\nnetwork:\n  version: 2\n  ethernets:\n    eth0:\n      dhcp4: true\n      optional: true\n  wifis:\n    wlan0:\n      optional: true\n      access-points:\n        \"Foo\":\n          password: \"Bar\"\n      dhcp4: true\n```\n\nYou're done! Follow the rest of the guide to finish building your initramfs.\n\n## Resources\n\n- https://gist.github.com/telenieko/d17544fc7e4b347beffa87252393384c\n- https://morfikov.github.io/post/wsparcie-dla-wifi-w-initramfs-initrd-by-odszyfrowac-luks-przez-ssh-bezprzewodowo/\n- https://morfikov.github.io/post/odszyfrowanie-luks-przez-ssh-z-poziomu-initramfs-initrd-na-raspberry-pi/\n- https://github.com/endlessm/linux-firmware/tree/master/brcm\n- https://forums.gentoo.org/viewtopic-t-1040452-start-0.html\n- https://github.com/lamby/initramfs-tools/blob/pass-reproducible-option/hook-functions\n- https://github.com/unixabg/cryptmypi/blob/master/hooks/0000-experimental-initramfs-wifi.hook\n- https://askubuntu.com/questions/1250133/interface-ip-conflict-after-dropbear-initramfs-boot\n"
  },
  {
    "path": "Wireless-USB.md",
    "content": "# WiFi USB Support\n\nThis guide will show you how to set up a WiFi USB dongle for use during initramfs. The steps here are intended for Ubuntu, slight changes will be necessary for Raspberry Pi OS.\n\n## Installing driver\n\nThe steps below are written for the [TP-LINK T4U](https://www.tp-link.com/uk/home-networking/adapter/archer-t4u/) USB dongle, which uses the Realtek RTL88x2B driver. As of Linux 5.15, this driver is not included in the kernel, so it needs to be built and installed manually. If your driver comes with your kernel, you can skip this section.\n\nFirst, install [dkms](https://help.ubuntu.com/community/DKMS):\n\n```bash\napt install dkms\n```\n\nBuild your initramfs once to generate dependencies needed by dkms. Replace the kernel version if necessary (check `/usr/lib/modules/`):\n\n```bash\nmkinitramfs -o /boot/initrd.img \"5.15.0-1005-raspi\"\n```\n\nPrepare the driver:\n\n```bash\ngit clone https://github.com/ViRb3/88x2bu-20210702.git\ncd 88x2bu-20210702\n```\n\nBy default, this driver's Makefile will use all of your CPU cores. This has the side effect of also using additional RAM, and if you're on a 1GB RAM device, it may run out of memory. To work around, disable the parallel build:\n\n```bash\nsed -i 's/-j$sproc/-j1/g' dkms-make.sh\n```\n\nBuild and install the driver:\n\n```bash\nKVER=\"5.15.0-1005-raspi\" ./install-driver.sh\n```\n\nTo prevent issues, disable all power-saving features:\n\n```bash\n./edit-options.sh\noptions 88x2bu rtw_power_mgnt=0 rtw_ips_mode=0 rtw_enusbss=0\n```\n\nIf you are connecting the card to a USB3 port, also add `rtw_switch_usb_mode=1` to force it into USB3 mode. Note that the Raspberry Pi 4B specifically has an issue where the driver silently stops working in USB3 mode when acting as AP or when downloading large volumes of data (~120GB). To work around, leave as default or add `rtw_switch_usb_mode=2` to force USB2 mode.\n\n## Set up initramfs\n\nOn Ubuntu 22.04, external (USB) WiFi dongles have a deterministic interface naming scheme that uses the device's MAC address, like: `wlx112233445566`. Replace the interface name with yours in the examples below.\n\nCreate the following files and customize them if necessary:\n\n- `/etc/initramfs-tools/scripts/init-premount/a_enable_wireless`\n\n  ```bash\n  #!/bin/sh\n  PREREQ=\"\"\n  prereqs()\n  {\n      echo \"$PREREQ\"\n  }\n\n  case $1 in\n  prereqs)\n      prereqs\n      exit 0\n      ;;\n  esac\n  \n  echo \"Waiting for wlan device to come up...\"\n  while [ ! -d \"/sys/class/net/wlx112233445566\" ]; do\n      sleep 1\n  done\n  \n  echo \"Initializing wpa-supplicant...\"\n  /sbin/wpa_supplicant -i wlx112233445566 -c /etc/wpa_supplicant.conf -P /run/initram-wpa_supplicant.pid -B\n  ```\n\n- `/etc/initramfs-tools/hooks/enable-wireless`\n\n  ```bash\n  #!/bin/sh\n  set -e\n  PREREQ=\"\"\n  prereqs()\n  {\n      echo \"${PREREQ}\"\n  }\n  case \"${1}\" in\n      prereqs)\n          prereqs\n          exit 0\n          ;;\n  esac\n  \n  . /usr/share/initramfs-tools/hook-functions\n  \n  copy_exec /sbin/wpa_supplicant\n  \n  # copy WiFi driver\n  manual_add_modules 88x2bu\n  \n  copy_file config /etc/initramfs-tools/wpa_supplicant.conf /etc/wpa_supplicant.conf\n  ```\n  \n- `/etc/initramfs-tools/scripts/init-bottom/kill_wireless`\n\n  ```bash\n  #!/bin/sh\n  PREREQ=\"\"\n  prereqs()\n  {\n      echo \"$PREREQ\"\n  }\n\n  case $1 in\n  prereqs)\n      prereqs\n      exit 0\n      ;;\n  esac\n\n  # allow the decrypted OS to handle WiFi on its own\n  echo \"Stopping wlan device...\"\n  kill $(cat /run/initram-wpa_supplicant.pid)\n  ip link set wlx112233445566 down\n  # created by initramfs\n  # for some reason it lists wlx112233445566 as ethernet, which breaks netplan - remove it\n  rm -f /run/netplan/wlx112233445566.yaml\n  ```\n\n- `/etc/initramfs-tools/wpa_supplicant.conf`\n\n  ```bash\n  ctrl_interface=/tmp/wpa_supplicant\n  country=GB\n  \n  network={\n      ssid=\"Foo\"\n      scan_ssid=1\n      psk=\"Bar\"\n      key_mgmt=WPA-PSK\n  }\n  ```\n\nChmod all scripts you just created:\n\n```bash\nchmod +x /etc/initramfs-tools/scripts/init-premount/a_enable_wireless\nchmod +x /etc/initramfs-tools/hooks/enable-wireless\nchmod +x /etc/initramfs-tools/scripts/init-bottom/kill_wireless\n```\n\nSet up WiFi for the decrypted OS. On Ubuntu, you do this by creating e.g. `/etc/netplan/10-user.yaml`:\n\n```yaml\nnetwork:\n  version: 2\n  ethernets:\n    eth0:\n      dhcp4: true\n      optional: true\n  wifis:\n    wlx112233445566:\n      optional: true\n      access-points:\n        \"Foo\":\n          password: \"Bar\"\n      dhcp4: true\n```\n\nYou may want to disable onboard WiFi from the decrypted OS so it doesn't conflict with your external USB card:\n\n```sh\necho \"dtoverlay=disable-wifi\" >> /boot/config.txt\n```\n\nYou're done! Follow the rest of the guide to finish building your initramfs.\n\n## Resources\n\n- [Wireless-Builtin.md](Wireless-Builtin.md)\n- https://github.com/morrownr/88x2bu-20210702\n"
  },
  {
    "path": "Wireless-USB2.md",
    "content": "# WiFi USB Support\n\nThis guide will show you how to set up a WiFi USB dongle for use during initramfs. The steps here are intended for Raspberry Pi OS, slight changes will be necessary for Ubuntu.\n\n## Installing driver\n\nThe steps below are written for the [Alfa AWUS036AXML](https://alfa-network.eu/alfa-usb-adapter-awus036axml) USB dongle, which uses the Mediatek MT7921AU driver. The driver is part of the Linux kernel starting from 6.1.\n\n## Set up initramfs\n\nCreate the following files and customize them if necessary:\n\n- `/etc/initramfs-tools/scripts/init-premount/a_enable_wireless`\n\n  ```bash\n  #!/bin/sh\n  PREREQ=\"\"\n  prereqs()\n  {\n      echo \"$PREREQ\"\n  }\n  \n  case $1 in\n  prereqs)\n      prereqs\n      exit 0\n      ;;\n  esac\n  \n  echo \"Waiting for wlan device to come up...\"\n  while [ ! -d \"/sys/class/net/wlan0\" ]; do\n      sleep 1\n  done\n  \n  echo \"Initializing wpa-supplicant...\"\n  /sbin/wpa_supplicant -i wlan0 -c /etc/wpa_supplicant.conf -P /run/initram-wpa_supplicant.pid -B\n  ```\n\n- `/etc/initramfs-tools/hooks/enable-wireless`\n\n  ```bash\n  #!/bin/sh\n  set -e\n  PREREQ=\"\"\n  prereqs()\n  {\n      echo \"${PREREQ}\"\n  }\n  case \"${1}\" in\n      prereqs)\n          prereqs\n          exit 0\n          ;;\n  esac\n  \n  . /usr/share/initramfs-tools/hook-functions\n  \n  copy_exec /sbin/wpa_supplicant\n  \n  # copy WiFi driver\n  manual_add_modules mt7921u\n  \n  copy_file config /etc/initramfs-tools/wpa_supplicant.conf /etc/wpa_supplicant.conf\n  ```\n  \n- `/etc/initramfs-tools/scripts/init-bottom/kill_wireless`\n\n  ```bash\n  #!/bin/sh\n  PREREQ=\"\"\n  prereqs()\n  {\n      echo \"$PREREQ\"\n  }\n  \n  case $1 in\n  prereqs)\n      prereqs\n      exit 0\n      ;;\n  esac\n  \n  # allow the decrypted OS to handle WiFi on its own\n  echo \"Stopping wlan device...\"\n  kill $(cat /run/initram-wpa_supplicant.pid)\n  ip link set wlan0 down\n  ```\n  \n- `/etc/initramfs-tools/wpa_supplicant.conf`\n\n  ```bash\n  ctrl_interface=/tmp/wpa_supplicant\n  country=GB\n  \n  network={\n      ssid=\"Foo\"\n      scan_ssid=1\n      psk=\"Bar\"\n      key_mgmt=WPA-PSK\n  }\n  ```\n\nNote that this will only set up WiFi in the initramfs. The decrypted OS needs to be configured separately.\n\nChmod all scripts you just created:\n\n```bash\nchmod +x /etc/initramfs-tools/scripts/init-premount/a_enable_wireless\nchmod +x /etc/initramfs-tools/hooks/enable-wireless\nchmod +x /etc/initramfs-tools/scripts/init-bottom/kill_wireless\n```\n\nYou may want to disable onboard WiFi from the decrypted OS so it doesn't conflict with your external USB card:\n\n```sh\necho \"dtoverlay=disable-wifi\" >> /boot/config.txt\n```\n\nYou're done! Follow the rest of the guide to finish building your initramfs.\n\n## Resources\n\n- [Wireless-Builtin.md](Wireless-Builtin.md)\n- https://github.com/morrownr/USB-WiFi/blob/main/home/USB_WiFi_Adapters_that_are_supported_with_Linux_in-kernel_drivers.md\n"
  }
]