---
title: "GNU/Linux wireless networking like it's 2020"
subtitle: "How to add some systemd stuff inside your network configuration"
date: 2020-07-14
draft: false
tags: [ops, systemd, network, wireless]
---

# From netcl to iwd 📡

ArchLinux is installed on my laptop (an XPS 15) since I got it from my job in
2017[^1]. 3 years ago, the cli tool distributed within the distribution was
`netctl`. It's an in-house [ArchLinux
project](https://git.archlinux.org/netctl.git/) 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

```sh
systemctl enable --now iwd.service
```

and open the interactive shell

```sh
iwctl
```

then list all networks

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

```sh
[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 :

```sh
[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

```txt
[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-networkd`[^2] 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

```sh
systemctl enable --now systemd-networkd.service
```

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

```txt
[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](https://en.wikipedia.org/wiki/DNS_over_TLS).

As usual to enable it :

```sh
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`.

```txt
# 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

```sh
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

- https://wiki.archlinux.org/index.php/Iwd
- https://wiki.archlinux.org/index.php/Systemd-networkd
- https://wiki.archlinux.org/index.php/Systemd-resolved

[^1]: And it runs on [btrfs](https://en.wikipedia.org/wiki/Btrfs) with absolutely no troubles for more than 3 years
[^2]: A systemd subservice handling networking stuff