From 32b19799a1355805bf69222ef1abb6d806980ced Mon Sep 17 00:00:00 2001 From: Collin Williams <96917990+bluedragon1221@users.noreply.github.com> Date: Fri, 31 Jul 2026 08:16:20 -0500 Subject: minimal nixos networking + some css changes --- _template.html | 20 +++++ minimalnetworkinglaptop.html | 173 +++++++++++++++++++++++++++++++++++++++++++ prose.css | 4 +- writing.html | 1 + 4 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 _template.html create mode 100644 minimalnetworkinglaptop.html diff --git a/_template.html b/_template.html new file mode 100644 index 0000000..65cedc6 --- /dev/null +++ b/_template.html @@ -0,0 +1,20 @@ + + + + + + Title + + + + + +
+
+ +

+ lorem ipsum +

+
+ + \ No newline at end of file diff --git a/minimalnetworkinglaptop.html b/minimalnetworkinglaptop.html new file mode 100644 index 0000000..f9ca405 --- /dev/null +++ b/minimalnetworkinglaptop.html @@ -0,0 +1,173 @@ + + + + + + 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. +

+
+ + \ No newline at end of file diff --git a/prose.css b/prose.css index bc0ad5d..db54f26 100644 --- a/prose.css +++ b/prose.css @@ -93,11 +93,11 @@ time { } } -summary { +details { font-family: 'Gelasio'; color: #888; - &::marker { + summary::marker { color: #888; } } diff --git a/writing.html b/writing.html index dcb6d52..e04ebb3 100644 --- a/writing.html +++ b/writing.html @@ -18,6 +18,7 @@

My Writing