--- /dev/null
+{ lib, pkgs, config, name, nodes, ... }:
+let
+ getDomains = p: lib.mapAttrsToList (n: v: v.fqdn) (lib.filterAttrs (n: v: v.receive) p.emailPolicies);
+ bydomain = builtins.mapAttrs (n: getDomains) nodes.eldiron.config.myServices.dns.zones;
+ receiving_domains = lib.flatten (builtins.attrValues bydomain);
+in
+{
+ options.myServices.mailBackup.enable = lib.mkEnableOption "enable MX backup services";
+ config = lib.mkIf config.myServices.mailBackup.enable {
+ myServices.mail.milters.enable = true;
+ security.acme.certs."mail" = {
+ postRun = ''
+ systemctl restart postfix.service
+ '';
+ domain = config.hostEnv.fqdn;
+ extraDomainNames = let
+ zonesWithMx = builtins.attrNames (lib.filterAttrs (n: v: v.hasEmail) nodes.eldiron.config.myServices.dns.zones);
+ mxs = map (n: "${config.myEnv.servers."${name}".mx.subdomain}.${n}") zonesWithMx;
+ in mxs;
+ };
+ secrets.keys = {
+ "postfix/mysql_alias_maps" = {
+ user = config.services.postfix.user;
+ group = config.services.postfix.group;
+ permissions = "0440";
+ text = ''
+ # We need to specify that option to trigger ssl connection
+ tls_ciphers = TLSv1.2
+ user = ${config.myEnv.mail.postfix.mysql.user}
+ password = ${config.myEnv.mail.postfix.mysql.password}
+ hosts = ${config.myEnv.mail.postfix.mysql.remoteHost}
+ dbname = ${config.myEnv.mail.postfix.mysql.database}
+ query = SELECT DISTINCT 1
+ FROM forwardings
+ WHERE
+ ((regex = 1 AND '%s' REGEXP CONCAT('^',source,'$') ) OR (regex = 0 AND source = '%s'))
+ AND active = 1
+ AND '%s' NOT IN
+ (
+ SELECT source
+ FROM forwardings_blacklisted
+ WHERE source = '%s'
+ ) UNION
+ SELECT 'devnull@immae.eu'
+ FROM forwardings_blacklisted
+ WHERE source = '%s'
+ '';
+ };
+ "postfix/ldap_mailboxes" = {
+ user = config.services.postfix.user;
+ group = config.services.postfix.group;
+ permissions = "0440";
+ text = ''
+ server_host = ldaps://${config.myEnv.mail.dovecot.ldap.host}:636
+ search_base = ${config.myEnv.mail.dovecot.ldap.base}
+ query_filter = ${config.myEnv.mail.dovecot.ldap.postfix_mailbox_filter}
+ bind_dn = ${config.myEnv.mail.dovecot.ldap.dn}
+ bind_pw = ${config.myEnv.mail.dovecot.ldap.password}
+ result_attribute = immaePostfixAddress
+ result_format = dummy
+ version = 3
+ '';
+ };
+ "postfix/sympa_mailbox_maps" = {
+ user = config.services.postfix.user;
+ group = config.services.postfix.group;
+ permissions = "0440";
+ text = ''
+ hosts = ${config.myEnv.mail.sympa.postgresql.host}
+ user = ${config.myEnv.mail.sympa.postgresql.user}
+ password = ${config.myEnv.mail.sympa.postgresql.password}
+ dbname = ${config.myEnv.mail.sympa.postgresql.database}
+ query = SELECT DISTINCT 1 FROM list_table WHERE '%s' IN (
+ CONCAT(name_list, '@', robot_list),
+ CONCAT(name_list, '-request@', robot_list),
+ CONCAT(name_list, '-editor@', robot_list),
+ CONCAT(name_list, '-unsubscribe@', robot_list),
+ CONCAT(name_list, '-owner@', robot_list),
+ CONCAT('sympa-request@', robot_list),
+ CONCAT('sympa-owner@', robot_list),
+ CONCAT('sympa@', robot_list),
+ CONCAT('listmaster@', robot_list),
+ CONCAT('bounce@', robot_list),
+ CONCAT('abuse-feedback-report@', robot_list)
+ )
+ '';
+ };
+ "postfix/ldap_ejabberd_users_immae_fr" = {
+ user = config.services.postfix.user;
+ group = config.services.postfix.group;
+ permissions = "0440";
+ text = ''
+ server_host = ldaps://${config.myEnv.jabber.ldap.host}:636
+ search_base = ${config.myEnv.jabber.ldap.base}
+ query_filter = ${config.myEnv.jabber.postfix_user_filter}
+ domain = immae.fr
+ bind_dn = ${config.myEnv.jabber.ldap.dn}
+ bind_pw = ${config.myEnv.jabber.ldap.password}
+ result_attribute = immaeXmppUid
+ result_format = ejabberd@localhost
+ version = 3
+ '';
+ };
+ };
+
+ networking.firewall.allowedTCPPorts = [ 25 ];
+
+ users.users."${config.services.postfix.user}".extraGroups = [ "keys" ];
+ services.filesWatcher.postfix = {
+ restart = true;
+ paths = [
+ config.secrets.fullPaths."postfix/mysql_alias_maps"
+ config.secrets.fullPaths."postfix/sympa_mailbox_maps"
+ config.secrets.fullPaths."postfix/ldap_ejabberd_users_immae_fr"
+ config.secrets.fullPaths."postfix/ldap_mailboxes"
+ ];
+ };
+ services.postfix = {
+ mapFiles = let
+ virtual_map = {
+ virtual = let
+ cfg = config.myEnv.monitoring.email_check.eldiron;
+ address = "${cfg.mail_address}@${cfg.mail_domain}";
+ aliases = config.myEnv.mail.postfix.common_aliases;
+ in pkgs.writeText "postfix-virtual" (
+ builtins.concatStringsSep "\n" (
+ [ "${address} 1"
+ ] ++
+ map (a: "${a} 1") config.myEnv.mail.postfix.other_aliases ++
+ lib.lists.flatten (map (domain: map (alias: "${alias}@${domain} 1") aliases) receiving_domains)
+ )
+ );
+ };
+ in
+ virtual_map;
+ config = {
+ ### postfix module overrides
+ readme_directory = "${pkgs.postfix}/share/postfix/doc";
+ smtp_tls_CAfile = lib.mkForce "";
+ smtp_tls_cert_file = lib.mkForce "";
+ smtp_tls_key_file = lib.mkForce "";
+
+ message_size_limit = "1073741824"; # Don't put 0 here, it's not equivalent to "unlimited"
+ mailbox_size_limit = "1073741825"; # Workaround, local delivered mails should all go through scripts
+ alias_database = "\$alias_maps";
+
+ ### Relay domains
+ relay_domains = receiving_domains;
+ relay_recipient_maps = let
+ virtual_alias_maps = [
+ "hash:/etc/postfix/virtual"
+ "mysql:${config.secrets.fullPaths."postfix/mysql_alias_maps"}"
+ "ldap:${config.secrets.fullPaths."postfix/ldap_ejabberd_users_immae_fr"}"
+ ];
+ virtual_mailbox_maps = [
+ "ldap:${config.secrets.fullPaths."postfix/ldap_mailboxes"}"
+ "pgsql:${config.secrets.fullPaths."postfix/sympa_mailbox_maps"}"
+ ];
+ in
+ virtual_alias_maps ++ virtual_mailbox_maps;
+ smtpd_relay_restrictions = [
+ "defer_unauth_destination"
+ ];
+
+ ### Additional smtpd configuration
+ smtpd_tls_received_header = "yes";
+ smtpd_tls_loglevel = "1";
+
+ ### Email sending configuration
+ smtp_tls_security_level = "may";
+ smtp_tls_loglevel = "1";
+
+ ### Force ip bind for smtp
+ smtp_bind_address = builtins.head config.myEnv.servers."${name}".ips.main.ip4;
+ smtp_bind_address6 = builtins.head config.myEnv.servers."${name}".ips.main.ip6;
+
+ smtpd_milters = [
+ "unix:${config.myServices.mail.milters.sockets.opendkim}"
+ "unix:${config.myServices.mail.milters.sockets.openarc}"
+ "unix:${config.myServices.mail.milters.sockets.opendmarc}"
+ ];
+ };
+ enable = true;
+ enableSmtp = true;
+ enableSubmission = false;
+ destination = ["localhost"];
+ # This needs to reverse DNS
+ hostname = config.hostEnv.fqdn;
+ setSendmail = false;
+ sslCert = "/var/lib/acme/mail/fullchain.pem";
+ sslKey = "/var/lib/acme/mail/key.pem";
+ recipientDelimiter = "+";
+ };
+ };
+}
+