dovecot service: refactor module
This commit is contained in:
parent
a190cb7636
commit
3f4276369e
@ -3,137 +3,178 @@
|
|||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
cfg = config.services.dovecot2;
|
cfg = config.services.dovecot2;
|
||||||
|
dovecotPkg = cfg.package;
|
||||||
|
|
||||||
dovecotConf =
|
baseDir = "/run/dovecot2";
|
||||||
''
|
stateDir = "/var/lib/dovecot";
|
||||||
base_dir = /var/run/dovecot2/
|
|
||||||
|
|
||||||
protocols = ${optionalString cfg.enableImap "imap"} ${optionalString cfg.enablePop3 "pop3"} ${optionalString cfg.enableLmtp "lmtp"}
|
protocols = concatStrings [
|
||||||
|
(optionalString cfg.enableImap "imap")
|
||||||
|
(optionalString cfg.enablePop3 "pop3")
|
||||||
|
(optionalString cfg.enableLmtp "lmtp")
|
||||||
|
];
|
||||||
|
|
||||||
|
dovecotConf = concatStrings [
|
||||||
''
|
''
|
||||||
+ (if cfg.sslServerCert!="" then
|
base_dir = ${baseDir}
|
||||||
|
protocols = ${protocols}
|
||||||
''
|
''
|
||||||
ssl_cert = <${cfg.sslServerCert}
|
|
||||||
ssl_key = <${cfg.sslServerKey}
|
(if isNull cfg.sslServerCert then ''
|
||||||
ssl_ca = <${cfg.sslCACert}
|
|
||||||
disable_plaintext_auth = yes
|
|
||||||
'' else ''
|
|
||||||
ssl = no
|
ssl = no
|
||||||
disable_plaintext_auth = no
|
disable_plaintext_auth = no
|
||||||
|
'' else ''
|
||||||
|
ssl_cert = <${cfg.sslServerCert}
|
||||||
|
ssl_key = <${cfg.sslServerKey}
|
||||||
|
${optionalString (!(isNull cfg.sslCACert)) ("ssl_ca = <" + cfg.sslCACert)}
|
||||||
|
disable_plaintext_auth = yes
|
||||||
'')
|
'')
|
||||||
|
|
||||||
+ ''
|
''
|
||||||
default_internal_user = ${cfg.user}
|
default_internal_user = ${cfg.user}
|
||||||
|
|
||||||
mail_location = ${cfg.mailLocation}
|
mail_location = ${cfg.mailLocation}
|
||||||
|
|
||||||
maildir_copy_with_hardlinks = yes
|
maildir_copy_with_hardlinks = yes
|
||||||
|
pop3_uidl_format = %08Xv%08Xu
|
||||||
|
|
||||||
auth_mechanisms = plain login
|
auth_mechanisms = plain login
|
||||||
|
|
||||||
service auth {
|
service auth {
|
||||||
user = root
|
user = root
|
||||||
}
|
}
|
||||||
|
''
|
||||||
|
|
||||||
|
(optionalString cfg.enablePAM ''
|
||||||
userdb {
|
userdb {
|
||||||
driver = passwd
|
driver = passwd
|
||||||
}
|
}
|
||||||
|
|
||||||
passdb {
|
passdb {
|
||||||
driver = pam
|
driver = pam
|
||||||
args = ${optionalString cfg.showPAMFailure "failure_show_msg=yes"} dovecot2
|
args = ${optionalString cfg.showPAMFailure "failure_show_msg=yes"} dovecot2
|
||||||
}
|
}
|
||||||
|
'')
|
||||||
|
|
||||||
pop3_uidl_format = %08Xv%08Xu
|
cfg.extraConfig
|
||||||
'' + cfg.extraConfig;
|
];
|
||||||
|
|
||||||
|
modulesDir = pkgs.symlinkJoin "dovecot-modules"
|
||||||
|
(map (module: "${module}/lib/dovecot") cfg.modules);
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
###### interface
|
options.services.dovecot2 = {
|
||||||
|
enable = mkEnableOption "Dovecot 2.x POP3/IMAP server";
|
||||||
|
|
||||||
options = {
|
enablePop3 = mkOption {
|
||||||
|
type = types.bool;
|
||||||
services.dovecot2 = {
|
default = true;
|
||||||
|
description = "Start the POP3 listener (when Dovecot is enabled).";
|
||||||
enable = mkOption {
|
|
||||||
default = false;
|
|
||||||
description = "Whether to enable the Dovecot 2.x POP3/IMAP server.";
|
|
||||||
};
|
|
||||||
|
|
||||||
enablePop3 = mkOption {
|
|
||||||
default = true;
|
|
||||||
description = "Start the POP3 listener (when Dovecot is enabled).";
|
|
||||||
};
|
|
||||||
|
|
||||||
enableImap = mkOption {
|
|
||||||
default = true;
|
|
||||||
description = "Start the IMAP listener (when Dovecot is enabled).";
|
|
||||||
};
|
|
||||||
|
|
||||||
enableLmtp = mkOption {
|
|
||||||
default = false;
|
|
||||||
description = "Start the LMTP listener (when Dovecot is enabled).";
|
|
||||||
};
|
|
||||||
|
|
||||||
user = mkOption {
|
|
||||||
default = "dovecot2";
|
|
||||||
description = "Dovecot user name.";
|
|
||||||
};
|
|
||||||
|
|
||||||
group = mkOption {
|
|
||||||
default = "dovecot2";
|
|
||||||
description = "Dovecot group name.";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
default = "";
|
|
||||||
example = "mail_debug = yes";
|
|
||||||
description = "Additional entries to put verbatim into Dovecot's config file.";
|
|
||||||
};
|
|
||||||
|
|
||||||
configFile = mkOption {
|
|
||||||
default = null;
|
|
||||||
description = "Config file used for the whole dovecot configuration.";
|
|
||||||
apply = v: if v != null then v else pkgs.writeText "dovecot.conf" dovecotConf;
|
|
||||||
};
|
|
||||||
|
|
||||||
mailLocation = mkOption {
|
|
||||||
default = "maildir:/var/spool/mail/%u"; /* Same as inbox, as postfix */
|
|
||||||
example = "maildir:~/mail:INBOX=/var/spool/mail/%u";
|
|
||||||
description = ''
|
|
||||||
Location that dovecot will use for mail folders. Dovecot mail_location option.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
sslServerCert = mkOption {
|
|
||||||
default = "";
|
|
||||||
description = "Server certificate";
|
|
||||||
};
|
|
||||||
|
|
||||||
sslCACert = mkOption {
|
|
||||||
default = "";
|
|
||||||
description = "CA certificate used by the server certificate.";
|
|
||||||
};
|
|
||||||
|
|
||||||
sslServerKey = mkOption {
|
|
||||||
default = "";
|
|
||||||
description = "Server key.";
|
|
||||||
};
|
|
||||||
|
|
||||||
showPAMFailure = mkOption {
|
|
||||||
default = false;
|
|
||||||
description = "Show the PAM failure message on authentication error (useful for OTPW).";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enableImap = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Start the IMAP listener (when Dovecot is enabled).";
|
||||||
|
};
|
||||||
|
|
||||||
|
enableLmtp = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Start the LMTP listener (when Dovecot is enabled).";
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.dovecot22;
|
||||||
|
description = "Dovecot package to use.";
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "dovecot2";
|
||||||
|
description = "Dovecot user name.";
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "dovecot2";
|
||||||
|
description = "Dovecot group name.";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
example = "mail_debug = yes";
|
||||||
|
description = "Additional entries to put verbatim into Dovecot's config file.";
|
||||||
|
};
|
||||||
|
|
||||||
|
configFile = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Config file used for the whole dovecot configuration.";
|
||||||
|
apply = v: if v != null then v else pkgs.writeText "dovecot.conf" dovecotConf;
|
||||||
|
};
|
||||||
|
|
||||||
|
mailLocation = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "maildir:/var/spool/mail/%u"; /* Same as inbox, as postfix */
|
||||||
|
example = "maildir:~/mail:INBOX=/var/spool/mail/%u";
|
||||||
|
description = ''
|
||||||
|
Location that dovecot will use for mail folders. Dovecot mail_location option.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
modules = mkOption {
|
||||||
|
type = types.listOf types.package;
|
||||||
|
default = [];
|
||||||
|
example = [ pkgs.dovecot_pigeonhole ];
|
||||||
|
description = ''
|
||||||
|
Symlinks the contents of lib/dovecot of every given package into
|
||||||
|
/var/lib/dovecot/modules. This will make the given modules available
|
||||||
|
if a dovecot package with the module_dir patch applied (like
|
||||||
|
pkgs.dovecot22, the default) is being used.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
sslCACert = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Path to the server's CA certificate key.";
|
||||||
|
};
|
||||||
|
|
||||||
|
sslServerCert = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Path to the server's public key.";
|
||||||
|
};
|
||||||
|
|
||||||
|
sslServerKey = mkOption {
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Path to the server's private key.";
|
||||||
|
};
|
||||||
|
|
||||||
|
enablePAM = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Wether to create a own Dovecot PAM service and configure PAM user logins.";
|
||||||
|
};
|
||||||
|
|
||||||
|
showPAMFailure = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Show the PAM failure message on authentication error (useful for OTPW).";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
###### implementation
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
config = mkIf config.services.dovecot2.enable {
|
security.pam.services.dovecot2 = mkIf cfg.enablePAM {};
|
||||||
|
|
||||||
security.pam.services.dovecot2 = {};
|
|
||||||
|
|
||||||
users.extraUsers = [
|
users.extraUsers = [
|
||||||
{ name = cfg.user;
|
{ name = cfg.user;
|
||||||
@ -148,36 +189,47 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
users.extraGroups = singleton
|
users.extraGroups = singleton {
|
||||||
{ name = cfg.group;
|
name = cfg.group;
|
||||||
gid = config.ids.gids.dovecot2;
|
gid = config.ids.gids.dovecot2;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.dovecot2 = {
|
||||||
|
description = "Dovecot IMAP/POP3 server";
|
||||||
|
|
||||||
|
after = [ "keys.target" "network.target" ];
|
||||||
|
wants = [ "keys.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
preStart = ''
|
||||||
|
mkdir -p "${baseDir}/login"
|
||||||
|
chown -R ${cfg.user}:${cfg.group} "${baseDir}"
|
||||||
|
rm -f "${stateDir}/modules"
|
||||||
|
ln -s "${modulesDir}" "${stateDir}/modules"
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${dovecotPkg}/sbin/dovecot -F -c ${cfg.configFile}";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = "1s";
|
||||||
|
StartLimitInterval = "1min";
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services.dovecot2 =
|
environment.systemPackages = [ dovecotPkg ];
|
||||||
{ description = "Dovecot IMAP/POP3 server";
|
|
||||||
|
|
||||||
after = [ "network.target" ];
|
assertions = [
|
||||||
wantedBy = [ "multi-user.target" ];
|
{ assertion = cfg.enablePop3 || cfg.enableImap;
|
||||||
|
message = "dovecot needs at least one of the IMAP or POP3 listeners enabled";
|
||||||
preStart =
|
}
|
||||||
''
|
{ assertion = isNull cfg.sslServerCert == isNull cfg.sslServerKey
|
||||||
${pkgs.coreutils}/bin/mkdir -p /var/run/dovecot2 /var/run/dovecot2/login
|
&& (!(isNull cfg.sslCACert) -> !(isNull cfg.sslServerCert || isNull cfg.sslServerKey));
|
||||||
${pkgs.coreutils}/bin/chown -R ${cfg.user}:${cfg.group} /var/run/dovecot2
|
message = "dovecot needs both sslServerCert and sslServerKey defined for working crypto";
|
||||||
'';
|
}
|
||||||
|
{ assertion = cfg.showPAMFailure -> cfg.enablePAM;
|
||||||
serviceConfig = {
|
message = "dovecot is configured with showPAMFailure while enablePAM is disabled";
|
||||||
ExecStart = "${pkgs.dovecot}/sbin/dovecot -F -c ${cfg.configFile}";
|
}
|
||||||
Restart = "on-failure";
|
];
|
||||||
RestartSec = "1s";
|
|
||||||
StartLimitInterval = "1min";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.dovecot ];
|
|
||||||
|
|
||||||
assertions = [{ assertion = cfg.enablePop3 || cfg.enableImap;
|
|
||||||
message = "dovecot needs at least one of the IMAP or POP3 listeners enabled";}];
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user