diff options
author | Alyssa Ross <hi@alyssa.is> | 2021-01-10 07:13:44 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2021-01-12 14:07:16 +0000 |
commit | e2698550456abba83c6dcd5d5e5a9990a0b96f8a (patch) | |
tree | 79a56f0df3fa55e470d84b4dff6059fbf487ec18 /nixpkgs/nixos/modules/services/mail | |
parent | 1cdc42df888dc98c347e03bd942ed9825a55bcb3 (diff) | |
parent | 84d74ae9c9cbed73274b8e4e00be14688ffc93fe (diff) | |
download | nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.tar nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.tar.gz nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.tar.bz2 nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.tar.lz nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.tar.xz nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.tar.zst nixlib-e2698550456abba83c6dcd5d5e5a9990a0b96f8a.zip |
Merge commit '84d74ae9c9cbed73274b8e4e00be14688ffc93fe'
Diffstat (limited to 'nixpkgs/nixos/modules/services/mail')
-rw-r--r-- | nixpkgs/nixos/modules/services/mail/dovecot.nix | 33 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/mail/mailhog.nix | 68 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/mail/mailman.nix | 80 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/mail/opendkim.nix | 30 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/mail/pfix-srsd.nix | 2 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/mail/postfix.nix | 90 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/mail/roundcube.nix | 18 |
7 files changed, 239 insertions, 82 deletions
diff --git a/nixpkgs/nixos/modules/services/mail/dovecot.nix b/nixpkgs/nixos/modules/services/mail/dovecot.nix index 51cbcbf1cbc8..c166ef68f292 100644 --- a/nixpkgs/nixos/modules/services/mail/dovecot.nix +++ b/nixpkgs/nixos/modules/services/mail/dovecot.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, ... }: +{ options, config, lib, pkgs, ... }: with lib; @@ -83,11 +83,11 @@ let ) ( - optionalString (cfg.mailboxes != []) '' + optionalString (cfg.mailboxes != {}) '' protocol imap { namespace inbox { inbox=yes - ${concatStringsSep "\n" (map mailboxConfig cfg.mailboxes)} + ${concatStringsSep "\n" (map mailboxConfig (attrValues cfg.mailboxes))} } } '' @@ -131,12 +131,13 @@ let special_use = \${toString mailbox.specialUse} '' + "}"; - mailboxes = { ... }: { + mailboxes = { name, ... }: { options = { name = mkOption { - type = types.nullOr (types.strMatching ''[^"]+''); + type = types.strMatching ''[^"]+''; example = "Spam"; - default = null; + default = name; + readOnly = true; description = "The name of the mailbox."; }; auto = mkOption { @@ -335,19 +336,11 @@ in }; mailboxes = mkOption { - type = with types; let m = submodule mailboxes; in either (listOf m) (attrsOf m); + type = with types; coercedTo + (listOf unspecified) + (list: listToAttrs (map (entry: { name = entry.name; value = removeAttrs entry ["name"]; }) list)) + (attrsOf (submodule mailboxes)); default = {}; - apply = x: - if isList x then warn "Declaring `services.dovecot2.mailboxes' as a list is deprecated and will break eval in 21.03!" x - else mapAttrsToList (name: value: - if value.name != null - then throw '' - When specifying dovecot2 mailboxes as attributes, declaring - a `name'-attribute is prohibited! The name ${value.name} should - be the attribute key! - '' - else value // { inherit name; } - ) x; example = literalExample '' { Spam = { specialUse = "Junk"; auto = "create"; }; @@ -471,6 +464,10 @@ in environment.systemPackages = [ dovecotPkg ]; + warnings = mkIf (any isList options.services.dovecot2.mailboxes.definitions) [ + "Declaring `services.dovecot2.mailboxes' as a list is deprecated and will break eval in 21.03! See the release notes for more info for migration." + ]; + assertions = [ { assertion = intersectLists cfg.protocols [ "pop3" "imap" ] != []; diff --git a/nixpkgs/nixos/modules/services/mail/mailhog.nix b/nixpkgs/nixos/modules/services/mail/mailhog.nix index 0f998c6d0ea6..b113f4ff3dec 100644 --- a/nixpkgs/nixos/modules/services/mail/mailhog.nix +++ b/nixpkgs/nixos/modules/services/mail/mailhog.nix @@ -4,17 +4,59 @@ with lib; let cfg = config.services.mailhog; -in { + + args = lib.concatStringsSep " " ( + [ + "-api-bind-addr :${toString cfg.apiPort}" + "-smtp-bind-addr :${toString cfg.smtpPort}" + "-ui-bind-addr :${toString cfg.uiPort}" + "-storage ${cfg.storage}" + ] ++ lib.optional (cfg.storage == "maildir") + "-maildir-path $STATE_DIRECTORY" + ++ cfg.extraArgs + ); + +in +{ ###### interface + imports = [ + (mkRemovedOptionModule [ "services" "mailhog" "user" ] "") + ]; + options = { services.mailhog = { enable = mkEnableOption "MailHog"; - user = mkOption { - type = types.str; - default = "mailhog"; - description = "User account under which mailhog runs."; + + storage = mkOption { + type = types.enum [ "maildir" "memory" ]; + default = "memory"; + description = "Store mails on disk or in memory."; + }; + + apiPort = mkOption { + type = types.port; + default = 8025; + description = "Port on which the API endpoint will listen."; + }; + + smtpPort = mkOption { + type = types.port; + default = 1025; + description = "Port on which the SMTP endpoint will listen."; + }; + + uiPort = mkOption { + type = types.port; + default = 8025; + description = "Port on which the HTTP UI will listen."; + }; + + extraArgs = mkOption { + type = types.listOf types.str; + default = []; + description = "List of additional arguments to pass to the MailHog process."; }; }; }; @@ -24,20 +66,16 @@ in { config = mkIf cfg.enable { - users.users.mailhog = { - name = cfg.user; - description = "MailHog service user"; - isSystemUser = true; - }; - systemd.services.mailhog = { - description = "MailHog service"; + description = "MailHog - Web and API based SMTP testing"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { - Type = "simple"; - ExecStart = "${pkgs.mailhog}/bin/MailHog"; - User = cfg.user; + Type = "exec"; + ExecStart = "${pkgs.mailhog}/bin/MailHog ${args}"; + DynamicUser = true; + Restart = "on-failure"; + StateDirectory = "mailhog"; }; }; }; diff --git a/nixpkgs/nixos/modules/services/mail/mailman.nix b/nixpkgs/nixos/modules/services/mail/mailman.nix index 81108327d3c7..115730e29d5e 100644 --- a/nixpkgs/nixos/modules/services/mail/mailman.nix +++ b/nixpkgs/nixos/modules/services/mail/mailman.nix @@ -6,14 +6,9 @@ let cfg = config.services.mailman; - pythonEnv = pkgs.python3.withPackages (ps: - [ps.mailman ps.mailman-web] - ++ lib.optional cfg.hyperkitty.enable ps.mailman-hyperkitty - ++ cfg.extraPythonPackages); - # This deliberately doesn't use recursiveUpdate so users can # override the defaults. - settings = { + webSettings = { DEFAULT_FROM_EMAIL = cfg.siteOwner; SERVER_EMAIL = cfg.siteOwner; ALLOWED_HOSTS = [ "localhost" "127.0.0.1" ] ++ cfg.webHosts; @@ -29,9 +24,13 @@ let level = "INFO"; }; }; + HAYSTACK_CONNECTIONS.default = { + ENGINE = "haystack.backends.whoosh_backend.WhooshEngine"; + PATH = "/var/lib/mailman-web/fulltext-index"; + }; } // cfg.webSettings; - settingsJSON = pkgs.writeText "settings.json" (builtins.toJSON settings); + webSettingsJSON = pkgs.writeText "settings.json" (builtins.toJSON webSettings); # TODO: Should this be RFC42-ised so that users can set additional options without modifying the module? mtaConfig = pkgs.writeText "mailman-postfix.cfg" '' @@ -40,31 +39,7 @@ let transport_file_type: hash ''; - mailmanCfg = '' - [mailman] - site_owner: ${cfg.siteOwner} - layout: fhs - - [paths.fhs] - bin_dir: ${pkgs.python3Packages.mailman}/bin - var_dir: /var/lib/mailman - queue_dir: $var_dir/queue - template_dir: $var_dir/templates - log_dir: /var/log/mailman - lock_dir: $var_dir/lock - etc_dir: /etc - ext_dir: $etc_dir/mailman.d - pid_file: /run/mailman/master.pid - - [mta] - configuration: ${mtaConfig} - '' + optionalString cfg.hyperkitty.enable '' - - [archiver.hyperkitty] - class: mailman_hyperkitty.Archiver - enable: yes - configuration: /var/lib/mailman/mailman-hyperkitty.cfg - '' + cfg.extraConfig; + mailmanCfg = (lib.generators.toINI {} cfg.settings) + cfg.extraConfig; mailmanHyperkittyCfg = pkgs.writeText "mailman-hyperkitty.cfg" '' [general] @@ -154,6 +129,12 @@ in { enable = mkEnableOption "Automatic nginx and uwsgi setup for mailman-web"; }; + settings = mkOption { + description = "Settings for mailman.cfg"; + type = types.attrsOf (types.attrsOf types.str); + default = {}; + }; + hyperkitty = { enable = mkEnableOption "the Hyperkitty archiver for Mailman"; @@ -180,6 +161,35 @@ in { config = mkIf cfg.enable { + services.mailman.settings = { + mailman.site_owner = lib.mkDefault cfg.siteOwner; + mailman.layout = "fhs"; + + "paths.fhs" = { + bin_dir = "${pkgs.python3Packages.mailman}/bin"; + var_dir = "/var/lib/mailman"; + queue_dir = "$var_dir/queue"; + template_dir = "$var_dir/templates"; + log_dir = "/var/log/mailman"; + lock_dir = "$var_dir/lock"; + etc_dir = "/etc"; + ext_dir = "$etc_dir/mailman.d"; + pid_file = "/run/mailman/master.pid"; + }; + + mta.configuration = lib.mkDefault "${mtaConfig}"; + + "archiver.hyperkitty" = lib.mkIf cfg.hyperkitty.enable { + class = "mailman_hyperkitty.Archiver"; + enable = "yes"; + configuration = "/var/lib/mailman/mailman-hyperkitty.cfg"; + }; + } // (let + loggerNames = ["root" "archiver" "bounce" "config" "database" "debug" "error" "fromusenet" "http" "locks" "mischief" "plugins" "runner" "smtp"]; + loggerSectionNames = map (n: "logging.${n}") loggerNames; + in lib.genAttrs loggerSectionNames(name: { handler = "stderr"; }) + ); + assertions = let inherit (config.services) postfix; @@ -230,7 +240,7 @@ in { import json - with open('${settingsJSON}') as f: + with open('${webSettingsJSON}') as f: globals().update(json.load(f)) with open('/var/lib/mailman-web/settings_local.json') as f: @@ -243,7 +253,7 @@ in { serverAliases = cfg.webHosts; locations = { "/".extraConfig = "uwsgi_pass unix:/run/mailman-web.socket;"; - "/static/".alias = settings.STATIC_ROOT + "/"; + "/static/".alias = webSettings.STATIC_ROOT + "/"; }; }; }; @@ -332,7 +342,7 @@ in { requiredBy = [ "mailman-uwsgi.service" ]; restartTriggers = [ config.environment.etc."mailman3/settings.py".source ]; script = '' - [[ -e "${settings.STATIC_ROOT}" ]] && find "${settings.STATIC_ROOT}/" -mindepth 1 -delete + [[ -e "${webSettings.STATIC_ROOT}" ]] && find "${webSettings.STATIC_ROOT}/" -mindepth 1 -delete ${pkgs.mailman-web}/bin/mailman-web migrate ${pkgs.mailman-web}/bin/mailman-web collectstatic ${pkgs.mailman-web}/bin/mailman-web compress diff --git a/nixpkgs/nixos/modules/services/mail/opendkim.nix b/nixpkgs/nixos/modules/services/mail/opendkim.nix index eb6a426684d4..9bf6f338d93e 100644 --- a/nixpkgs/nixos/modules/services/mail/opendkim.nix +++ b/nixpkgs/nixos/modules/services/mail/opendkim.nix @@ -129,6 +129,36 @@ in { User = cfg.user; Group = cfg.group; RuntimeDirectory = optional (cfg.socket == defaultSock) "opendkim"; + StateDirectory = "opendkim"; + StateDirectoryMode = "0700"; + ReadWritePaths = [ cfg.keyPath ]; + + AmbientCapabilities = []; + CapabilityBoundingSet = []; + DevicePolicy = "closed"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "strict"; + RemoveIPC = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6 AF_UNIX" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ "@system-service" "~@privileged @resources" ]; + UMask = "0077"; }; }; diff --git a/nixpkgs/nixos/modules/services/mail/pfix-srsd.nix b/nixpkgs/nixos/modules/services/mail/pfix-srsd.nix index 38984f896d6a..e3dbf2a014f0 100644 --- a/nixpkgs/nixos/modules/services/mail/pfix-srsd.nix +++ b/nixpkgs/nixos/modules/services/mail/pfix-srsd.nix @@ -53,4 +53,4 @@ with lib; }; }; }; -} \ No newline at end of file +} diff --git a/nixpkgs/nixos/modules/services/mail/postfix.nix b/nixpkgs/nixos/modules/services/mail/postfix.nix index 608f64a68fb0..fd4d16cdc37b 100644 --- a/nixpkgs/nixos/modules/services/mail/postfix.nix +++ b/nixpkgs/nixos/modules/services/mail/postfix.nix @@ -25,6 +25,8 @@ let clientRestrictions = concatStringsSep ", " (clientAccess ++ dnsBl); + smtpTlsSecurityLevel = if cfg.useDane then "dane" else "may"; + mainCf = let escape = replaceStrings ["$"] ["$$"]; mkList = items: "\n " + concatStringsSep ",\n " items; @@ -280,6 +282,17 @@ in description = "Whether to enable smtp submission."; }; + enableSubmissions = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable smtp submission via smtps. + + According to RFC 8314 this should be preferred + over STARTTLS for submission of messages by end user clients. + ''; + }; + submissionOptions = mkOption { type = types.attrs; default = { @@ -298,6 +311,29 @@ in description = "Options for the submission config in master.cf"; }; + submissionsOptions = mkOption { + type = types.attrs; + default = { + smtpd_sasl_auth_enable = "yes"; + smtpd_client_restrictions = "permit_sasl_authenticated,reject"; + milter_macro_daemon_name = "ORIGINATING"; + }; + example = { + smtpd_sasl_auth_enable = "yes"; + smtpd_sasl_type = "dovecot"; + smtpd_client_restrictions = "permit_sasl_authenticated,reject"; + milter_macro_daemon_name = "ORIGINATING"; + }; + description = '' + Options for the submission config via smtps in master.cf. + + smtpd_tls_security_level will be set to encrypt, if it is missing + or has one of the values "may" or "none". + + smtpd_tls_wrappermode with value "yes" will be added automatically. + ''; + }; + setSendmail = mkOption { type = types.bool; default = true; @@ -454,7 +490,7 @@ in ''; example = { mail_owner = "postfix"; - smtp_use_tls = true; + smtp_tls_security_level = "may"; }; }; @@ -466,16 +502,26 @@ in "; }; - sslCert = mkOption { + tlsTrustedAuthorities = mkOption { type = types.str; - default = ""; - description = "SSL certificate to use."; + default = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + description = '' + File containing trusted certification authorities (CA) to verify certificates of mailservers contacted for mail delivery. This basically sets smtp_tls_CAfile and enables opportunistic tls. Defaults to NixOS trusted certification authorities. + ''; + }; + + useDane = mkOption { + type = types.bool; + default = false; + description = '' + Sets smtp_tls_security_level to "dane" rather than "may". See postconf(5) for details. + ''; }; - sslCACert = mkOption { + sslCert = mkOption { type = types.str; default = ""; - description = "SSL certificate of CA."; + description = "SSL certificate to use."; }; sslKey = mkOption { @@ -771,18 +817,20 @@ in recipient_canonical_classes = [ "envelope_recipient" ]; } // optionalAttrs cfg.enableHeaderChecks { header_checks = [ "regexp:/etc/postfix/header_checks" ]; } + // optionalAttrs (cfg.tlsTrustedAuthorities != "") { + smtp_tls_CAfile = cfg.tlsTrustedAuthorities; + smtp_tls_security_level = smtpTlsSecurityLevel; + } // optionalAttrs (cfg.sslCert != "") { - smtp_tls_CAfile = cfg.sslCACert; smtp_tls_cert_file = cfg.sslCert; smtp_tls_key_file = cfg.sslKey; - smtp_use_tls = true; + smtp_tls_security_level = smtpTlsSecurityLevel; - smtpd_tls_CAfile = cfg.sslCACert; smtpd_tls_cert_file = cfg.sslCert; smtpd_tls_key_file = cfg.sslKey; - smtpd_use_tls = true; + smtpd_tls_security_level = "may"; }; services.postfix.masterConfig = { @@ -878,6 +926,23 @@ in command = "smtp"; args = [ "-o" "smtp_fallback_relay=" ]; }; + } // optionalAttrs cfg.enableSubmissions { + submissions = { + type = "inet"; + private = false; + command = "smtpd"; + args = let + mkKeyVal = opt: val: [ "-o" (opt + "=" + val) ]; + adjustSmtpTlsSecurityLevel = !(cfg.submissionsOptions ? smtpd_tls_security_level) || + cfg.submissionsOptions.smtpd_tls_security_level == "none" || + cfg.submissionsOptions.smtpd_tls_security_level == "may"; + submissionsOptions = cfg.submissionsOptions // { + smtpd_tls_wrappermode = "yes"; + } // optionalAttrs adjustSmtpTlsSecurityLevel { + smtpd_tls_security_level = "encrypt"; + }; + in concatLists (mapAttrsToList mkKeyVal submissionsOptions); + }; }; } @@ -900,4 +965,9 @@ in services.postfix.mapFiles.client_access = checkClientAccessFile; }) ]); + + imports = [ + (mkRemovedOptionModule [ "services" "postfix" "sslCACert" ] + "services.postfix.sslCACert was replaced by services.postfix.tlsTrustedAuthorities. In case you intend that your server should validate requested client certificates use services.postfix.extraConfig.") + ]; } diff --git a/nixpkgs/nixos/modules/services/mail/roundcube.nix b/nixpkgs/nixos/modules/services/mail/roundcube.nix index ed1439745ac9..a0bbab64985b 100644 --- a/nixpkgs/nixos/modules/services/mail/roundcube.nix +++ b/nixpkgs/nixos/modules/services/mail/roundcube.nix @@ -95,6 +95,18 @@ in ''; }; + maxAttachmentSize = mkOption { + type = types.int; + default = 18; + description = '' + The maximum attachment size in MB. + + Note: Since roundcube only uses 70% of max upload values configured in php + 30% is added automatically to <xref linkend="opt-services.roundcube.maxAttachmentSize"/>. + ''; + apply = configuredMaxAttachmentSize: "${toString (configuredMaxAttachmentSize * 1.3)}M"; + }; + extraConfig = mkOption { type = types.lines; default = ""; @@ -115,7 +127,7 @@ in $config = array(); $config['db_dsnw'] = 'pgsql://${cfg.database.username}${lib.optionalString (!localDB) ":' . $password . '"}@${if localDB then "unix(/run/postgresql)" else cfg.database.host}/${cfg.database.dbname}'; $config['log_driver'] = 'syslog'; - $config['max_message_size'] = '25M'; + $config['max_message_size'] = '${cfg.maxAttachmentSize}'; $config['plugins'] = [${concatMapStringsSep "," (p: "'${p}'") cfg.plugins}]; $config['des_key'] = file_get_contents('/var/lib/roundcube/des_key'); $config['mime_types'] = '${pkgs.nginx}/conf/mime.types'; @@ -172,8 +184,8 @@ in phpOptions = '' error_log = 'stderr' log_errors = on - post_max_size = 25M - upload_max_filesize = 25M + post_max_size = ${cfg.maxAttachmentSize} + upload_max_filesize = ${cfg.maxAttachmentSize} ''; settings = mapAttrs (name: mkDefault) { "listen.owner" = "nginx"; |