{ config, lib, pkgs, ... }: with lib; let cfg = config.services.dovecot2; dovecotConf = '' base_dir = /var/run/dovecot2/ protocols = ${optionalString cfg.enableImap "imap"} ${optionalString cfg.enablePop3 "pop3"} ${optionalString cfg.enableLmtp "lmtp"} '' + (if cfg.sslServerCert!="" then '' ssl_cert = <${cfg.sslServerCert} ssl_key = <${cfg.sslServerKey} ssl_ca = <${cfg.sslCACert} disable_plaintext_auth = yes '' else '' ssl = no disable_plaintext_auth = no '') + '' default_internal_user = ${cfg.user} mail_location = ${cfg.mailLocation} maildir_copy_with_hardlinks = yes auth_mechanisms = plain login service auth { user = root } userdb { driver = passwd } passdb { driver = pam args = ${optionalString cfg.showPAMFailure "failure_show_msg=yes"} dovecot2 } pop3_uidl_format = %08Xv%08Xu '' + cfg.extraConfig; in { ###### interface options = { services.dovecot2 = { 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)."; }; }; }; ###### implementation config = mkIf config.services.dovecot2.enable { security.pam.services.dovecot2 = {}; users.extraUsers = [ { name = cfg.user; uid = config.ids.uids.dovecot2; description = "Dovecot user"; group = cfg.group; } { name = "dovenull"; uid = config.ids.uids.dovenull2; description = "Dovecot user for untrusted logins"; group = cfg.group; } ]; users.extraGroups = singleton { name = cfg.group; gid = config.ids.gids.dovecot2; }; systemd.services.dovecot2 = { description = "Dovecot IMAP/POP3 server"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; preStart = '' ${pkgs.coreutils}/bin/mkdir -p /var/run/dovecot2 /var/run/dovecot2/login ${pkgs.coreutils}/bin/chown -R ${cfg.user}:${cfg.group} /var/run/dovecot2 ''; serviceConfig = { 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";}]; }; }