summary refs log tree commit diff
diff options
context:
space:
mode:
authorRickard Nilsson <rickynils@gmail.com>2018-07-05 23:22:09 +0200
committerRickard Nilsson <rickynils@gmail.com>2018-07-07 17:15:35 +0200
commitd80292dbd24ab860f30fded9a4e6e21d213eb89f (patch)
tree78c07db40252f89710517af3001e1ed11491e1c9
parent499203e19934601b95a81f8c62aa418b2bbf16c4 (diff)
downloadnixpkgs-d80292dbd24ab860f30fded9a4e6e21d213eb89f.tar
nixpkgs-d80292dbd24ab860f30fded9a4e6e21d213eb89f.tar.gz
nixpkgs-d80292dbd24ab860f30fded9a4e6e21d213eb89f.tar.bz2
nixpkgs-d80292dbd24ab860f30fded9a4e6e21d213eb89f.tar.lz
nixpkgs-d80292dbd24ab860f30fded9a4e6e21d213eb89f.tar.xz
nixpkgs-d80292dbd24ab860f30fded9a4e6e21d213eb89f.tar.zst
nixpkgs-d80292dbd24ab860f30fded9a4e6e21d213eb89f.zip
nixos: Add option networking.networkmanager.dynamicHosts
This allows non-privileged users to configure local DNS
entries by editing hosts files read by NetworkManager's dnsmasq
instance.

Cherry-picked from e6c3d5a507909c4e0c0a5013040684cce89c35ce and
5a566004a2b12c3d91bf0acdb704f1b40770c28f.
-rw-r--r--nixos/modules/services/networking/networkmanager.nix87
1 files changed, 82 insertions, 5 deletions
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index cdc3a352590..b0bc1c83d6b 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -6,6 +6,9 @@ with lib;
 let
   cfg = config.networking.networkmanager;
 
+  dynamicHostsEnabled =
+    cfg.dynamicHosts.enable && cfg.dynamicHosts.hostsDirs != {};
+
   # /var/lib/misc is for dnsmasq.leases.
   stateDirs = "/var/lib/NetworkManager /var/lib/dhclient /var/lib/misc";
 
@@ -317,6 +320,52 @@ in {
           so you don't need to to that yourself.
         '';
       };
+
+      dynamicHosts = {
+        enable = mkOption {
+          type = types.bool;
+          default = false;
+          description = ''
+            Enabling this option requires the
+            <option>networking.networkmanager.dns</option> option to be
+            set to <literal>dnsmasq</literal>. If enabled, the directories
+            defined by the
+            <option>networking.networkmanager.dynamicHosts.hostsDirs</option>
+            option will be set up when the service starts. The dnsmasq instance
+            managed by NetworkManager will then watch those directories for
+            hosts files (see the <literal>--hostsdir</literal> option of
+            dnsmasq). This way a non-privileged user can add or override DNS
+            entries on the local system (depending on what hosts directories
+            that are configured)..
+          '';
+        };
+        hostsDirs = mkOption {
+          type = with types; attrsOf (submodule {
+            options = {
+              user = mkOption {
+                type = types.str;
+                default = "root";
+                description = ''
+                  The user that will own the hosts directory.
+                '';
+              };
+              group = mkOption {
+                type = types.str;
+                default = "root";
+                description = ''
+                  The group that will own the hosts directory.
+                '';
+              };
+            };
+          });
+          default = {};
+          description = ''
+            Defines a set of directories (relative to
+            <literal>/run/NetworkManager/hostdirs</literal>) that dnsmasq will
+            watch for hosts files.
+          '';
+        };
+      };
     };
   };
 
@@ -325,10 +374,17 @@ in {
 
   config = mkIf cfg.enable {
 
-    assertions = [{
-      assertion = config.networking.wireless.enable == false;
-      message = "You can not use networking.networkmanager with networking.wireless";
-    }];
+    assertions = [
+      { assertion = config.networking.wireless.enable == false;
+        message = "You can not use networking.networkmanager with networking.wireless";
+      }
+      { assertion = !dynamicHostsEnabled || (dynamicHostsEnabled && cfg.dns == "dnsmasq");
+        message = ''
+          To use networking.networkmanager.dynamicHosts you also need to set
+          networking.networkmanager.dns = "dnsmasq"
+        '';
+      }
+    ];
 
     environment.etc = with cfg.basePackages; [
       { source = configFile;
@@ -362,7 +418,13 @@ in {
       ++ lib.imap1 (i: s: {
         inherit (s) source;
         target = "NetworkManager/dispatcher.d/${dispatcherTypesSubdirMap.${s.type}}03userscript${lib.fixedWidthNumber 4 i}";
-      }) cfg.dispatcherScripts;
+      }) cfg.dispatcherScripts
+      ++ optional (dynamicHostsEnabled)
+           { target = "NetworkManager/dnsmasq.d/dyndns.conf";
+             text = concatMapStrings (n: ''
+               hostsdir=/run/NetworkManager/hostsdirs/${n}
+             '') (attrNames cfg.dynamicHosts.hostsDirs);
+           };
 
     environment.systemPackages = cfg.packages;
 
@@ -398,6 +460,21 @@ in {
       '';
     };
 
+    systemd.services.nm-setup-hostsdirs = mkIf dynamicHostsEnabled {
+      wantedBy = [ "network-manager.service" ];
+      before = [ "network-manager.service" ];
+      partOf = [ "network-manager.service" ];
+      script = concatStrings (mapAttrsToList (n: d: ''
+        mkdir -p "/run/NetworkManager/hostsdirs/${n}"
+        chown "${d.user}:${d.group}" "/run/NetworkManager/hostsdirs/${n}"
+        chmod 0775 "/run/NetworkManager/hostsdirs/${n}"
+      '') cfg.dynamicHosts.hostsDirs);
+      serviceConfig = {
+        Type = "oneshot";
+        RemainAfterExist = true;
+      };
+    };
+
     # Turn off NixOS' network management
     networking = {
       useDHCP = false;