From 8964e6218f3257aeaf0c184e4895e2f8bf317c9f Mon Sep 17 00:00:00 2001 From: Collin Williams <96917990+bluedragon1221@users.noreply.github.com> Date: Sat, 22 Aug 2026 17:17:49 -0500 Subject: update css, rename article, move assets to selfhosted --- minimalnetworkinglaptop.html | 173 ------------------------------------------- 1 file changed, 173 deletions(-) delete mode 100644 minimalnetworkinglaptop.html (limited to 'minimalnetworkinglaptop.html') diff --git a/minimalnetworkinglaptop.html b/minimalnetworkinglaptop.html deleted file mode 100644 index bc07c9b..0000000 --- a/minimalnetworkinglaptop.html +++ /dev/null @@ -1,173 +0,0 @@ - - - - Minimal Laptop Networking with NixOS - - - - -
-
- -

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

- -

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

- -
- -

The default stack

-

If not configured otherwise, NixOS uses the following stack:

- -

We'll be replacing it with:

- -

- 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[2]. - 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. -

- -

So the first thing we can do is disable all of the default stuff:

-
{
-  networking = {
-    networkmanager.enable = false;
-    dhcpcd.enable = false;
-    resolvconf.enable = false;
-    networking.useDHCP = false;
-  };
-}
- -

And let's get to configuring!

- -

iwd

-

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

-
{
-  networking.wireless.iwd = {
-    enable = true;
-    settings = {
-      General = {
-        EnableNetworkConfiguration = false; # delegated to networkd
-        AddressRandomization = "once";
-        AddressRandomizationRange = "full";
-      };
-      Network.NameResolvingService = "systemd"; # use systemd-resolved
-    };
-  };
-}
- -

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

- - -

systemd-networkd

-

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

-
- why disable DHCP-advertised DNS? - 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. -
- -
{
-  systemd.network = {
-    enable = true;
-
-    networks."11-default" = {
-      name = "wl*";
-      networkConfig.DHCP = "yes";
-
-      # never accept dhcp dns
-      dhcpV4Config.UseDNS = "no";
-      dhcpV6Config.UseDNS = "no";
-    };
-  };
-  networking.useNetworkd = true;
-}
- -

- The name = "wl*" - 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"[3]. - Here we use a glob (*) to match all wireless interfaces. -

- -

You can verify that your configuration worked with a few commands:

- - -

systemd-resolved

-

- 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 quad9, but do your own research and find the best upstream DNS server for you! - Some other options include Cloudflare DNS, Google's DNS, or AdGuard Public DNS. -

-
{
-  networking.nameservers = [
-    "9.9.9.9#dns.quad9.net"
-    "149.112.112.112#dns.quad9.net"
-  ];
-
-  services.resolved = {
-    enable = true;
-    settings.Resolve = {
-      DNSOverTLS = true;
-      DNSSEC = "allow-downgrade";
-
-      LLMNR = false;
-      MulticastDNS = false;
-    };
-  };
-}
- -

You can verify your DNS configuration by using the resolvectl status - command or by just opening a website.

- -

P.S. Captive portals

-

- 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 Captive Browser - (nixpkgs), 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.P.S. I miss nm-applet

-

- 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 iwmenu, which is a launcher (dmenu, rofi, fuzzel)-based menu for connecting to wifi networks via iwd. -

-
- - -- cgit v1.3.1