Replacing WPA Supplicant with iwd in Ubuntu Eoan

While open-source software ecosystems encourage variation, variation is not guaranteed. Deep down the rabbit hole lay many tasks which are either too tedious or uncontroversial to warrant revising or replacing whatever ancient solution has been arrived at. In these cases, simply being “good enough” is good enough.

Until it isn’t.

Any time I read about a new driver or library or daemon or whatever that aims to overthrow something standard, I am intrigued. Why re-invent the wheel? Why now? And, most importantly, should I personally care?

An Example

For as long as I can remember, it has been necessary to install a package called WPA supplicant to give a Linux system basic wireless networking capabilities. While its early days were a bit hairy, it has, for a long time, been “good enough”.

As such, I was intrigued to read about Intel’s work on iwd, a new networking daemon written from the ground-up to address the modern demands of wireless networking, which unsurprisingly, don’t look very much like the demands that existed in 2003 when WPA supplicant was first released.

While still a work in progress, iwd is stable enough for most purposes, and can serve as a replacement for WPA supplicant, if that sort of thing intrigues you.

At the moment, I am happy to report that it is vaguely better! Its leaner code base leads to earlier and faster wireless networking connections, at least for me and my Thinkpad. I can’t even begin to count up how many milliseconds it has saved me, though I would guess the number would be in the thousands.

Installing iwd

Update 31 October 2019: The first stable release (1.0) of iwd has been added to the upcoming Fossa repo and can be downloaded and manually installed on Eoan (and probably Disco… though I didn’t try it). To use this version, download the .deb package and manually install it like:

sudo dpkg -i iwd_1.0-1_amd64.deb

If you prefer sticking with software present in your Ubuntu release’s official repository, that’s A-OK. Disco Dingo (19.04) and Eoan Ermine (19.10) users can pop a terminal and type the following to get an older, supported version:

sudo apt-get update && sudo apt-get install iwd

Regardless of the version, once you’ve installed it, it is a good idea to make sure the service is connected:

sudo systemctl enable iwd.service
sudo systemctl start iwd.service

Now you need to tell NetworkManager to use iwd for its backend. Open up /etc/NetworkManager/NetworkManager.conf in your favorite editor and add wifi.backend=iwd to the [device] section, giving you something like:

[main]
plugins=ifupdown,keyfile

[ifupdown]
managed=false

[device]
wifi.scan-rand-mac-address=no
wifi.backend=iwd

That, friends, would be that, except that Ubuntu does not yet realize that the iwd package it provides is a replacement for the wpa_supplicant package it also provides. A lot of packages mistakenly “depend” on wpa_supplicant, so any attempt to uninstall it would subsequently try to uninstall everything else, including the Ubuntu desktop itself! (i.e. Don’t do it!)

Making matters even more Kafkaesque, systemd services suffer similar silly dependency confusion. While you could certainly try to type sudo systemctl disable wpa_supplicant.service, the service will jump back to life with each and every boot.

To truly prevent wpa_supplicant from starting up, ever, you need to hack the systemd service directly. Open up /lib/systemd/system/wpa_supplicant.service in your favorite editor and replace the entire [Service] section with the following:

[Service]
# Type=dbus
# BusName=fi.w1.wpa_supplicant1
# ExecStart=/sbin/wpa_supplicant -u -s -O /run/wpa_supplicant
ExecStart=echo 1

Now whenever the pesky Lazarus task resurrects itself, instead of executing WPA, it will simply echo “1” and exit.

Check mate, Ubuntu!

Profit?

If you haven’t already done so, reboot your computer.

You may or may not be asked to resupply your WiFi network credentials, but after that, everything should be business as usual. If not, fear not! Simply redo the tutorial in reverse, undoing the few things you just did, and re-reboot to return to how things were.

If everything works, great! It should keep working, being “gooder enough”, for years to come. Just keep an eye out for package updates for wpa_supplicant. Every once in a while one comes down that will blow away the updated systemd service definition, requiring you to re-neuter it.