[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

iwd + systemd-networkd + resolvconf wrinkles



This might be considered a reply to:
https://lists.debian.org/debian-user/2022/02/msg00118.html
or the couple of threads around:
https://lists.debian.org/debian-user/2021/09/msg01052.html
or even:
https://lists.debian.org/debian-user/2019/04/msg01013.html

Now that wicd has gone (no Python2), and allegedly wpasupplicant
is not long for this world, I was casting round for a simple way
to run iwd + resolvconf + systemd-networkd as replacement.

  iwd               Highly functional & low resource & DHCP client.
                    Minimally documented¹, only does wifi (no wired)

  resolvconf        Should configure varying nameservers into
                    resolv.conf for different networks/interfaces.

  systemd-networkd  Runs the wired interfaces.

As the debian-installer installs wpasupplicant, this is
necessarily a conversion process, outlined briefly here,
a combination of howto and diary:

Install iwd, and resolvconf if necessary. You may then need to reboot
if the wifi interface has already been renamed by the kernel, ie if
it's not wlan0. (With buster, there's a missing file that needs adding
first; see below).

$ systemctl --now disable wpa_supplicant.service
$ systemctl --now enable iwd.service

(Those commands are quieter when done as root, or with sudo.)

$ iwctl
Waiting for IWD to start...
[iwd]#

This section is interactive. Some of the commands here are just to
confirm its actions and replies. Don't type the "iwctl" before each
command: it's only needed when typing into a bash prompt, as opposed
to the [iwd]# prompt².

  iwctl adapter list
  iwctl adapter phy0 show
  iwctl device list
  iwctl device wlan0 show
  iwctl station list
  iwctl station wlan0 show
  iwctl station wlan0 get-networks
  iwctl station wlan0 connect YourSSID
    Type the network passphrase for Cascade5G psk.
    Passphrase: *********************************
  iwctl known-networks list
  iwctl station wlan0 show

By the end of all this, the link should be working, and a file
like this will have been written (that only root can see):

# cat /var/lib/iwd/YourSSID.psk 
[Security]
PreSharedKey=abdcef0123456789…abdcef0123456789…abdcef0123456789
Passphrase=yoursecretpassphrase
# 

The other file that I have created on my bullseye is:

# /etc/iwd/main.conf
[General]
# use DHCP client built into iwd:
EnableNetworkConfiguration=true
# for use only when travelling:
#AddressRandomization=network
[Network]
# systemd-resolved would otherwise default:
NameResolvingService=resolvconf
#

That should be enough to get connected to a router via wifi
as soon as it boots up, with DHCP supplying an IP address, and
contents for resolv.conf. However, the latter does not happen
until I make one other change.

The problem appears to be that iwd doesn't have necessary
permission to mess with /run/resolvconf and /etc/resolv.conf.
AIUI it's not file permissions, but internal policy within
systemd. The simplest fix seems to be:³

# cp -ip /lib/systemd/system/iwd.service /etc/systemd/system/

# edit /etc/systemd/system/iwd.service and add these two lines
  to the end of the [Service] section:

RuntimeDirectory=resolvconf
ReadWritePaths=/etc

The error being eliminated can be seen in /var/log/daemon.log:

  iwd[…]: /usr/sbin/resolvconf: 57: cannot create
             /run/resolvconf/run-lock: Read-only file system
  iwd[…]: resolve: /usr/sbin/resolvconf exited with status (512).

After fixing and rebooting, you should get something like:

/run/resolvconf/:
-rw-r--r-- 1 root root   0 enable-updates
drwxr-xr-x 2 root root  60 interface
-rw-r--r-- 1 root root 298 resolv.conf
-rw-r--r-- 1 root root   0 run-lock

/run/resolvconf/interface:
-rw-r--r-- 1 root root 23 wlan0.dns
$ 

Note that the comments in /run/resolvconf/resolv.conf are
misleading, and assume that we're using systemd-resolved.
Running  "resolvectl status", as suggested there, gives:
Failed to get global data: Unit dbus-org.freedesktop.resolve1.service not found.

Why don't I use systemd-resolved? (a) I don't understand its
documentation, nor its diagnostic output, and (b) it was slow
resolving, say, google.com, and threw an error rather than
resolve www.google.com. Not a lot of use to me.

If you try this on buster, which has a very old version of iwd,
you need to create this file to prevent the kernel from renaming
the wifi interface, which can cause a race with iwd.

# /etc/systemd/network/80-iwd.link
[Match]
Type=wlan
[Link]
# prevent udev from renaming this interface:
NamePolicy=keep kernel
#

Also, the EnableNetworkConfiguration=true doesn't appear to
have been implemented on buster's version 0.14, so the IP
configuration has to be left up to systemd-networkd with:

# cat /etc/systemd/network/80-wifi-station.network 
[Match]
Name=wlan0
[Network]
DHCP=yes
# 

(/usr/lib/systemd/network/80-wifi-station.network.example is
taken from bullseye, but simplified.) However, I haven't seen
any nameservers being added to resolv.conf in buster.

Back in bullseye, I can simultaneously configure a static interface
with the same IP address on the wired ethernet interface, which is
a useful backup for my LAN in the absence of wifi.

However, I haven't yet worked out how to make systemd-networkd
talk to resolvconf (whilst sharing with iwd) so that the wired
interface can resolve Internet addresses.

This thread is covering a similar lack when using NetworkManager:
https://lists.debian.org/debian-user/2022/03/msg00484.html
and I'm currently looking through references in:
https://unix.stackexchange.com/questions/517919/systemd-way-to-disable-wlan-if-wired-network-is-available

Because all my computers can intercommunicate on my LAN using
/etc/hosts, it's not too much of an issue at present. I can
even update/upgrade through my local apt-cacher-ng.

¹ virtually none in buster.

² If you want to log your conversation, it's easiest to run each
  iwctl command separately at a shell prompt and copy/paste the
  output. Using script on an interactive session is not the way to go.

³ Don't alter anything in /lib, but override and supplement things
  in /etc.

Cheers,
David.


Reply to: