Unverified Commit 25310642 authored by Maximilian Bosch's avatar Maximilian Bosch Committed by GitHub
Browse files

Merge: nixos/postgresql: allow customisations of SystemCallFilter (#386345)

parents a3ab644a 6e87867e
Loading
Loading
Loading
Loading
+120 −10
Original line number Diff line number Diff line
@@ -14,8 +14,11 @@ let
    const
    elem
    escapeShellArgs
    filter
    filterAttrs
    getAttr
    getName
    hasPrefix
    isString
    literalExpression
    mapAttrs
@@ -31,6 +34,8 @@ let
    mkRemovedOptionModule
    mkRenamedOptionModule
    optionalString
    pipe
    sortProperties
    types
    versionAtLeast
    warn
@@ -124,6 +129,100 @@ in
        '';
      };

      systemCallFilter = mkOption {
        type = types.attrsOf (
          types.coercedTo types.bool (enable: { inherit enable; }) (
            types.submodule (
              { name, ... }:
              {
                options = {
                  enable = mkEnableOption "${name} in postgresql's syscall filter";
                  priority = mkOption {
                    default =
                      if hasPrefix "@" name then
                        500
                      else if hasPrefix "~@" name then
                        1000
                      else
                        1500;
                    defaultText = literalExpression ''
                      if hasPrefix "@" name then 500 else if hasPrefix "~@" name then 1000 else 1500
                    '';
                    type = types.int;
                    description = ''
                      Set the priority of the system call filter setting. Later declarations
                      override earlier ones, e.g.

                      ```ini
                      [Service]
                      SystemCallFilter=~read write
                      SystemCallFilter=write
                      ```

                      results in a service where _only_ `read` is not allowed.

                      The ordering in the unit file is controlled by this option: the higher
                      the number, the later it will be added to the filterset.

                      By default, depending on the prefix a priority is assigned: usually, call-groups
                      (starting with `@`) are used to allow/deny a larger set of syscalls and later
                      on single syscalls are configured for exceptions. Hence, syscall groups
                      and negative groups are placed before individual syscalls by default.
                    '';
                  };
                };
              }
            )
          )
        );
        defaultText = literalExpression ''
          {
            "@system-service" = true;
            "~@privileged" = true;
            "~@resources" = true;
          }
        '';
        description = ''
          Configures the syscall filter for `postgresql.service`. The keys are
          declarations for `SystemCallFilter` as described in {manpage}`systemd.exec(5)`.

          The value is a boolean: `true` adds the attribute name to the syscall filter-set,
          `false` doesn't. This is done to allow downstream configurations to turn off
          restrictions made here. E.g. with

          ```nix
          {
            services.postgresql.systemCallFilter."~@resources" = false;
          }
          ```

          it's possible to remove the restriction on `@resources` (keep in mind that
          `@system-service` implies `@resources`).

          As described in the section for [](#opt-services.postgresql.systemCallFilter._name_.priority),
          the ordering matters. Hence, it's also possible to specify customizations with

          ```nix
          {
            services.postgresql.systemCallFilter = {
              "foobar" = { enable = true; priority = 23; };
            };
          }
          ```

          [](#opt-services.postgresql.systemCallFilter._name_.enable) is the flag whether
          or not it will be added to the `SystemCallFilter` of `postgresql.service`.

          Settings with a higher priority are added after filter settings with a lower
          priority. Hence, syscall groups with a higher priority can discard declarations
          with a lower priority.

          By default, syscall groups (i.e. attribute names starting with `@`) are added
          _before_ negated groups (i.e. `~@` as prefix) _before_ syscall names
          and negations.
        '';
      };

      checkConfig = mkOption {
        type = types.bool;
        default = true;
@@ -583,6 +682,21 @@ in
      '')
    ];

    services.postgresql.systemCallFilter = mkMerge [
      (mapAttrs (const mkDefault) {
        "@system-service" = true;
        "~@privileged" = true;
        "~@resources" = true;
      })
      (mkIf (any extensionInstalled [ "plv8" ]) {
        "@pkey" = true;
      })
      (mkIf (any extensionInstalled [ "citus" ]) {
        "getpriority" = true;
        "setpriority" = true;
      })
    ];

    users.users.postgres = {
      name = "postgres";
      uid = config.ids.uids.postgres;
@@ -727,15 +841,11 @@ in
          RestrictRealtime = true;
          RestrictSUIDSGID = true;
          SystemCallArchitectures = "native";
          SystemCallFilter =
            [
              "@system-service"
              "~@privileged @resources"
            ]
            ++ lib.optionals (any extensionInstalled [ "plv8" ]) [ "@pkey" ]
            ++ lib.optionals (any extensionInstalled [ "citus" ]) [
              "getpriority"
              "setpriority"
          SystemCallFilter = pipe cfg.systemCallFilter [
            (mapAttrsToList (name: v: v // { inherit name; }))
            (filter (getAttr "enable"))
            sortProperties
            (map (getAttr "name"))
          ];
          UMask = if groupAccessAvailable then "0027" else "0077";
        }