dovecot service: refactor module

This commit is contained in:
Christoph Hrdinka 2015-12-09 10:27:44 +01:00
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";}];
}; };