GNU/Linux wireless networking like it's 2020

How to add some systemd stuff inside your network configuration

From netcl to iwd 📡

ArchLinux is installed on my laptop (an XPS 15) since I got it from my job in 20171. 3 years ago, the cli tool distributed within the distribution was netctl. It’s an in-house ArchLinux project allowing users to manage networking. Overall, the tool does everything I need to get a network connection up and running the way I need it. One of the main thing I dislike about it is wifi-menu, a poorly design UI to search for wireless access points.

Not so long ago a new challenger appeared : iwd. iNet Wireless Daemon (iwd) is new wireless daemon for GNU/Linux (a standard tool, available on all distros is better for this kind of tasks). Even if this project aims to replace wpa_supplicant it can also replace netctl. If you think it’s a toy project from some random guy over the internet, bad news for you, that guy is : Intel™. The fact that this program acts as a daemon means one standing point : multiple clients will be available in the future and some well known managers like network-manager might also use it. A default one comes with the package as an interactive shell called iwctl, bye-bye wifi-menu !

To begin with iwd enable and start the service

systemctl enable --now iwd.service

and open the interactive shell

iwctl

then list all networks

[iwd] station wlan0 get-networks
                               Available networks
--------------------------------------------------------------------------------
    Network name                    Security  Signal
--------------------------------------------------------------------------------
    ORTHANC                         psk       ****
    MINAS ITHIL                     psk       ****
    MINAS TIRITH                    psk       ****
[iwd] station wlan0 connect ORTHANC

Enter the password if needed, it will be saved for later use (in /var/lib/iwd) and check if everything is ok :

[iwd] station wlan0 show
                                 Station: wlan0
--------------------------------------------------------------------------------
  Settable  Property            Value
--------------------------------------------------------------------------------
            Scanning            no
            State               connected
            Connected network   ORTHANC

On reboot, iwd will try to reconnect to last used connection.

Adding some salty systemd stuff 🧂

Connected, sure, but what about an IP address 🤡 ? The first option is obviously dhcpd but it scales poorly if you have to type it everytime you connect to a network. Since version 0.19 iwd comes with a built-in DHCP client to enable it just add

[General]
EnableNetworkConfiguration=true

in /etc/iwd/main.conf.

For some people it’s good enough, but you know me, I like systemd a lot and i’m already using systemd-networkd2 to create various kind of static network interfaces and network connections.

To let systemd-networkd get DHCP configuration for you, ensure systemd-networkd is enabled

systemctl enable --now systemd-networkd.service

Now, add a .network file (in /etc/systemd/network) for the main wifi interface

[Match]
Name=wlan0

[Network]
DHCP=yes

The match section is used to identify the interface by name, the network one ensures that this configuration comes from DHCP.

Now that everything is setup, systemd-networkd will get configuration for this interface when requested by changes on wifi interface from iwctl.

More salt with systemd-resolved 👺

In order to piss off the ones who hate systemd, I decided to add systemd-resolved into the mix.

systemd-resolved is a systemd subservice providing a local DNS system with caching, DNSSEC or the cool new kid : DNS over TLS.

As usual to enable it :

systemctl enable --now systemd-resolved.service

The common way to change the DNS configuration is the good old /etc/resolv.conf file. With systemd-resolved the recommended and most disruptive way is to symlink the generated stub file /run/systemd/resolve/stub-resolv.conf to /etc/resolv.conf.

# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "resolvectl status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs should typically not access this file directly, but only
# through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a
# different way, replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 127.0.0.53
options edns0
search example.lan example.com

The stub file contains only the local DNS stub server from systemd-resolved (available on 127.0.0.53).

The main purpose of this server is a caching implementation avoiding useless DNS requests.

To get an idea of the number of requests where the cache is used, just check statistics

resolvectl statistics
DNSSEC supported by current servers: no

Transactions
Current Transactions: 0
  Total Transactions: 8544

Cache
  Current Cache Size: 65
          Cache Hits: 2394
        Cache Misses: 3939

To customize systemd-resolved configuration, just look at systemd-revolved(8) and the config file in /etc/systemd/resolved.conf (resolvctl with no argument can be used to get information about the current configuration).

This is, in my opinion, the best networking config I ever have.

Happy systemding !

Ressources


  1. And it runs on btrfs with absolutely no troubles for more than 3 years ↩︎

  2. A systemd subservice handling networking stuff ↩︎