diff options
Diffstat (limited to 'modules/private/mail/relay.nix')
-rw-r--r-- | modules/private/mail/relay.nix | 235 |
1 files changed, 0 insertions, 235 deletions
diff --git a/modules/private/mail/relay.nix b/modules/private/mail/relay.nix deleted file mode 100644 index 668d365..0000000 --- a/modules/private/mail/relay.nix +++ /dev/null | |||
@@ -1,235 +0,0 @@ | |||
1 | { lib, pkgs, config, nodes, name, ... }: | ||
2 | { | ||
3 | config = lib.mkIf config.myServices.mailBackup.enable { | ||
4 | security.acme.certs."mail" = config.myServices.certificates.certConfig // { | ||
5 | postRun = '' | ||
6 | systemctl restart postfix.service | ||
7 | ''; | ||
8 | domain = config.hostEnv.fqdn; | ||
9 | extraDomains = let | ||
10 | zonesWithMx = builtins.filter (zone: | ||
11 | lib.attrsets.hasAttr "withEmail" zone && lib.lists.length zone.withEmail > 0 | ||
12 | ) config.myEnv.dns.masterZones; | ||
13 | mxs = map (zone: "${config.myEnv.servers."${name}".mx.subdomain}.${zone.name}") zonesWithMx; | ||
14 | in builtins.listToAttrs (map (mx: lib.attrsets.nameValuePair mx null) mxs); | ||
15 | }; | ||
16 | secrets.keys = { | ||
17 | "postfix/mysql_alias_maps" = { | ||
18 | user = config.services.postfix.user; | ||
19 | group = config.services.postfix.group; | ||
20 | permissions = "0440"; | ||
21 | text = '' | ||
22 | # We need to specify that option to trigger ssl connection | ||
23 | tls_ciphers = TLSv1.2 | ||
24 | user = ${config.myEnv.mail.postfix.mysql.user} | ||
25 | password = ${config.myEnv.mail.postfix.mysql.password} | ||
26 | hosts = ${config.myEnv.mail.postfix.mysql.remoteHost} | ||
27 | dbname = ${config.myEnv.mail.postfix.mysql.database} | ||
28 | query = SELECT DISTINCT 1 | ||
29 | FROM forwardings | ||
30 | WHERE | ||
31 | ((regex = 1 AND '%s' REGEXP CONCAT('^',source,'$') ) OR (regex = 0 AND source = '%s')) | ||
32 | AND active = 1 | ||
33 | AND '%s' NOT IN | ||
34 | ( | ||
35 | SELECT source | ||
36 | FROM forwardings_blacklisted | ||
37 | WHERE source = '%s' | ||
38 | ) UNION | ||
39 | SELECT 'devnull@immae.eu' | ||
40 | FROM forwardings_blacklisted | ||
41 | WHERE source = '%s' | ||
42 | ''; | ||
43 | }; | ||
44 | "postfix/ldap_mailboxes" = { | ||
45 | user = config.services.postfix.user; | ||
46 | group = config.services.postfix.group; | ||
47 | permissions = "0440"; | ||
48 | text = '' | ||
49 | server_host = ldaps://${config.myEnv.mail.dovecot.ldap.host}:636 | ||
50 | search_base = ${config.myEnv.mail.dovecot.ldap.base} | ||
51 | query_filter = ${config.myEnv.mail.dovecot.ldap.postfix_mailbox_filter} | ||
52 | bind_dn = ${config.myEnv.mail.dovecot.ldap.dn} | ||
53 | bind_pw = ${config.myEnv.mail.dovecot.ldap.password} | ||
54 | result_attribute = immaePostfixAddress | ||
55 | result_format = dummy | ||
56 | version = 3 | ||
57 | ''; | ||
58 | }; | ||
59 | "postfix/sympa_mailbox_maps" = { | ||
60 | user = config.services.postfix.user; | ||
61 | group = config.services.postfix.group; | ||
62 | permissions = "0440"; | ||
63 | text = '' | ||
64 | hosts = ${config.myEnv.mail.sympa.postgresql.host} | ||
65 | user = ${config.myEnv.mail.sympa.postgresql.user} | ||
66 | password = ${config.myEnv.mail.sympa.postgresql.password} | ||
67 | dbname = ${config.myEnv.mail.sympa.postgresql.database} | ||
68 | query = SELECT DISTINCT 1 FROM list_table WHERE '%s' IN ( | ||
69 | CONCAT(name_list, '@', robot_list), | ||
70 | CONCAT(name_list, '-request@', robot_list), | ||
71 | CONCAT(name_list, '-editor@', robot_list), | ||
72 | CONCAT(name_list, '-unsubscribe@', robot_list), | ||
73 | CONCAT(name_list, '-owner@', robot_list), | ||
74 | CONCAT('sympa-request@', robot_list), | ||
75 | CONCAT('sympa-owner@', robot_list), | ||
76 | CONCAT('sympa@', robot_list), | ||
77 | CONCAT('listmaster@', robot_list), | ||
78 | CONCAT('bounce@', robot_list), | ||
79 | CONCAT('abuse-feedback-report@', robot_list) | ||
80 | ) | ||
81 | ''; | ||
82 | }; | ||
83 | "postfix/ldap_ejabberd_users_immae_fr" = { | ||
84 | user = config.services.postfix.user; | ||
85 | group = config.services.postfix.group; | ||
86 | permissions = "0440"; | ||
87 | text = '' | ||
88 | server_host = ldaps://${config.myEnv.jabber.ldap.host}:636 | ||
89 | search_base = ${config.myEnv.jabber.ldap.base} | ||
90 | query_filter = ${config.myEnv.jabber.postfix_user_filter} | ||
91 | domain = immae.fr | ||
92 | bind_dn = ${config.myEnv.jabber.ldap.dn} | ||
93 | bind_pw = ${config.myEnv.jabber.ldap.password} | ||
94 | result_attribute = immaeXmppUid | ||
95 | result_format = ejabberd@localhost | ||
96 | version = 3 | ||
97 | ''; | ||
98 | }; | ||
99 | }; | ||
100 | |||
101 | networking.firewall.allowedTCPPorts = [ 25 ]; | ||
102 | |||
103 | users.users."${config.services.postfix.user}".extraGroups = [ "keys" ]; | ||
104 | services.filesWatcher.postfix = { | ||
105 | restart = true; | ||
106 | paths = [ | ||
107 | config.secrets.fullPaths."postfix/mysql_alias_maps" | ||
108 | config.secrets.fullPaths."postfix/sympa_mailbox_maps" | ||
109 | config.secrets.fullPaths."postfix/ldap_ejabberd_users_immae_fr" | ||
110 | config.secrets.fullPaths."postfix/ldap_mailboxes" | ||
111 | ]; | ||
112 | }; | ||
113 | services.postfix = { | ||
114 | mapFiles = let | ||
115 | recipient_maps = let | ||
116 | name = n: i: "relay_${n}_${toString i}"; | ||
117 | pair = n: i: m: lib.attrsets.nameValuePair (name n i) ( | ||
118 | if m.type == "hash" | ||
119 | then pkgs.writeText (name n i) m.content | ||
120 | else null | ||
121 | ); | ||
122 | pairs = n: v: lib.imap1 (i: m: pair n i m) v.recipient_maps; | ||
123 | in lib.attrsets.filterAttrs (k: v: v != null) ( | ||
124 | lib.attrsets.listToAttrs (lib.flatten ( | ||
125 | lib.attrsets.mapAttrsToList pairs config.myEnv.mail.postfix.backup_domains | ||
126 | )) | ||
127 | ); | ||
128 | relay_restrictions = lib.attrsets.filterAttrs (k: v: v != null) ( | ||
129 | lib.attrsets.mapAttrs' (n: v: | ||
130 | lib.attrsets.nameValuePair "recipient_access_${n}" ( | ||
131 | if lib.attrsets.hasAttr "relay_restrictions" v | ||
132 | then pkgs.writeText "recipient_access_${n}" v.relay_restrictions | ||
133 | else null | ||
134 | ) | ||
135 | ) config.myEnv.mail.postfix.backup_domains | ||
136 | ); | ||
137 | virtual_map = { | ||
138 | virtual = let | ||
139 | cfg = config.myEnv.monitoring.email_check.eldiron; | ||
140 | address = "${cfg.mail_address}@${cfg.mail_domain}"; | ||
141 | in pkgs.writeText "postfix-virtual" ( | ||
142 | builtins.concatStringsSep "\n" ( | ||
143 | ["${address} 1"] ++ | ||
144 | lib.attrsets.mapAttrsToList ( | ||
145 | n: v: lib.optionalString v.external '' | ||
146 | script_${n}@mail.immae.eu 1 | ||
147 | '' | ||
148 | ) config.myEnv.mail.scripts | ||
149 | ) | ||
150 | ); | ||
151 | }; | ||
152 | in | ||
153 | recipient_maps // relay_restrictions // virtual_map; | ||
154 | config = { | ||
155 | ### postfix module overrides | ||
156 | readme_directory = "${pkgs.postfix}/share/postfix/doc"; | ||
157 | smtp_tls_CAfile = lib.mkForce ""; | ||
158 | smtp_tls_cert_file = lib.mkForce ""; | ||
159 | smtp_tls_key_file = lib.mkForce ""; | ||
160 | |||
161 | message_size_limit = "1073741824"; # Don't put 0 here, it's not equivalent to "unlimited" | ||
162 | mailbox_size_limit = "1073741825"; # Workaround, local delivered mails should all go through scripts | ||
163 | alias_database = "\$alias_maps"; | ||
164 | |||
165 | ### Relay domains | ||
166 | relay_domains = let | ||
167 | backups = lib.flatten (lib.attrsets.mapAttrsToList (n: v: v.domains or []) config.myEnv.mail.postfix.backup_domains); | ||
168 | virtual_domains = config.myEnv.mail.postfix.additional_mailbox_domains | ||
169 | ++ lib.remove null (lib.flatten (map | ||
170 | (zone: map | ||
171 | (e: if e.receive | ||
172 | then "${e.domain}${lib.optionalString (e.domain != "") "."}${zone.name}" | ||
173 | else null | ||
174 | ) | ||
175 | (zone.withEmail or []) | ||
176 | ) | ||
177 | config.myEnv.dns.masterZones | ||
178 | )); | ||
179 | in | ||
180 | backups ++ virtual_domains; | ||
181 | relay_recipient_maps = let | ||
182 | backup_recipients = lib.flatten (lib.attrsets.mapAttrsToList (n: v: | ||
183 | lib.imap1 (i: m: "${m.type}:/etc/postfix/relay_${n}_${toString i}") v.recipient_maps | ||
184 | ) config.myEnv.mail.postfix.backup_domains); | ||
185 | virtual_alias_maps = [ | ||
186 | "hash:/etc/postfix/virtual" | ||
187 | "mysql:${config.secrets.fullPaths."postfix/mysql_alias_maps"}" | ||
188 | "ldap:${config.secrets.fullPaths."postfix/ldap_ejabberd_users_immae_fr"}" | ||
189 | ]; | ||
190 | virtual_mailbox_maps = [ | ||
191 | "ldap:${config.secrets.fullPaths."postfix/ldap_mailboxes"}" | ||
192 | "pgsql:${config.secrets.fullPaths."postfix/sympa_mailbox_maps"}" | ||
193 | ]; | ||
194 | in | ||
195 | backup_recipients ++ virtual_alias_maps ++ virtual_mailbox_maps; | ||
196 | smtpd_relay_restrictions = [ | ||
197 | "defer_unauth_destination" | ||
198 | ] ++ lib.flatten (lib.attrsets.mapAttrsToList (n: v: | ||
199 | if lib.attrsets.hasAttr "relay_restrictions" v | ||
200 | then [ "check_recipient_access hash:/etc/postfix/recipient_access_${n}" ] | ||
201 | else [] | ||
202 | ) config.myEnv.mail.postfix.backup_domains); | ||
203 | |||
204 | ### Additional smtpd configuration | ||
205 | smtpd_tls_received_header = "yes"; | ||
206 | smtpd_tls_loglevel = "1"; | ||
207 | |||
208 | ### Email sending configuration | ||
209 | smtp_tls_security_level = "may"; | ||
210 | smtp_tls_loglevel = "1"; | ||
211 | |||
212 | ### Force ip bind for smtp | ||
213 | smtp_bind_address = config.myEnv.servers."${name}".ips.main.ip4; | ||
214 | smtp_bind_address6 = builtins.head config.myEnv.servers."${name}".ips.main.ip6; | ||
215 | |||
216 | smtpd_milters = [ | ||
217 | "unix:${config.myServices.mail.milters.sockets.opendkim}" | ||
218 | "unix:${config.myServices.mail.milters.sockets.openarc}" | ||
219 | "unix:${config.myServices.mail.milters.sockets.opendmarc}" | ||
220 | ]; | ||
221 | }; | ||
222 | enable = true; | ||
223 | enableSmtp = true; | ||
224 | enableSubmission = false; | ||
225 | destination = ["localhost"]; | ||
226 | # This needs to reverse DNS | ||
227 | hostname = config.hostEnv.fqdn; | ||
228 | setSendmail = false; | ||
229 | sslCert = "/var/lib/acme/mail/fullchain.pem"; | ||
230 | sslKey = "/var/lib/acme/mail/key.pem"; | ||
231 | recipientDelimiter = "+"; | ||
232 | }; | ||
233 | }; | ||
234 | } | ||
235 | |||