diff options
Diffstat (limited to 'minimalnetworkinglaptop.html')
| -rw-r--r-- | minimalnetworkinglaptop.html | 173 |
1 files changed, 0 insertions, 173 deletions
diff --git a/minimalnetworkinglaptop.html b/minimalnetworkinglaptop.html deleted file mode 100644 index bc07c9b..0000000 --- a/minimalnetworkinglaptop.html +++ /dev/null @@ -1,173 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <title>Minimal Laptop Networking with NixOS</title> - <meta property="article:published_time" content="2026-07-29"> - <script src="article.js"></script> - </head> - <body> - <article> - <header></header> - - <p> - The default networking stack on NixOS uses NetworkManager. - While it's a great choice for many users, I prefer a lighter setup built around systemd-networkd, systemd-resolved, and iwd. It integrates well with the rest of the systemd stack, has fewer moving pieces, and exposes powerful networking features without an additional network management daemon. - </p> - - <p class="comment"> - This article focuses on laptops that connect to wifi. - If you're configuring a server, you probably don't need iwd at all; systemd-networkd and systemd-resolved are usually sufficient. - </p> - - <div id="toc"></div> - - <h2>The default stack</h2> - <p>If not configured otherwise, NixOS uses the following stack:</p> - <ul> - <li>NetworkManager for wifi</li> - <li>dhcpcd for DHCP</li> - <li>resolvconf for DNS</li> - <li>a "legacy script based system" for network configuration<sup><a href="https://search.nixos.org/options?channel=26.05&query=useNetworkd&type=options#show=option%253Anetworking.useNetworkd:~:text=legacy%20script%20based%20system">[1]</a></sup></li> - </ul> - <p>We'll be replacing it with:</p> - <ul> - <li>iwd for wifi</li> - <li>systemd-networkd for DHCP and network configuration</li> - <li>systemd-resolved for DNS</li> - </ul> - <p> - This has a few benefits. - Firstly, switching to resolved allows you to enable features like encrypted DNS over TLS (DoT) and DNSSEC validation, which reduces the potential for DNS spoofing and man-in-the-middle attacks<sup><a href="https://whynothugo.nl/journal/2026/06/24/ignore-dnssec-if-you-like-mitm-attacks/#distributions-and-oss">[2]</a></sup>. - Additionally, the default stack uses 3 extra packages (NM, dhcpcd, resolvconf) and some bash scripts, while this setup only uses one extra package (iwd). - Also, I'm kind of a systemd nerd, and this is a way to dig into systemd a bit more. - </p> - - <p>So the first thing we can do is disable all of the default stuff:</p> - <pre><code>{ - <prop>networking</prop> = { - <prop>networkmanager</prop>.<prop>enable</prop> = <kw>false</kw>; - <prop>dhcpcd</prop>.<prop>enable</prop> = <kw>false</kw>; - <prop>resolvconf</prop>.<prop>enable</prop> = <kw>false</kw>; - <prop>networking</prop>.<prop>useDHCP</prop> = <kw>false</kw>; - }; -}</code></pre> - - <p>And let's get to configuring!</p> - - <h2>iwd</h2> - <p> - First up is iwd. - The important parts of the configuration are delegating network configuration to networkd, delegating name resolution (DNS) to resolved, and configuring MAC randomization for some extra privacy. - </p> - <pre><code>{ - <prop>networking</prop>.<prop>wireless</prop>.<prop>iwd</prop> = { - <prop>enable</prop> = <kw>true</kw>; - <prop>settings</prop> = { - <prop>General</prop> = { - <prop>EnableNetworkConfiguration</prop> = <kw>false</kw>; <com># delegated to networkd</com> - <prop>AddressRandomization</prop> = <str>"once"</str>; - <prop>AddressRandomizationRange</prop> = <str>"full"</str>; - }; - <prop>Network</prop>.<prop>NameResolvingService</prop> = <str>"systemd"</str>; <com># use systemd-resolved</com> - }; - }; -}</code></pre> - - <p> - At this point, we don't have any network configuration yet, so internet access won't work. However, you can verify that iwd is functioning correctly: - </p> - <ul> - <li><code><kw>iwctl</kw> <prop>station</prop> <prop>wlan0</prop> <prop>scan</prop></code>: Scans for new wifi networks</li> - <li><code><kw>iwctl</kw> <prop>station</prop> <prop>wlan0</prop> <prop>get-networks</prop></code>: lists the networks that it found</li> - <li><code><kw>iwctl</kw> <prop>station</prop> <prop>wlan0</prop> <prop>connect</prop> <str>"<SSID>"</str></code>: connects to the network, prompting for a PSK if necessary</li> - </ul> - - <h2>systemd-networkd</h2> - <p> - Next up is systemd-networkd. - Networkd has lots of advanced options for things like static IP config, Wireguard tunnels, VLANs, domain-based DNS routing, and more. - However, here we'll just do a basic configuration to enable DHCP and deny DHCP-advertised DNS. - </p> - <details class="comment"> - <summary>why disable DHCP-advertised DNS?</summary> - By default, most networks advertise their own DNS resolver via DHCP. - Since we'll configure our own encrypted upstream DNS servers in the next section, we tell networkd to ignore the ones provided by the network. - </details> - - <pre><code>{ - <prop>systemd</prop>.<prop>network</prop> = { - <prop>enable</prop> = <kw>true</kw>; - - <prop>networks</prop>.<str>"11-default"</str> = { - <prop>name</prop> = <str>"wl*"</str>; - <prop>networkConfig</prop>.<prop>DHCP</prop> = <str>"yes"</str>; - - <com># never accept dhcp dns</com> - <prop>dhcpV4Config</prop>.<prop>UseDNS</prop> = <str>"no"</str>; - <prop>dhcpV6Config</prop>.<prop>UseDNS</prop> = <str>"no"</str>; - }; - }; - <prop>networking</prop>.<prop>useNetworkd</prop> = <kw>true</kw>; -}</code></pre> - - <p> - The <code>name = "wl*"</code> - refers to the network interface name that this configuration applies to. - According to the systemd docs, wireless LAN devices should start with the two-character prefix "wl"<sup><a href="https://www.freedesktop.org/software/systemd/man/latest/systemd.net-naming-scheme.html#:~:text=wl,WLAN">[3]</a></sup>. - Here we use a glob (<code>*</code>) to match all wireless interfaces. - </p> - - <p>You can verify that your configuration worked with a few commands:</p> - <ul> - <li><code><kw>ip</kw> <prop>addr</prop></code>: make sure that there's an IP address associated with your wireless interface. That means DHCP is working.</li> - <li><code><kw>networkctl</kw> <prop>status</prop></code>: make sure there's no significant errors in the logs.</li> - </ul> - - <h2>systemd-resolved</h2> - <p> - Now all we have left is DNS configuration, then we're done. - This is probably the part where you can nerd out the hardest, but I try to keep it pretty minimal. - The important parts are selecting upstream DNS servers that support secure DNS protocols (like DNS over TLS and DNSSEC) and that respect your privacy. - For these reasons, I use <a href="https://quad9.net">quad9</a>, but do your own research and find the best upstream DNS server for you! - Some other options include <a href="https://www.cloudflare.com/products/dns/">Cloudflare DNS</a>, <a href="https://developers.google.com/speed/public-dns/">Google's DNS</a>, or <a href="https://adguard-dns.io/en/public-dns.html">AdGuard Public DNS</a>. - </p> - <pre><code>{ - <prop>networking</prop>.<prop>nameservers</prop> = [ - <str>"9.9.9.9#dns.quad9.net"</str> - <str>"149.112.112.112#dns.quad9.net"</str> - ]; - - <prop>services</prop>.<prop>resolved</prop> = { - <prop>enable</prop> = <kw>true</kw>; - <prop>settings</prop>.<prop>Resolve</prop> = { - <prop>DNSOverTLS</prop> = <kw>true</kw>; - <prop>DNSSEC</prop> = <str>"allow-downgrade"</str>; - - <prop>LLMNR</prop> = <kw>false</kw>; - <prop>MulticastDNS</prop> = <kw>false</kw>; - }; - }; -}</code></pre> - - <p>You can verify your DNS configuration by using the <code><kw>resolvectl</kw> <prop>status</prop></code> - command or by just opening a website.</p> - - <h2>P.S. Captive portals</h2> - <p> - Captive portals are those wifi login pages that pop up when you connect to some public wifi networks. - Some captive portals don't behave correctly when you're using an encrypted third-party DNS server instead of the network's advertised resolver. - To get around this, I use <a href="https://github.com/FiloSottile/captive-browser">Captive Browser</a> - (<a href="https://search.nixos.org/packages?channel=26.05&query=captive-browser#show=captive-browser">nixpkgs</a>), which launches an instance of Chromium through a SOCKS5 proxy, avoiding the system DNS configuration altogether. - This allows you to access a captive portal for long enough to log in and gain internet access. - Pretty neat! - </p> - - <h2>P.P.S. I miss nm-applet</h2> - <p> - Probably the biggest downside to this setup is the lack of desktop integration. - GNOME and Plasma only support NetworkManager in their network configuration menu, so you're kinda out of luck. - For tiling window manager people, I can recommend <a href="https://github.com/e-tho/iwmenu">iwmenu</a>, which is a launcher (dmenu, rofi, fuzzel)-based menu for connecting to wifi networks via iwd. - </p> - </article> - </body> -</html> |
