Skip to content

Commit 2531064

Browse files
authored
Merge: nixos/postgresql: allow customisations of SystemCallFilter (#386345)
2 parents a3ab644 + 6e87867 commit 2531064

File tree

1 file changed

+120
-10
lines changed

1 file changed

+120
-10
lines changed

nixos/modules/services/databases/postgresql.nix

Lines changed: 120 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ let
1414
const
1515
elem
1616
escapeShellArgs
17+
filter
1718
filterAttrs
19+
getAttr
1820
getName
21+
hasPrefix
1922
isString
2023
literalExpression
2124
mapAttrs
@@ -31,6 +34,8 @@ let
3134
mkRemovedOptionModule
3235
mkRenamedOptionModule
3336
optionalString
37+
pipe
38+
sortProperties
3439
types
3540
versionAtLeast
3641
warn
@@ -124,6 +129,100 @@ in
124129
'';
125130
};
126131

132+
systemCallFilter = mkOption {
133+
type = types.attrsOf (
134+
types.coercedTo types.bool (enable: { inherit enable; }) (
135+
types.submodule (
136+
{ name, ... }:
137+
{
138+
options = {
139+
enable = mkEnableOption "${name} in postgresql's syscall filter";
140+
priority = mkOption {
141+
default =
142+
if hasPrefix "@" name then
143+
500
144+
else if hasPrefix "~@" name then
145+
1000
146+
else
147+
1500;
148+
defaultText = literalExpression ''
149+
if hasPrefix "@" name then 500 else if hasPrefix "~@" name then 1000 else 1500
150+
'';
151+
type = types.int;
152+
description = ''
153+
Set the priority of the system call filter setting. Later declarations
154+
override earlier ones, e.g.
155+
156+
```ini
157+
[Service]
158+
SystemCallFilter=~read write
159+
SystemCallFilter=write
160+
```
161+
162+
results in a service where _only_ `read` is not allowed.
163+
164+
The ordering in the unit file is controlled by this option: the higher
165+
the number, the later it will be added to the filterset.
166+
167+
By default, depending on the prefix a priority is assigned: usually, call-groups
168+
(starting with `@`) are used to allow/deny a larger set of syscalls and later
169+
on single syscalls are configured for exceptions. Hence, syscall groups
170+
and negative groups are placed before individual syscalls by default.
171+
'';
172+
};
173+
};
174+
}
175+
)
176+
)
177+
);
178+
defaultText = literalExpression ''
179+
{
180+
"@system-service" = true;
181+
"~@privileged" = true;
182+
"~@resources" = true;
183+
}
184+
'';
185+
description = ''
186+
Configures the syscall filter for `postgresql.service`. The keys are
187+
declarations for `SystemCallFilter` as described in {manpage}`systemd.exec(5)`.
188+
189+
The value is a boolean: `true` adds the attribute name to the syscall filter-set,
190+
`false` doesn't. This is done to allow downstream configurations to turn off
191+
restrictions made here. E.g. with
192+
193+
```nix
194+
{
195+
services.postgresql.systemCallFilter."~@resources" = false;
196+
}
197+
```
198+
199+
it's possible to remove the restriction on `@resources` (keep in mind that
200+
`@system-service` implies `@resources`).
201+
202+
As described in the section for [](#opt-services.postgresql.systemCallFilter._name_.priority),
203+
the ordering matters. Hence, it's also possible to specify customizations with
204+
205+
```nix
206+
{
207+
services.postgresql.systemCallFilter = {
208+
"foobar" = { enable = true; priority = 23; };
209+
};
210+
}
211+
```
212+
213+
[](#opt-services.postgresql.systemCallFilter._name_.enable) is the flag whether
214+
or not it will be added to the `SystemCallFilter` of `postgresql.service`.
215+
216+
Settings with a higher priority are added after filter settings with a lower
217+
priority. Hence, syscall groups with a higher priority can discard declarations
218+
with a lower priority.
219+
220+
By default, syscall groups (i.e. attribute names starting with `@`) are added
221+
_before_ negated groups (i.e. `~@` as prefix) _before_ syscall names
222+
and negations.
223+
'';
224+
};
225+
127226
checkConfig = mkOption {
128227
type = types.bool;
129228
default = true;
@@ -583,6 +682,21 @@ in
583682
'')
584683
];
585684

685+
services.postgresql.systemCallFilter = mkMerge [
686+
(mapAttrs (const mkDefault) {
687+
"@system-service" = true;
688+
"~@privileged" = true;
689+
"~@resources" = true;
690+
})
691+
(mkIf (any extensionInstalled [ "plv8" ]) {
692+
"@pkey" = true;
693+
})
694+
(mkIf (any extensionInstalled [ "citus" ]) {
695+
"getpriority" = true;
696+
"setpriority" = true;
697+
})
698+
];
699+
586700
users.users.postgres = {
587701
name = "postgres";
588702
uid = config.ids.uids.postgres;
@@ -727,16 +841,12 @@ in
727841
RestrictRealtime = true;
728842
RestrictSUIDSGID = true;
729843
SystemCallArchitectures = "native";
730-
SystemCallFilter =
731-
[
732-
"@system-service"
733-
"~@privileged @resources"
734-
]
735-
++ lib.optionals (any extensionInstalled [ "plv8" ]) [ "@pkey" ]
736-
++ lib.optionals (any extensionInstalled [ "citus" ]) [
737-
"getpriority"
738-
"setpriority"
739-
];
844+
SystemCallFilter = pipe cfg.systemCallFilter [
845+
(mapAttrsToList (name: v: v // { inherit name; }))
846+
(filter (getAttr "enable"))
847+
sortProperties
848+
(map (getAttr "name"))
849+
];
740850
UMask = if groupAccessAvailable then "0027" else "0077";
741851
}
742852
(mkIf (cfg.dataDir != "/var/lib/postgresql/${cfg.package.psqlSchema}") {

0 commit comments

Comments
 (0)