It is time to revisit of the simple wifi setup as much has changed since. This time, however, we will not only cover wifi, but also wired connections as well as DNS.
Wired networking
This wired setup is based on systemd-networkd
, which typically comes with systemd. If you use a systemd-based Linux, you should be ready to go right away.
It further assumes that acquiring an IP address via DHCP once a cable is plugged in the typical usecase.1
Create the file /etc/systemd/network/cable.network
2:
[Match]
Name=<name of the wired network device> <second one if applicable> [<more ...>]
[Network]
DHCP=yes
IPv6PrivacyExtensions=true
[DHCP]
Anonymize=true
Then systemctl enable --now systemd-networkd
and plug in a cable, wired networking with DHCP is up and running.
Wireless networking
The wireless setup is based on iwd, the currently vastly superior tool for wireless networking on Linux compared to existing alternatives such as wpa_supplicant
(the effectively only other contender in this game) and software using it such as NetworkManager
and netctl
.
It requires iwd
as well as Linux >= 4.20
for full operation.
Create the file /etc/iwd/main.conf
:
[General]
# uncomment for setting the wifi interface name yourself
# see https://iwd.wiki.kernel.org/interface_lifecycle
#UseDefaultInterface=true
# enable builtin DHCP-client within iwd for wifi
EnableNetworkConfiguration=true
# randomizes mac-address every time iwd starts or the hardware is initially detected
AddressRandomization=once
Then systemctl enable --now iwd
, wireless networking with DHCP is up and running, blazingly fast and stable.
You might want to take a look at the previous post to deal with race conditions that might be introduced due to iwd being significantly faster than other wifi-solutions on Linux.
Frontends
iwd
stores its known networks in /var/lib/iwd
. To add, modify or delete them, several options are available:
iwctl
You can now connect to simple PSK wifi networks in the iwctl
shell:
[iwctl] station <devicename> get-networks
…
[iwctl] station <devicename> connect <network-name>
iwctl
will ask you for the password, iwd
will memorize it for later connections and autoconnect the next time the network appears.
Currently, iwctl
only supports creating simple password-only network connections, for more complex network setups, instead of iwctl
asking you all the nifty details of an enterprise connection, use the file-based config instead.
For everything else, just type help
within iwctl
.
file-based config
If you have more complex wifi-setups, you can simply drop a network configuration file in /var/lib/iwd
.
The files must be named as networkname.protocol
.
You can find the protocol listed in the output of get-networks
in the iwctl-shell.
To fill the file, take a look to the network configuration settings in the iwd documentation or the iwd.network
manpage.
For example, to use the University Heidelberg’s eduroam network, create the file /var/lib/iwd/eduroam.8021x
containing
[Security]
EAP-Method=TTLS
EAP-Identity=<anonymous-identity>
EAP-TTLS-CACert=/etc/ssl/certs/T-TeleSec_GlobalRoot_Class_2.pem
EAP-TTLS-Phase2-Method=MSCHAPV2
EAP-TTLS-Phase2-Identity=<uni-id>@uni-heidelberg.de
EAP-TTLS-Phase2-Password=<your University account password>
For other institutions, the details in the method might vary, of course. See man iwd.network
for details. It also includes several examples for almost all possible configurations.
Network Manager
You can also use Network Manager for a more graphical experience, you just have to enable the iwd-backend for NetworkManager to use it.
In addition to that, double check if you have the right NetworkManager version for your iwd
version, just as a precaution.
DNS
For modern domain name resolution, you can use systemd-resolved
, which provides statistics, automated caching of DNS requests, DNSSEC validation and much more.
To use it, ensure systemd-resolved is installed3 and systemctl enable --now systemd-resolved
.
Ensure that /etc/resolv.conf
is symlinked to /run/systemd/resolve/stub-resolv.conf
, if not
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
takes care of it.
Afterwards, you can change the default fallback DNS servers and other things in /etc/systemd/resolved.conf
, if desired and otherwise enjoy resolvectl
and resolvectl statistics
.
Miscellaneous optimizations
Binding iwd to the wifi-device
To disable iwd when the wifi is not present (and iwd therefore not needed) create the file /etc/udev/rules.d/wifi.rules
containing
# bind iwd to wifi
SUBSYSTEM=="rfkill", ENV{RFKILL_NAME}=="phy0", ENV{RFKILL_TYPE}=="wlan", ACTION=="change", ENV{RFKILL_STATE}=="1", RUN+="/usr/bin/systemctl --no-block start iwd.service"
SUBSYSTEM=="rfkill", ENV{RFKILL_NAME}=="phy0", ENV{RFKILL_TYPE}=="wlan", ACTION=="change", ENV{RFKILL_STATE}=="0", RUN+="/usr/bin/systemctl --no-block stop iwd.service"
If AddressRamdomization=once
is set in the configuration, this udev rule has the nice side-effect that, as iwd
starts nanew when the wifi is un-rfkilled, the MAC address of the interface is randomized again.
Persistent device naming
If you want to have persistent device names, for example for devices showing up in a status bar or something similar, this ist easiest achieved by creating a link
-file4 /etc/systemd/network
. To persistently name the wireless device wifi
, create /etc/systemd/network/00-wifi.link
containing
[Match]
MACAddress=ab:cd:ef:12:34:56 # wifi's original MAC address
[Link]
Name=wifi # can be used for matching in the according *.network-file
If you do this for any device operated by iwd, ensure you have UseDefaultInterface=true
set in section [General]
in /etc/iwd/main.conf
.
Setting specific MAC addresses for specific wifi networks and randomizing on every connect
In case you need to set a specific address for a specific wireless network, iwd>=1.6
allows using AddressOverride=
inside a network configuration file. For this to take effect, however, AddressRandomization=once
must be dropped from /etc/iwd/main.conf
. This makes iwd
generate persistent MAC addresses per network (generated from its SSID and real hardware address) by default and allows AddressOverride
to take effect.
Additionally, a network file can contain AlwaysRandomizeAddress=true
, which randomizes the MAC address on each connect for this network (also only takes effect when AddressRandomization
is not set or set do its default value in main.conf
.
However, due to kernel limitations, each change of a MAC address requires powercyling the card. This leads to (for iwd
standards) singificantly prolonged connection times (by ≈300-400ms).
Given that, as long as you do not require AddressOverride
, AddressRandomization=once
gives you fast connection times while still randomizing your card’s MAC address regularly enough.
Thanks to rixx for proofreading and helpful suggestions.
-
Although this if of course an assumption, my personal statistics says that this setup has worked with 100% of all network cables I ever plugged into my laptop so far. ↩︎
-
see
man systemd.network
(preferrably, as it fits your version) or https://www.freedesktop.org/software/systemd/man/systemd.network.html for the latest docs. ↩︎ -
The simplest check is
systemctl status systemd-resolved
. ↩︎ -
see
man systemd.link
or https://www.freedesktop.org/software/systemd/man/systemd.link.html ↩︎