nixos/logrotate: harden systemd unit

Logrotate is a service that runs as root and moves logfiles around while
keeping ownership of these files intact. This means we can and should
severely limit the scope of what can be done during its runtime.
This commit is contained in:
Martin Weinelt 2024-09-02 18:30:59 +02:00
parent 8588b1599e
commit 01d0b0b683
No known key found for this signature in database
GPG Key ID: 87C1E9888F856759
2 changed files with 50 additions and 3 deletions

View File

@ -97,6 +97,8 @@ in
defaultText = lib.literalExpression "cfg.settings != {}";
};
allowNetworking = lib.mkEnableOption "network access for logrotate";
settings = lib.mkOption {
default = { };
description = ''
@ -240,12 +242,55 @@ in
config = lib.mkIf cfg.enable {
systemd.services.logrotate = {
description = "Logrotate Service";
documentation = [
"man:logrotate(8)"
"man:logrotate(5)"
];
startAt = "hourly";
serviceConfig = {
Restart = "no";
User = "root";
ExecStart = "${pkgs.logrotate}/sbin/logrotate ${utils.escapeSystemdExecArgs cfg.extraArgs} ${mailOption} ${cfg.configFile}";
Type = "oneshot";
ExecStart = "${lib.getExe pkgs.logrotate} ${utils.escapeSystemdExecArgs cfg.extraArgs} ${mailOption} ${cfg.configFile}";
# performance
Nice = 19;
IOSchedulingClass = "best-effort";
IOSchedulingPriority = 7;
# hardening
CapabilityBoundingSet = [
"CAP_CHOWN"
"CAP_SETGID"
];
DevicePolicy = "closed";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "full";
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged @resources"
"@chown"
];
UMask = "0027";
} // lib.optionalAttrs (!cfg.allowNetworking) {
PrivateNetwork = true;
RestrictAddressFamilies = "none";
};
};
systemd.services.logrotate-checkconf = {

View File

@ -127,5 +127,7 @@ import ./make-test-python.nix ({ pkgs, ... }: rec {
if info["ActiveState"] != "failed":
raise Exception('logrotate-checkconf.service was not failed')
machine.log(machine.execute("systemd-analyze security logrotate.service | grep -v ")[1])
'';
})