Skip to content
Andrei Pozolotin edited this page Sep 14, 2021 · 3 revisions

based on issue #27
based on issue #86

The below solution enables connecting to a wireless network secured with a password to be usable during boot time. It uses a custom systemd service that connects to the correct network using wpa_supplicant. It relies on the existing initrd-network.service with the specific network interface being configured per initrd-network.network (by systemd-networkd) and followed by a custom service that starts wpa_supplicant to connect to the network.

Manual Testing

It is useful to manually get into an initrd-shell and setup the network during boot once by hand to make sure you get all the needed configuration options correctly. it's also useful for debugging the proper setup, or lookup status/error-messages from the new service. Enable the debug shell (temporarily) for doing this:

systemctl enable initrd-debug-shell.service

For initial testing, it may be helpful to manually include some needed binaries in your initramfs by adding them to the FILES section of /etc/mkinitcpio.conf. wpa_supplicant & wpa_passphrase are useful binaries to include during testing. You can undo all of this later once you have the proper setup described below.

Rebuild using mkinitcpio and then reboot & get to the debug shell (Ctrl-Alt-F8 usually). Manually see if you can setup & connect to the wireless network using regular network connections instructions. See also wpa_supplicant. Typically this requires upping the network interface, use wpa_supplicant to connect & authenticate to the network, and then configure ip via DHCP.

Make sure to note the network interface name available during boot as it may be different in initrd vs what you normally see after booting up fully into user mode.

Setup Instructions

Generate your wpa_supplicant config under /etc/wpa_supplicant/wpa_supplicant.conf. See wpa_supplicant wiki for more details. An easy way is to use wpa_passphrase with your SSID & passphrase.

Add the following custom unit file to /etc/systemd/system/initrd-wifi.service. Edit the wifi interface name as required if you have something other than wlan0 (*See notes).

[Unit]
Description=Initrd Wpa Service
ConditionPathExists=/etc/initrd-release
Requires=initrd-network.service
After=initrd-network.service
Before=cryptsetup-pre.target
Before=initrd-tinysshd.service
DefaultDependencies=no


[Service]
# Sleep as a hacky solution instead of a proper systemd ordering dependency.
ExecStart=/usr/bin/sh -c "/usr/bin/sleep 5; /usr/bin/wpa_supplicant -W -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf"

[Install]
WantedBy=sysinit.target

[X-SystemdTool]

InitrdPath=/etc/wpa_supplicant/wpa_supplicant.conf
InitrdBinary=/usr/bin/wpa_supplicant

Edit /etc/mkinitcpio-systemd-tool/network/initrd-network.network to match the same interface as above. e.g

...
[Match]
Name=wlan0
...

Enable the above service & rebuild your initramfs:

sytemctl enable initrd-wifi.service
mkinitcpio -P

That should be all! Reboot and test if it connects to the wifi on boot.

Notes & Tips

  • Sometimes all the needed modules for your wifi device might not be included in initramfs causing the device not to be available during boot or worse partially loaded and failed preventing the device from properly showing up even after full boot has completed. If this happens make sure to include the extra modules under the MODULES section of /etc/mkinitcpio.conf. See Issue #27 for an example for iwlwifi devices.
  • The wirelss interface name typically gets renamed in proper boot. e.g it may be wlan0 at boot, but renamed to wlo1 . Check through dmesg logs or get into an initrd shell to see the interface's name. For more details see: https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
    https://unix.stackexchange.com/questions/400893/renaming-my-wlan-network-interface
  • The above setup includes a sleep before starting wpa_supplicant. This is a hack to make sure the interface is already up and started by the other services. Without it, wpa_supplicant may start too early and fail as it requires the interface & drivers to already be setup. There may be a better solution here to have the ordering specified to systemd.