Skip to content

Commit 9b9ca77

Browse files
authored
nixos/logrotate: harden systemd unit (#339050)
2 parents 44d7484 + 5ccb0b4 commit 9b9ca77

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

nixos/doc/manual/release-notes/rl-2411.section.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@
199199

200200
- The `MSMTP_QUEUE` and `MSMTP_LOG` environment variables accepted by `msmtpq` have now been renamed to `MSMTPQ_Q` and `MSMTPQ_LOG` respectively.
201201

202+
- The logrotate service has received hardening and now requires enabling `allowNetworking`, if logrotate needs to access the network.
203+
202204
- The fcgiwrap module now allows multiple instances running as distinct users.
203205
The option `services.fgciwrap` now takes an attribute set of the
204206
configuration of each individual instance.

nixos/modules/services/logging/logrotate.nix

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ in
9797
defaultText = lib.literalExpression "cfg.settings != {}";
9898
};
9999

100+
allowNetworking = lib.mkEnableOption "network access for logrotate";
101+
100102
settings = lib.mkOption {
101103
default = { };
102104
description = ''
@@ -240,12 +242,55 @@ in
240242
config = lib.mkIf cfg.enable {
241243
systemd.services.logrotate = {
242244
description = "Logrotate Service";
245+
documentation = [
246+
"man:logrotate(8)"
247+
"man:logrotate(5)"
248+
];
243249
startAt = "hourly";
244250

245251
serviceConfig = {
246-
Restart = "no";
247-
User = "root";
248-
ExecStart = "${pkgs.logrotate}/sbin/logrotate ${utils.escapeSystemdExecArgs cfg.extraArgs} ${mailOption} ${cfg.configFile}";
252+
Type = "oneshot";
253+
ExecStart = "${lib.getExe pkgs.logrotate} ${utils.escapeSystemdExecArgs cfg.extraArgs} ${mailOption} ${cfg.configFile}";
254+
255+
# performance
256+
Nice = 19;
257+
IOSchedulingClass = "best-effort";
258+
IOSchedulingPriority = 7;
259+
260+
# hardening
261+
CapabilityBoundingSet = [
262+
"CAP_CHOWN"
263+
"CAP_SETGID"
264+
];
265+
DevicePolicy = "closed";
266+
LockPersonality = true;
267+
MemoryDenyWriteExecute = true;
268+
NoNewPrivileges = true;
269+
PrivateDevices = true;
270+
PrivateTmp = true;
271+
ProcSubset = "pid";
272+
ProtectClock = true;
273+
ProtectControlGroups = true;
274+
ProtectHome = true;
275+
ProtectHostname = true;
276+
ProtectKernelLogs = true;
277+
ProtectKernelModules = true;
278+
ProtectKernelTunables = true;
279+
ProtectProc = "invisible";
280+
ProtectSystem = "full";
281+
RestrictNamespaces = true;
282+
RestrictRealtime = true;
283+
RestrictSUIDSGID = true;
284+
SystemCallArchitectures = "native";
285+
SystemCallFilter = [
286+
"@system-service"
287+
"~@privileged @resources"
288+
"@chown"
289+
];
290+
UMask = "0027";
291+
} // lib.optionalAttrs (!cfg.allowNetworking) {
292+
PrivateNetwork = true;
293+
RestrictAddressFamilies = "none";
249294
};
250295
};
251296
systemd.services.logrotate-checkconf = {

nixos/tests/logrotate.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,5 +127,7 @@ import ./make-test-python.nix ({ pkgs, ... }: rec {
127127
if info["ActiveState"] != "failed":
128128
raise Exception('logrotate-checkconf.service was not failed')
129129
130+
machine.log(machine.execute("systemd-analyze security logrotate.service | grep -v ✓")[1])
131+
130132
'';
131133
})

0 commit comments

Comments
 (0)