mirror of
https://github.com/SebastianWendel/nixpkgs.git
synced 2024-09-20 20:39:04 +02:00
Merge pull request #155895 from rnhmjoj/pr-dhcpd-hard
nixos/dhcpd: switch to DynamicUser [v2]
This commit is contained in:
commit
09e2956012
|
@ -235,6 +235,23 @@
|
|||
removed due to it being an outdated version.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The DHCP server (<literal>services.dhcpd4</literal>,
|
||||
<literal>services.dhcpd6</literal>) has been hardened. The
|
||||
service is now using the systemd’s
|
||||
<literal>DynamicUser</literal> mechanism to run as an
|
||||
unprivileged dynamically-allocated user with limited
|
||||
capabilities. The dhcpd state files are now always stored in
|
||||
<literal>/var/lib/dhcpd{4,6}</literal> and the
|
||||
<literal>services.dhcpd4.stateDir</literal> and
|
||||
<literal>service.dhcpd6.stateDir</literal> options have been
|
||||
removed. If you were depending on root privileges or
|
||||
set{uid,gid,cap} binaries in dhcpd shell hooks, you may give
|
||||
dhcpd more capabilities with e.g.
|
||||
<literal>systemd.services.dhcpd6.serviceConfig.AmbientCapabilities</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>mailpile</literal> email webclient
|
||||
|
|
|
@ -81,6 +81,11 @@ In addition to numerous new and upgraded packages, this release has the followin
|
|||
|
||||
- `services.kubernetes.addons.dashboard` was removed due to it being an outdated version.
|
||||
|
||||
- The DHCP server (`services.dhcpd4`, `services.dhcpd6`) has been hardened.
|
||||
The service is now using the systemd's `DynamicUser` mechanism to run as an unprivileged dynamically-allocated user with limited capabilities.
|
||||
The dhcpd state files are now always stored in `/var/lib/dhcpd{4,6}` and the `services.dhcpd4.stateDir` and `service.dhcpd6.stateDir` options have been removed.
|
||||
If you were depending on root privileges or set{uid,gid,cap} binaries in dhcpd shell hooks, you may give dhcpd more capabilities with e.g. `systemd.services.dhcpd6.serviceConfig.AmbientCapabilities`.
|
||||
|
||||
- The `mailpile` email webclient (`services.mailpile`) has been removed due to its reliance on python2.
|
||||
|
||||
- The MoinMoin wiki engine (`services.moinmoin`) has been removed, because Python 2 is being retired from nixpkgs.
|
||||
|
|
|
@ -28,38 +28,45 @@ let
|
|||
}
|
||||
'';
|
||||
|
||||
dhcpdService = postfix: cfg: optionalAttrs cfg.enable {
|
||||
"dhcpd${postfix}" = {
|
||||
description = "DHCPv${postfix} server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
dhcpdService = postfix: cfg:
|
||||
let
|
||||
configFile =
|
||||
if cfg.configFile != null
|
||||
then cfg.configFile
|
||||
else writeConfig cfg;
|
||||
leaseFile = "/var/lib/dhcpd${postfix}/dhcpd.leases";
|
||||
args = [
|
||||
"@${pkgs.dhcp}/sbin/dhcpd" "dhcpd${postfix}" "-${postfix}"
|
||||
"-pf" "/run/dhcpd${postfix}/dhcpd.pid"
|
||||
"-cf" configFile
|
||||
"-lf" leaseFile
|
||||
] ++ cfg.extraFlags
|
||||
++ cfg.interfaces;
|
||||
in
|
||||
optionalAttrs cfg.enable {
|
||||
"dhcpd${postfix}" = {
|
||||
description = "DHCPv${postfix} server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
preStart = ''
|
||||
mkdir -m 755 -p ${cfg.stateDir}
|
||||
chown dhcpd:nogroup ${cfg.stateDir}
|
||||
touch ${cfg.stateDir}/dhcpd.leases
|
||||
'';
|
||||
|
||||
serviceConfig =
|
||||
let
|
||||
configFile = if cfg.configFile != null then cfg.configFile else writeConfig cfg;
|
||||
args = [ "@${pkgs.dhcp}/sbin/dhcpd" "dhcpd${postfix}" "-${postfix}"
|
||||
"-pf" "/run/dhcpd${postfix}/dhcpd.pid"
|
||||
"-cf" "${configFile}"
|
||||
"-lf" "${cfg.stateDir}/dhcpd.leases"
|
||||
"-user" "dhcpd" "-group" "nogroup"
|
||||
] ++ cfg.extraFlags
|
||||
++ cfg.interfaces;
|
||||
|
||||
in {
|
||||
ExecStart = concatMapStringsSep " " escapeShellArg args;
|
||||
Type = "forking";
|
||||
Restart = "always";
|
||||
RuntimeDirectory = [ "dhcpd${postfix}" ];
|
||||
PIDFile = "/run/dhcpd${postfix}/dhcpd.pid";
|
||||
preStart = "touch ${leaseFile}";
|
||||
serviceConfig = {
|
||||
ExecStart = concatMapStringsSep " " escapeShellArg args;
|
||||
Type = "forking";
|
||||
Restart = "always";
|
||||
DynamicUser = true;
|
||||
User = "dhcpd";
|
||||
Group = "dhcpd";
|
||||
AmbientCapabilities = [
|
||||
"CAP_NET_RAW" # to send ICMP messages
|
||||
"CAP_NET_BIND_SERVICE" # to bind on DHCP port (67)
|
||||
];
|
||||
StateDirectory = "dhcpd${postfix}";
|
||||
RuntimeDirectory = "dhcpd${postfix}";
|
||||
PIDFile = "/run/dhcpd${postfix}/dhcpd.pid";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
machineOpts = { ... }: {
|
||||
|
||||
|
@ -102,15 +109,6 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
stateDir = mkOption {
|
||||
type = types.path;
|
||||
# We use /var/lib/dhcp for DHCPv4 to save backwards compatibility.
|
||||
default = "/var/lib/dhcp${if postfix == "4" then "" else postfix}";
|
||||
description = ''
|
||||
State directory for the DHCP server.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
default = "";
|
||||
|
@ -194,7 +192,13 @@ in
|
|||
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "services" "dhcpd" ] [ "services" "dhcpd4" ])
|
||||
];
|
||||
] ++ flip map [ "4" "6" ] (postfix:
|
||||
mkRemovedOptionModule [ "services" "dhcpd${postfix}" "stateDir" ] ''
|
||||
The DHCP server state directory is now managed with the systemd's DynamicUser mechanism.
|
||||
This means the directory is named after the service (dhcpd${postfix}), created under
|
||||
/var/lib/private/ and symlinked to /var/lib/.
|
||||
''
|
||||
);
|
||||
|
||||
###### interface
|
||||
|
||||
|
@ -210,15 +214,6 @@ in
|
|||
|
||||
config = mkIf (cfg4.enable || cfg6.enable) {
|
||||
|
||||
users = {
|
||||
users.dhcpd = {
|
||||
isSystemUser = true;
|
||||
group = "dhcpd";
|
||||
description = "DHCP daemon user";
|
||||
};
|
||||
groups.dhcpd = {};
|
||||
};
|
||||
|
||||
systemd.services = dhcpdService "4" cfg4 // dhcpdService "6" cfg6;
|
||||
|
||||
};
|
||||
|
|
|
@ -36,19 +36,10 @@ import ./make-test-python.nix ({pkgs, ...}: {
|
|||
};
|
||||
|
||||
# Since we want to program the routes that we delegate to the "customer"
|
||||
# into our routing table we must have a way to gain the required privs.
|
||||
# This security wrapper will do in our test setup.
|
||||
#
|
||||
# DO NOT COPY THIS TO PRODUCTION AS IS. Think about it at least twice.
|
||||
# Everyone on the "isp" machine will be able to add routes to the kernel.
|
||||
security.wrappers.add-dhcpd-lease = {
|
||||
owner = "root";
|
||||
group = "root";
|
||||
source = pkgs.writeShellScript "add-dhcpd-lease" ''
|
||||
exec ${pkgs.iproute2}/bin/ip -6 route replace "$1" via "$2"
|
||||
'';
|
||||
capabilities = "cap_net_admin+ep";
|
||||
};
|
||||
# into our routing table we must give dhcpd the required privs.
|
||||
systemd.services.dhcpd6.serviceConfig.AmbientCapabilities =
|
||||
[ "CAP_NET_ADMIN" ];
|
||||
|
||||
services = {
|
||||
# Configure the DHCPv6 server
|
||||
#
|
||||
|
@ -80,7 +71,7 @@ import ./make-test-python.nix ({pkgs, ...}: {
|
|||
set Prefix = pick-first-value(binary-to-ascii(16, 16, ":", suffix(option dhcp6.ia-pd, 16)), "n/a");
|
||||
set PrefixLength = pick-first-value(binary-to-ascii(10, 8, ":", substring(suffix(option dhcp6.ia-pd, 17), 0, 1)), "n/a");
|
||||
log(concat(IP, " ", Prefix, " ", PrefixLength));
|
||||
execute("/run/wrappers/bin/add-dhcpd-lease", concat(Prefix,"/",PrefixLength), IP);
|
||||
execute("${pkgs.iproute2}/bin/ip", "-6", "route", "replace", concat(Prefix,"/",PrefixLength), "via", IP);
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue