Reapply "nixos/dovecot: improve and harden systemd unit"
This reverts commit a794031c597bd8a1898a1305b70952508e2d3612. With the following additions: Allow `CAP_KILL`, so the dovecot master process may interrupt its child processes. Allow new privileges, so dovecot and call the setuid sendmail executable. Allow AF_NETLINK sockets, so dovecot sieve handling can use the getifaddrs syscall. Finally, we now asssert, that no options are set on the legacy dovecot2 systemd unit name, to make the user aware they need to update their overrides.
This commit is contained in:
parent
3687f1eb34
commit
6403717045
@ -70,6 +70,8 @@
|
||||
|
||||
- []{#sec-release-25.11-incompatibilities-sourcehut-removed} The `services.sourcehut` module and corresponding `sourcehut` packages were removed due to being broken and unmaintained.
|
||||
|
||||
- The `dovecot` systemd service was renamed from `dovecot2` to `dovecot`. The former is now just an alias. Update any overrides on the systemd unit to the new name.
|
||||
|
||||
- The `yeahwm` package and `services.xserver.windowManager.yeahwm` module were removed due to the package being broken and unmaintained upstream.
|
||||
|
||||
- The `services.postgresql` module now sets up a systemd unit `postgresql.target`. Depending on `postgresql.target` guarantees that postgres is in read-write mode and initial/ensure scripts were executed. Depending on `postgresql.service` only guarantees a read-only connection.
|
||||
|
@ -692,23 +692,69 @@ in
|
||||
|
||||
environment.etc."dovecot/dovecot.conf".source = cfg.configFile;
|
||||
|
||||
systemd.services.dovecot2 = {
|
||||
systemd.services.dovecot = {
|
||||
aliases = [ "dovecot2.service" ];
|
||||
description = "Dovecot IMAP/POP3 server";
|
||||
documentation = [
|
||||
"man:dovecot(1)"
|
||||
"https://doc.dovecot.org"
|
||||
];
|
||||
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [
|
||||
cfg.configFile
|
||||
];
|
||||
restartTriggers = [ cfg.configFile ];
|
||||
|
||||
startLimitIntervalSec = 60; # 1 min
|
||||
serviceConfig = {
|
||||
Type = "notify";
|
||||
ExecStart = "${dovecotPkg}/sbin/dovecot -F";
|
||||
ExecReload = "${dovecotPkg}/sbin/doveadm reload";
|
||||
|
||||
CapabilityBoundingSet = [
|
||||
"CAP_CHOWN"
|
||||
"CAP_DAC_OVERRIDE"
|
||||
"CAP_FOWNER"
|
||||
"CAP_KILL" # Required for child process management
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
"CAP_SETGID"
|
||||
"CAP_SETUID"
|
||||
"CAP_SYS_CHROOT"
|
||||
"CAP_SYS_RESOURCE"
|
||||
];
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = false; # e.g for sendmail
|
||||
OOMPolicy = "continue";
|
||||
PrivateTmp = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = lib.mkDefault false;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "full";
|
||||
PrivateDevices = true;
|
||||
Restart = "on-failure";
|
||||
RestartSec = "1s";
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_NETLINK" # e.g. getifaddrs in sieve handling
|
||||
"AF_UNIX"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = false; # sets sgid on maildirs
|
||||
RuntimeDirectory = [ "dovecot2" ];
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service @resources"
|
||||
"~@privileged"
|
||||
"@chown @setuid capset chroot"
|
||||
];
|
||||
};
|
||||
|
||||
# When copying sieve scripts preserve the original time stamp
|
||||
@ -773,6 +819,12 @@ in
|
||||
assertion = cfg.sieve.scripts != { } -> (cfg.mailUser != null && cfg.mailGroup != null);
|
||||
message = "dovecot requires mailUser and mailGroup to be set when `sieve.scripts` is set";
|
||||
}
|
||||
{
|
||||
assertion = config.systemd.services ? dovecot2 == false;
|
||||
message = ''
|
||||
Your configuration sets options on the `dovecot2` systemd service. These have no effect until they're migrated to the `dovecot` service.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
|
@ -84,11 +84,13 @@
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("postfix.service")
|
||||
machine.wait_for_unit("dovecot2.service")
|
||||
machine.wait_for_unit("dovecot.service")
|
||||
machine.succeed("send-testmail")
|
||||
machine.succeed("send-lda")
|
||||
machine.wait_until_fails('[ "$(postqueue -p)" != "Mail queue is empty" ]')
|
||||
machine.succeed("test-imap")
|
||||
machine.succeed("test-pop")
|
||||
|
||||
machine.log(machine.succeed("systemd-analyze security dovecot.service | grep -v ✓"))
|
||||
'';
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user