diff --git a/README.md b/README.md index e8e78f4..543305f 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,12 @@ includes **Playwright CLI + matching Firefox**, with a writable, once-seeded Web profile on first startup, retained on restarts and updated explicitly. No host service is activated. +### System DNS + +`network.nix` enables **`systemd-resolved.service` on both hosts at boot**, with automatic restart after five seconds and no retry limit. NetworkManager supplies per-link DNS on the laptop; EC2 retains dhcpcd. NixOS connects `/etc/resolv.conf` to resolved's stub and provides the D-Bus service used by `resolvectl`. Upstream DNS still comes from DHCP/VPN configuration, not hard-coded public or private servers. An explicit `systemctl stop systemd-resolved` still stops it normally. + +Use `systemctl status systemd-resolved` and `resolvectl status` to inspect it. `sudo resolvectl dns krishna-laptop 192.168.1.19` sets DNS on that existing interface at runtime; it does not persist across interface recreation or reboot. Put persistent VPN DNS and any routing domains in the VPN/NetworkManager profile. + ### Local Tor client On both hosts, `network.nix` installs Tor from the **system pin** and enables `tor.service` at boot. It runs as the dedicated `tor` user with the NixOS module's sandbox and private persistent state in `/var/lib/tor`. Systemd restarts an exited daemon after five seconds without a retry limit; an explicit `systemctl stop tor` still stops it normally. A running process does not guarantee network connectivity—check for `Bootstrapped 100%` in the journal. diff --git a/network.nix b/network.nix index f752d94..9d6033d 100644 --- a/network.nix +++ b/network.nix @@ -1,5 +1,4 @@ { - config, inputs, lib, pkgs, @@ -8,14 +7,14 @@ let latest = import inputs.nixpkgs-latest { inherit (pkgs.stdenv.hostPlatform) system; - config = pkgs.config; + inherit (pkgs) config; }; in { - # NetworkManager owns local DNS on workstations. With dhcpcd (EC2), - # NixOS wires resolvconf to resolved. Preserve both hosts' existing behavior. + # Keep resolvectl available on both hosts. NixOS wires NetworkManager and + # /etc/resolv.conf to resolved; DHCP/VPNs still supply the upstream DNS. services.resolved = { - enable = lib.mkDefault (!config.networking.networkmanager.enable); + enable = true; settings.Resolve = { LLMNR = false; MulticastDNS = false; @@ -23,6 +22,15 @@ in }; }; + # The NixOS module enables resolved at boot. Retry exits without a start limit. + systemd.services.systemd-resolved = { + unitConfig.StartLimitIntervalSec = 0; + serviceConfig = { + Restart = "always"; + RestartSec = "5s"; + }; + }; + # Local, opt-in SOCKS client only. Keep the daemon on the system package pin. # No relay/exit, control listener, transparent proxy or host DNS changes. services.tor = { diff --git a/physical-test.nix b/physical-test.nix index ee46930..e4685ef 100644 --- a/physical-test.nix +++ b/physical-test.nix @@ -84,11 +84,38 @@ let { assertion = config.networking.networkmanager.enable - && !config.services.resolved.enable + && config.networking.networkmanager.dns == "systemd-resolved" && builtins.elem (lib.getName pkgs.networkmanager-openvpn) ( map lib.getName config.networking.networkmanager.plugins ); - message = "Keep NetworkManager/DNS and provide its OpenVPN integration."; + message = "Keep NetworkManager with resolved DNS and its OpenVPN integration."; + } + { + assertion = + lib.all + ( + c: + let + unit = c.systemd.services.systemd-resolved; + in + c.services.resolved.enable + && builtins.elem "sysinit.target" unit.wantedBy + && builtins.elem "dbus-org.freedesktop.resolve1.service" unit.aliases + && unit.serviceConfig.Restart == "always" + && unit.serviceConfig.RestartSec == "5s" + && unit.unitConfig.StartLimitIntervalSec == 0 + && !c.networking.resolvconf.enable + && c.networking.resolvconf.package == c.systemd.package + && c.environment.etc."resolv.conf".source == "/run/systemd/resolve/stub-resolv.conf" + && c.services.resolved.settings.Resolve.DNS == [ ] + && !c.services.resolved.settings.Resolve.LLMNR + && !c.services.resolved.settings.Resolve.MulticastDNS + ) + [ + config + ec2Config + ]; + message = "Both hosts need boot-enabled, restarting resolved with D-Bus/stub DNS integration, without hard-coded DNS servers."; } { assertion = @@ -232,7 +259,7 @@ pkgs.runCommand "physical-config-check" { } '' test -f "$sessions/wayland-sessions/hyprland-uwsm.desktop" test ! -e "$sessions/wayland-sessions/hyprland.desktop" for tool in wg wg-quick openvpn iperf3 nmap traceroute whois mtr dig tcpdump ethtool nc socat \ - fping drill torsocks proxychains4 tor nm-connection-editor; do + fping drill torsocks proxychains4 tor nm-connection-editor resolvectl; do test -x "${config.system.path}/bin/$tool" done # Validate the exact generated torrc offline without touching live Tor state.