Goodbye NetworkManager. Hello decent network configuration
I was recently experiencing problems with the wireless interface on my Debian 11 home server. The connection was very
instable and I could observe rtlwifi: AP off, try to reconnect now
entries in the kernel log. My first thought was a
power management issue with my wireless adapter, so I put
options rtl8188ee swenc=1 ips=0 swlps=0 fwlps=0 aspm=0
into /etc/modprobe.d/rtl8188ee.conf
. However, this did not solve the problem.
iwd
Somewhere I read that it might be NetworkManager's fault, so I decided to give iwd (iNet Wireless Daemon) a try. The setup couldn't be easier, and as always, the Arch Wiki has a very good documentation. First disable NetworkManager and enable iwd:
# systemctl disable --now NetworkManager.service
# systemctl enable --now iwd.service
Then, just connect to your wireless network using iwctl station $IWDEV connect $YOURSSID
. The credentials are stored
in /var/lib/iwd/$SSID.psk
and the connection will be established automatically the next time you boot. That's it for
the wireless connection. However iwd is not particulary good at configuring your network interfaces with irrelevant
details like an IP address. For example, IPv6 is disabled by default (wtf, it's 2022 guys). Even after I manually
enabled IPv6, I couldn't really get it to work as expected. So I decided to use systemd-networkd for this.
systemd-networkd
As I already disabled NetworkManager, it couldn't interfere with systemd-networkd. However, your mileage may vary. Make
sure there is no /etc/network/interfaces*
, netplan or anything else also trying to configure your network interface.
The configuration goes to /etc/systemd/network/wireless.network
in my case, and is quite straight forward:
[Match]
# Name=wlan0
Type=wlan
[Network]
DHCP=ipv4
IgnoreCarrierLoss=true
IPv6AcceptRA=true
[IPv6AcceptRA]
UseDNS=false
[DHCPv4]
UseDNS=false
As I only have one wireless interface, I decided to use Type=wlan
, but it's also perfectly fine to specify the
wireless interface. Again have a look at the great Arch Wiki documentation on
systemd-networkd or man systemd.network
for details.
Then enable systemd-networkd by systemctl enable --now systemd-networkd.service
. As I wanted to play with DNS over
TLS, I decided to put UseDNS=false
in there and use systemd-resolved for DNS.
systemd-resolved
I just found out that the VPN provider Mullvad offers free ad-blocking DoT-ready DNS
servers. The german Wikipedia also has a list of
DoT-ready DNS servers for you. The DNS
configuration goes to /etc/systemd/resolved.conf
and effectively just looks like this in my case:
[Resolve]
DNS=2a07:e340::3#adblock.doh.mullvad.net 194.242.2.3#adblock.doh.mullvad.net 193.19.108.3#adblock.doh.mullvad.net
DNSOverTLS=yes
FallbackDNS=2a00:f826:8:1::254 2a01:4f8:1c0c:82c0::1 94.247.43.254 88.198.92.222
If DoT on the Mullvad servers does not work for whatever reason, I fallback to using DNS servers of the OpenNIC project. systemd-resolved has some fallback servers from Cloudflare, Google and Quad9 builtin, but I don't want to use them, even in case.
After enabling systemd-resolved (run systemctl enable --now systemd-resolved.service
) you can already resolve your
first domain names securely and ad-free. For example try resolvectl query analytics.google.com
. Oh no, Google
Analytics resolves to 0.0.0.0, that's sad, isn't it? However, you will notice that other DNS resolvers on your system
don't respect your wishes for an ad-free world and happily resolve domain names using whatever nameserver is configured
in your legacy /etc/resolv.conf
. systemd-resolved provides a stub dns resolver listening on localhost:53 for this and
you can configure it system-wide by symlinking to a pseudo resolv.conf like this:
# rm /etc/resolv.conf
# ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
Conclusion
I am happy to say, that I finally have a stable wireless connection on my home server, thanks to iwd and systemd-networkd. As a plus, I am now enjoying an ad-free and privacy-friendly DNS experience. Nice :)