From cb10fe8aaf430862537f0ae807146995fc05c946 Mon Sep 17 00:00:00 2001 From: Eduard Bachmakov Date: Fri, 9 Aug 2024 22:17:11 +0200 Subject: [PATCH] treewide: Remove ineffective capability grants. Systemd units with `PrivateUsers` set get their capabilities within the user namespace only [1]. As a result they do cannot bind to privileged ports even though they *appear* like they should be able to. The units in this commit [2] set `PrivateUsers` unconditionally so binding to privileged ports is currently impossible. Granting them CAP_NET_BIND_SERVICE is useless and misleading any reader of those modules. Technically, this commit also hardens these modules ever so slightly. (There are corner cases where this could make sense (e.g. across units, using `JoinsNamspaceOf`) but this is arcane enough to not to be present in nixpkgs.) [1]: systemd.exec(5): PrivateUsers [2]: found using `rg -e 'PrivateUsers.?=\s+[^f][^a]' -l | xargs rg -e '\bCAP_' -l` --- nixos/modules/services/misc/mollysocket.nix | 8 ++------ nixos/modules/services/misc/paperless.nix | 3 --- nixos/modules/services/misc/tandoor-recipes.nix | 3 --- nixos/modules/services/misc/transfer-sh.nix | 1 - nixos/modules/services/misc/wastebin.nix | 1 - nixos/modules/services/monitoring/prometheus/default.nix | 2 -- nixos/modules/services/web-apps/dex.nix | 2 -- nixos/modules/services/web-apps/freshrss.nix | 1 - nixos/modules/services/web-apps/microbin.nix | 1 - nixos/modules/services/web-apps/photoprism.nix | 4 ---- nixos/modules/services/web-apps/powerdns-admin.nix | 2 -- nixos/modules/services/web-apps/shiori.nix | 1 - 12 files changed, 2 insertions(+), 27 deletions(-) diff --git a/nixos/modules/services/misc/mollysocket.nix b/nixos/modules/services/misc/mollysocket.nix index f40caa4a782e..460e8aa05266 100644 --- a/nixos/modules/services/misc/mollysocket.nix +++ b/nixos/modules/services/misc/mollysocket.nix @@ -1,7 +1,7 @@ { config, lib, pkgs, ... }: let - inherit (lib) getExe mkIf mkOption mkEnableOption optionals types; + inherit (lib) getExe mkIf mkOption mkEnableOption types; cfg = config.services.mollysocket; configuration = format.generate "mollysocket.conf" cfg.settings; @@ -85,9 +85,7 @@ in { after = [ "network-online.target" ]; wants = [ "network-online.target" ]; environment.RUST_LOG = cfg.logLevel; - serviceConfig = let - capabilities = [ "" ] ++ optionals (cfg.settings.port < 1024) [ "CAP_NET_BIND_SERVICE" ]; - in { + serviceConfig = { EnvironmentFile = cfg.environmentFile; ExecStart = "${getExe package} server"; KillSignal = "SIGINT"; @@ -97,8 +95,6 @@ in { WorkingDirectory = "/var/lib/mollysocket"; # hardening - AmbientCapabilities = capabilities; - CapabilityBoundingSet = capabilities; DevicePolicy = "closed"; DynamicUser = true; LockPersonality = true; diff --git a/nixos/modules/services/misc/paperless.nix b/nixos/modules/services/misc/paperless.nix index 6d6a49c10bdd..cf6a6609333a 100644 --- a/nixos/modules/services/misc/paperless.nix +++ b/nixos/modules/services/misc/paperless.nix @@ -364,9 +364,6 @@ in SystemCallFilter = defaultServiceConfig.SystemCallFilter ++ [ "@setuid mbind" ]; # Needs to serve web page PrivateNetwork = false; - } // lib.optionalAttrs (cfg.port < 1024) { - AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; - CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; }; environment = env // { PYTHONPATH = "${cfg.package.python.pkgs.makePythonPath cfg.package.propagatedBuildInputs}:${cfg.package}/lib/paperless-ngx/src"; diff --git a/nixos/modules/services/misc/tandoor-recipes.nix b/nixos/modules/services/misc/tandoor-recipes.nix index 1c903d280378..f8a85e0ac221 100644 --- a/nixos/modules/services/misc/tandoor-recipes.nix +++ b/nixos/modules/services/misc/tandoor-recipes.nix @@ -119,9 +119,6 @@ in # gunicorn needs setuid SystemCallFilter = [ "@system-service" "~@privileged" "@resources" "@setuid" "@keyring" ]; UMask = "0066"; - } // lib.optionalAttrs (cfg.port < 1024) { - AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; - CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; }; wantedBy = [ "multi-user.target" ]; diff --git a/nixos/modules/services/misc/transfer-sh.nix b/nixos/modules/services/misc/transfer-sh.nix index 150af2337e14..b0d1b724d727 100644 --- a/nixos/modules/services/misc/transfer-sh.nix +++ b/nixos/modules/services/misc/transfer-sh.nix @@ -69,7 +69,6 @@ in wantedBy = [ "multi-user.target" ]; environment = mapAttrs (_: v: if isBool v then boolToString v else toString v) cfg.settings; serviceConfig = { - CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; DevicePolicy = "closed"; DynamicUser = true; ExecStart = "${getExe cfg.package} --provider ${cfg.provider}"; diff --git a/nixos/modules/services/misc/wastebin.nix b/nixos/modules/services/misc/wastebin.nix index f24bf94fa52b..51dfe625c010 100644 --- a/nixos/modules/services/misc/wastebin.nix +++ b/nixos/modules/services/misc/wastebin.nix @@ -126,7 +126,6 @@ in wantedBy = [ "multi-user.target" ]; environment = mapAttrs (_: v: if isBool v then boolToString v else toString v) cfg.settings; serviceConfig = { - CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; DevicePolicy = "closed"; DynamicUser = true; ExecStart = "${getExe cfg.package}"; diff --git a/nixos/modules/services/monitoring/prometheus/default.nix b/nixos/modules/services/monitoring/prometheus/default.nix index 4de80acfa9a8..1d035b53673d 100644 --- a/nixos/modules/services/monitoring/prometheus/default.nix +++ b/nixos/modules/services/monitoring/prometheus/default.nix @@ -1811,8 +1811,6 @@ in StateDirectory = cfg.stateDir; StateDirectoryMode = "0700"; # Hardening - AmbientCapabilities = lib.mkIf (cfg.port < 1024) [ "CAP_NET_BIND_SERVICE" ]; - CapabilityBoundingSet = if (cfg.port < 1024) then [ "CAP_NET_BIND_SERVICE" ] else [ "" ]; DeviceAllow = [ "/dev/null rw" ]; DevicePolicy = "strict"; LockPersonality = true; diff --git a/nixos/modules/services/web-apps/dex.nix b/nixos/modules/services/web-apps/dex.nix index 7fbbd8a0c284..45e16603373d 100644 --- a/nixos/modules/services/web-apps/dex.nix +++ b/nixos/modules/services/web-apps/dex.nix @@ -80,7 +80,6 @@ in ]; RuntimeDirectory = "dex"; - AmbientCapabilities = "CAP_NET_BIND_SERVICE"; BindReadOnlyPaths = [ "/nix/store" "-/etc/dex" @@ -91,7 +90,6 @@ in "-/etc/ssl/certs/ca-certificates.crt" ]; BindPaths = optional (cfg.settings.storage.type == "postgres") "/var/run/postgresql"; - CapabilityBoundingSet = "CAP_NET_BIND_SERVICE"; # ProtectClock= adds DeviceAllow=char-rtc r DeviceAllow = ""; DynamicUser = true; diff --git a/nixos/modules/services/web-apps/freshrss.nix b/nixos/modules/services/web-apps/freshrss.nix index 53366e2c891e..18f403752b56 100644 --- a/nixos/modules/services/web-apps/freshrss.nix +++ b/nixos/modules/services/web-apps/freshrss.nix @@ -164,7 +164,6 @@ in let defaultServiceConfig = { ReadWritePaths = "${cfg.dataDir}"; - CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; DeviceAllow = ""; LockPersonality = true; NoNewPrivileges = true; diff --git a/nixos/modules/services/web-apps/microbin.nix b/nixos/modules/services/web-apps/microbin.nix index 0ebe644a2595..e404609a4c22 100644 --- a/nixos/modules/services/web-apps/microbin.nix +++ b/nixos/modules/services/web-apps/microbin.nix @@ -61,7 +61,6 @@ in wantedBy = [ "multi-user.target" ]; environment = lib.mapAttrs (_: v: if lib.isBool v then lib.boolToString v else toString v) cfg.settings; serviceConfig = { - CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; DevicePolicy = "closed"; DynamicUser = true; EnvironmentFile = lib.optional (cfg.passwordFile != null) cfg.passwordFile; diff --git a/nixos/modules/services/web-apps/photoprism.nix b/nixos/modules/services/web-apps/photoprism.nix index ec4126b420cd..f880b3539e00 100644 --- a/nixos/modules/services/web-apps/photoprism.nix +++ b/nixos/modules/services/web-apps/photoprism.nix @@ -109,7 +109,6 @@ in LoadCredential = lib.optionalString (cfg.passwordFile != null) "PHOTOPRISM_ADMIN_PASSWORD:${cfg.passwordFile}"; - CapabilityBoundingSet = ""; LockPersonality = true; PrivateDevices = true; PrivateUsers = true; @@ -126,9 +125,6 @@ in SystemCallArchitectures = "native"; SystemCallFilter = [ "@system-service" "~@setuid @keyring" ]; UMask = "0066"; - } // lib.optionalAttrs (cfg.port < 1024) { - AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; - CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; }; wantedBy = [ "multi-user.target" ]; diff --git a/nixos/modules/services/web-apps/powerdns-admin.nix b/nixos/modules/services/web-apps/powerdns-admin.nix index d64c468a9cb5..d1886129515e 100644 --- a/nixos/modules/services/web-apps/powerdns-admin.nix +++ b/nixos/modules/services/web-apps/powerdns-admin.nix @@ -87,7 +87,6 @@ in User = "powerdnsadmin"; Group = "powerdnsadmin"; - AmbientCapabilities = "CAP_NET_BIND_SERVICE"; BindReadOnlyPaths = [ "/nix/store" "-/etc/resolv.conf" @@ -97,7 +96,6 @@ in ] ++ (optional (cfg.secretKeyFile != null) cfg.secretKeyFile) ++ (optional (cfg.saltFile != null) cfg.saltFile); - CapabilityBoundingSet = "CAP_NET_BIND_SERVICE"; # ProtectClock= adds DeviceAllow=char-rtc r DeviceAllow = ""; # Implies ProtectSystem=strict, which re-mounts all paths diff --git a/nixos/modules/services/web-apps/shiori.nix b/nixos/modules/services/web-apps/shiori.nix index df3eeaef1618..bec5ab4083bb 100644 --- a/nixos/modules/services/web-apps/shiori.nix +++ b/nixos/modules/services/web-apps/shiori.nix @@ -90,7 +90,6 @@ in { "/var/run/mysqld"; CapabilityBoundingSet = ""; - AmbientCapabilities = "CAP_NET_BIND_SERVICE"; DeviceAllow = "";