Loading nixos/modules/services/networking/dhcpcd.nix +74 −30 Original line number Diff line number Diff line Loading @@ -69,7 +69,7 @@ let hostname # A list of options to request from the DHCP server. option domain_name_servers, domain_name, domain_search, host_name option domain_name_servers, domain_name, domain_search option classless_static_routes, ntp_servers, interface_mtu # A ServerID is required by RFC2131. Loading Loading @@ -112,6 +112,7 @@ let ${lib.optionalString (config.networking.enableIPv6 && cfg.IPv6rs == false) '' noipv6rs ''} ${lib.optionalString cfg.setHostname "option host_name"} ${cfg.extraConfig} ''; Loading @@ -137,7 +138,7 @@ in type = lib.types.bool; default = false; description = '' Whenever to leave interfaces configured on dhcpcd daemon Whether to leave interfaces configured on dhcpcd daemon shutdown. Set to true if you have your root or store mounted over the network or this machine accepts SSH connections through DHCP interfaces and clients should be notified when Loading @@ -145,6 +146,22 @@ in ''; }; networking.dhcpcd.setHostname = lib.mkOption { type = lib.types.bool; default = true; description = '' Whether to set the machine hostname based on the information received from the DHCP server. ::: {.note} The hostname will be changed only if the current one is the empty string, `localhost` or `nixos`. Polkit ([](#opt-security.polkit.enable)) is also required. ::: ''; }; networking.dhcpcd.denyInterfaces = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; Loading Loading @@ -185,6 +202,15 @@ in ''; }; networking.dhcpcd.allowSetuid = lib.mkOption { type = lib.types.bool; default = false; description = '' Whether to relax the security sandbox to allow running setuid binaries (e.g. `sudo`) in the dhcpcd hooks. ''; }; networking.dhcpcd.runHook = lib.mkOption { type = lib.types.lines; default = ""; Loading @@ -196,7 +222,7 @@ in ::: {.note} To use sudo or similar tools in your script you may have to set: systemd.services.dhcpcd.serviceConfig.NoNewPrivileges = false; networking.dhcpcd.allowSetuid = true; In addition, as most of the filesystem is inaccessible to dhcpcd by default, you may want to define some exceptions, e.g. Loading Loading @@ -263,11 +289,16 @@ in # dhcpcd. So do a "systemctl restart" instead. stopIfChanged = false; path = [ path = [ dhcpcd pkgs.nettools config.networking.resolvconf.package ]; ] ++ lib.optional cfg.setHostname ( pkgs.writeShellScriptBin "hostname" '' ${lib.getExe' pkgs.systemd "hostnamectl"} set-hostname --transient $1 '' ); unitConfig.ConditionCapability = "CAP_NET_ADMIN"; Loading Loading @@ -299,7 +330,7 @@ in "CAP_NET_RAW" "CAP_NET_BIND_SERVICE" ]; CapabilityBoundingSet = [ CapabilityBoundingSet = lib.optionals (!cfg.allowSetuid) [ "CAP_NET_ADMIN" "CAP_NET_RAW" "CAP_NET_BIND_SERVICE" Loading @@ -313,7 +344,7 @@ in DeviceAllow = ""; LockPersonality = true; MemoryDenyWriteExecute = true; NoNewPrivileges = lib.mkDefault true; # may be disabled for sudo in runHook NoNewPrivileges = lib.mkDefault (!cfg.allowSetuid); # may be disabled for sudo in runHook PrivateDevices = true; PrivateMounts = true; PrivateTmp = true; Loading @@ -338,12 +369,15 @@ in RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; SystemCallFilter = [ SystemCallFilter = [ "@system-service" "~@aio" "~@keyring" "~@memlock" "~@mount" ] ++ lib.optionals (!cfg.allowSetuid) [ "~@privileged" "~@resources" ]; Loading Loading @@ -371,17 +405,27 @@ in /run/current-system/systemd/bin/systemctl reload dhcpcd.service ''; security.polkit.extraConfig = lib.mkIf config.services.resolved.enable '' security.polkit.extraConfig = lib.mkMerge [ (lib.mkIf config.services.resolved.enable '' polkit.addRule(function(action, subject) { if (action.id == 'org.freedesktop.resolve1.revert' || action.id == 'org.freedesktop.resolve1.set-dns-servers' || action.id == 'org.freedesktop.resolve1.set-domains') { if (subject.user == '${config.systemd.services.dhcpcd.serviceConfig.User}') { if (subject.user == 'dhcpcd') { return polkit.Result.YES; } } }); ''; '') (lib.mkIf cfg.setHostname '' polkit.addRule(function(action, subject) { if (action.id == 'org.freedesktop.hostname1.set-hostname' && subject.user == 'dhcpcd') { return polkit.Result.YES; } }); '') ]; }; Loading nixos/tests/networking/networkd-and-scripted.nix +23 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,29 @@ let router.wait_until_succeeds("ping -c 1 fd00:1234:5678:2::2") ''; }; dhcpHostname = { name = "hostnameDHCP"; nodes.router = router; nodes.client = clientConfig { # use the name given by the DHCP server system.name = "client"; networking.hostName = lib.mkForce ""; security.polkit.enable = true; virtualisation.interfaces.enp1s0.vlan = 1; networking.interfaces.enp1s0.useDHCP = true; }; testScript = '' router.start() router.systemctl("start network-online.target") router.wait_for_unit("network-online.target") client.start() client.wait_for_unit("network.target") with subtest("Wait until we have received the hostname"): client.wait_until_succeeds("hostname | grep -q 'client1'") ''; }; dhcpOneIf = { name = "OneInterfaceDHCP"; nodes.router = router; Loading pkgs/by-name/dh/dhcpcd/package.nix +7 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ stdenv.mkDerivation rec { "--localstatedir=/var" "--disable-privsep" "--dbdir=/var/lib/dhcpcd" "--with-default-hostname=nixos" (lib.enableFeature enablePrivSep "privsep") ] ++ lib.optional enablePrivSep "--privsepuser=dhcpcd"; Loading @@ -62,7 +63,12 @@ stdenv.mkDerivation rec { ) "[ -e ${placeholder "out"}/lib/dhcpcd/dev/udev.so ]"; passthru.tests = { inherit (nixosTests.networking.scripted) macvlan dhcpSimple dhcpOneIf; inherit (nixosTests.networking.scripted) macvlan dhcpSimple dhcpHostname dhcpOneIf ; }; meta = with lib; { Loading Loading
nixos/modules/services/networking/dhcpcd.nix +74 −30 Original line number Diff line number Diff line Loading @@ -69,7 +69,7 @@ let hostname # A list of options to request from the DHCP server. option domain_name_servers, domain_name, domain_search, host_name option domain_name_servers, domain_name, domain_search option classless_static_routes, ntp_servers, interface_mtu # A ServerID is required by RFC2131. Loading Loading @@ -112,6 +112,7 @@ let ${lib.optionalString (config.networking.enableIPv6 && cfg.IPv6rs == false) '' noipv6rs ''} ${lib.optionalString cfg.setHostname "option host_name"} ${cfg.extraConfig} ''; Loading @@ -137,7 +138,7 @@ in type = lib.types.bool; default = false; description = '' Whenever to leave interfaces configured on dhcpcd daemon Whether to leave interfaces configured on dhcpcd daemon shutdown. Set to true if you have your root or store mounted over the network or this machine accepts SSH connections through DHCP interfaces and clients should be notified when Loading @@ -145,6 +146,22 @@ in ''; }; networking.dhcpcd.setHostname = lib.mkOption { type = lib.types.bool; default = true; description = '' Whether to set the machine hostname based on the information received from the DHCP server. ::: {.note} The hostname will be changed only if the current one is the empty string, `localhost` or `nixos`. Polkit ([](#opt-security.polkit.enable)) is also required. ::: ''; }; networking.dhcpcd.denyInterfaces = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; Loading Loading @@ -185,6 +202,15 @@ in ''; }; networking.dhcpcd.allowSetuid = lib.mkOption { type = lib.types.bool; default = false; description = '' Whether to relax the security sandbox to allow running setuid binaries (e.g. `sudo`) in the dhcpcd hooks. ''; }; networking.dhcpcd.runHook = lib.mkOption { type = lib.types.lines; default = ""; Loading @@ -196,7 +222,7 @@ in ::: {.note} To use sudo or similar tools in your script you may have to set: systemd.services.dhcpcd.serviceConfig.NoNewPrivileges = false; networking.dhcpcd.allowSetuid = true; In addition, as most of the filesystem is inaccessible to dhcpcd by default, you may want to define some exceptions, e.g. Loading Loading @@ -263,11 +289,16 @@ in # dhcpcd. So do a "systemctl restart" instead. stopIfChanged = false; path = [ path = [ dhcpcd pkgs.nettools config.networking.resolvconf.package ]; ] ++ lib.optional cfg.setHostname ( pkgs.writeShellScriptBin "hostname" '' ${lib.getExe' pkgs.systemd "hostnamectl"} set-hostname --transient $1 '' ); unitConfig.ConditionCapability = "CAP_NET_ADMIN"; Loading Loading @@ -299,7 +330,7 @@ in "CAP_NET_RAW" "CAP_NET_BIND_SERVICE" ]; CapabilityBoundingSet = [ CapabilityBoundingSet = lib.optionals (!cfg.allowSetuid) [ "CAP_NET_ADMIN" "CAP_NET_RAW" "CAP_NET_BIND_SERVICE" Loading @@ -313,7 +344,7 @@ in DeviceAllow = ""; LockPersonality = true; MemoryDenyWriteExecute = true; NoNewPrivileges = lib.mkDefault true; # may be disabled for sudo in runHook NoNewPrivileges = lib.mkDefault (!cfg.allowSetuid); # may be disabled for sudo in runHook PrivateDevices = true; PrivateMounts = true; PrivateTmp = true; Loading @@ -338,12 +369,15 @@ in RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; SystemCallFilter = [ SystemCallFilter = [ "@system-service" "~@aio" "~@keyring" "~@memlock" "~@mount" ] ++ lib.optionals (!cfg.allowSetuid) [ "~@privileged" "~@resources" ]; Loading Loading @@ -371,17 +405,27 @@ in /run/current-system/systemd/bin/systemctl reload dhcpcd.service ''; security.polkit.extraConfig = lib.mkIf config.services.resolved.enable '' security.polkit.extraConfig = lib.mkMerge [ (lib.mkIf config.services.resolved.enable '' polkit.addRule(function(action, subject) { if (action.id == 'org.freedesktop.resolve1.revert' || action.id == 'org.freedesktop.resolve1.set-dns-servers' || action.id == 'org.freedesktop.resolve1.set-domains') { if (subject.user == '${config.systemd.services.dhcpcd.serviceConfig.User}') { if (subject.user == 'dhcpcd') { return polkit.Result.YES; } } }); ''; '') (lib.mkIf cfg.setHostname '' polkit.addRule(function(action, subject) { if (action.id == 'org.freedesktop.hostname1.set-hostname' && subject.user == 'dhcpcd') { return polkit.Result.YES; } }); '') ]; }; Loading
nixos/tests/networking/networkd-and-scripted.nix +23 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,29 @@ let router.wait_until_succeeds("ping -c 1 fd00:1234:5678:2::2") ''; }; dhcpHostname = { name = "hostnameDHCP"; nodes.router = router; nodes.client = clientConfig { # use the name given by the DHCP server system.name = "client"; networking.hostName = lib.mkForce ""; security.polkit.enable = true; virtualisation.interfaces.enp1s0.vlan = 1; networking.interfaces.enp1s0.useDHCP = true; }; testScript = '' router.start() router.systemctl("start network-online.target") router.wait_for_unit("network-online.target") client.start() client.wait_for_unit("network.target") with subtest("Wait until we have received the hostname"): client.wait_until_succeeds("hostname | grep -q 'client1'") ''; }; dhcpOneIf = { name = "OneInterfaceDHCP"; nodes.router = router; Loading
pkgs/by-name/dh/dhcpcd/package.nix +7 −1 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ stdenv.mkDerivation rec { "--localstatedir=/var" "--disable-privsep" "--dbdir=/var/lib/dhcpcd" "--with-default-hostname=nixos" (lib.enableFeature enablePrivSep "privsep") ] ++ lib.optional enablePrivSep "--privsepuser=dhcpcd"; Loading @@ -62,7 +63,12 @@ stdenv.mkDerivation rec { ) "[ -e ${placeholder "out"}/lib/dhcpcd/dev/udev.so ]"; passthru.tests = { inherit (nixosTests.networking.scripted) macvlan dhcpSimple dhcpOneIf; inherit (nixosTests.networking.scripted) macvlan dhcpSimple dhcpHostname dhcpOneIf ; }; meta = with lib; { Loading