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