From dc56af5c6b283c75c823b85e88b9f7d55fcd7398 Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Mon, 2 Dec 2024 20:17:09 +0800 Subject: [PATCH] services/enthalpy: fixup dns leak in network namespace --- nixos/modules/services/enthalpy/common.nix | 4 - nixos/modules/services/enthalpy/ipsec.nix | 2 +- nixos/modules/services/enthalpy/services.nix | 99 ++++++++++++++++---- nixos/profiles/services/resolved/default.nix | 1 - 4 files changed, 83 insertions(+), 23 deletions(-) diff --git a/nixos/modules/services/enthalpy/common.nix b/nixos/modules/services/enthalpy/common.nix index bc0c660..6ead0e9 100644 --- a/nixos/modules/services/enthalpy/common.nix +++ b/nixos/modules/services/enthalpy/common.nix @@ -77,9 +77,5 @@ in after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; }; - - environment.etc."netns/enthalpy/resolv.conf".text = lib.mkDefault '' - nameserver 2606:4700:4700::1111 - ''; }; } diff --git a/nixos/modules/services/enthalpy/ipsec.nix b/nixos/modules/services/enthalpy/ipsec.nix index 2bae02c..34eabc0 100644 --- a/nixos/modules/services/enthalpy/ipsec.nix +++ b/nixos/modules/services/enthalpy/ipsec.nix @@ -88,7 +88,7 @@ in config = mkIf (cfg.enable && cfg.ipsec.enable) { assertions = [ { - assertion = builtins.all (lib.id) [ + assertion = builtins.all id [ (cfg.ipsec.blacklist != null -> cfg.ipsec.whitelist == null) (cfg.ipsec.whitelist != null -> cfg.ipsec.blacklist == null) ]; diff --git a/nixos/modules/services/enthalpy/services.nix b/nixos/modules/services/enthalpy/services.nix index ee10378..1c4bd6c 100644 --- a/nixos/modules/services/enthalpy/services.nix +++ b/nixos/modules/services/enthalpy/services.nix @@ -3,6 +3,7 @@ { config, lib, + pkgs, ... }: with lib; @@ -36,22 +37,86 @@ in }; }; - config = mkIf cfg.enable { - systemd.services = mapAttrs (_name: value: { - inherit (value) overrideStrategy; - serviceConfig = { - NetworkNamespacePath = "/run/netns/${cfg.netns}"; - BindReadOnlyPaths = "/etc/netns/${cfg.netns}/resolv.conf:/etc/resolv.conf:norbind"; - }; - after = [ "enthalpy.service" ]; - requires = [ "enthalpy.service" ]; - }) cfg.services; + config = mkIf cfg.enable (mkMerge [ + { + systemd.services = mapAttrs (_name: value: { + inherit (value) overrideStrategy; + serviceConfig = { + NetworkNamespacePath = "/run/netns/${cfg.netns}"; + BindReadOnlyPaths = [ + "/etc/netns/${cfg.netns}/resolv.conf:/etc/resolv.conf:norbind" + "/etc/netns/${cfg.netns}/nsswitch.conf:/etc/nsswitch.conf:norbind" + "/run/enthalpy/nscd:/run/nscd:norbind" + ]; + }; + after = [ "enthalpy.service" ]; + requires = [ "enthalpy.service" ]; + }) cfg.services; - services.enthalpy.services = mapAttrs' ( - name: _value: - nameValuePair "user@${toString config.users.users.${name}.uid}" { - overrideStrategy = "asDropin"; - } - ) cfg.users; - }; + services.enthalpy.services = mapAttrs' ( + name: _value: + nameValuePair "user@${toString config.users.users.${name}.uid}" { + overrideStrategy = "asDropin"; + } + ) cfg.users; + } + + # https://philipdeljanov.com/posts/2019/05/31/dns-leaks-with-network-namespaces + # https://flokli.de/posts/2022-11-18-nsncd + (mkIf (cfg.services != { }) { + environment.etc."netns/enthalpy/resolv.conf".text = mkDefault '' + nameserver 2606:4700:4700::1111 + ''; + + environment.etc."netns/enthalpy/nsswitch.conf".text = '' + passwd: ${concatStringsSep " " config.system.nssDatabases.passwd} + group: ${concatStringsSep " " config.system.nssDatabases.group} + shadow: ${concatStringsSep " " config.system.nssDatabases.shadow} + sudoers: ${concatStringsSep " " config.system.nssDatabases.sudoers} + + hosts: ${concatStringsSep " " (remove "resolve [!UNAVAIL=return]" config.system.nssDatabases.hosts)} + networks: files + + ethers: files + services: ${concatStringsSep " " config.system.nssDatabases.services} + protocols: files + rpc: files + ''; + + systemd.services.enthalpy-nsncd = { + serviceConfig = { + NetworkNamespacePath = "/run/netns/${cfg.netns}"; + BindReadOnlyPaths = [ + "/etc/netns/${cfg.netns}/resolv.conf:/etc/resolv.conf:norbind" + "/etc/netns/${cfg.netns}/nsswitch.conf:/etc/nsswitch.conf:norbind" + ]; + BindPaths = [ + "/run/enthalpy/nscd:/run/nscd:norbind" + ]; + ExecStart = "${pkgs.nsncd}/bin/nsncd"; + Type = "notify"; + DynamicUser = true; + RemoveIPC = true; + NoNewPrivileges = true; + RestrictSUIDSGID = true; + ProtectSystem = "strict"; + ProtectHome = "read-only"; + ProtectKernelTunables = true; + ProtectControlGroups = true; + PrivateTmp = true; + RuntimeDirectory = "enthalpy/nscd"; + Restart = "always"; + SystemCallFilter = "~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io"; + MemoryDenyWriteExecute = "yes"; + }; + environment.LD_LIBRARY_PATH = config.system.nssModules.path; + after = [ + "enthalpy.service" + "network.target" + ]; + requires = [ "enthalpy.service" ]; + wantedBy = [ "multi-user.target" ]; + }; + }) + ]); } diff --git a/nixos/profiles/services/resolved/default.nix b/nixos/profiles/services/resolved/default.nix index 0891e07..4d74222 100644 --- a/nixos/profiles/services/resolved/default.nix +++ b/nixos/profiles/services/resolved/default.nix @@ -5,7 +5,6 @@ llmnr = "false"; extraConfig = '' MulticastDNS=off - DNSStubListener=no ''; }; }