diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2023-10-04 01:35:06 +0200 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2023-10-04 02:11:48 +0200 |
commit | 1a64deeb894dc95e2645a75771732c6cc53a79ad (patch) | |
tree | 1b9df4838f894577a09b9b260151756272efeb53 /systems/eldiron/mail/postfix.nix | |
parent | fa25ffd4583cc362075cd5e1b4130f33306103f0 (diff) | |
download | Nix-1a64deeb894dc95e2645a75771732c6cc53a79ad.tar.gz Nix-1a64deeb894dc95e2645a75771732c6cc53a79ad.tar.zst Nix-1a64deeb894dc95e2645a75771732c6cc53a79ad.zip |
Squash changes containing private information
There were a lot of changes since the previous commit, but a lot of them
contained personnal information about users. All thos changes got
stashed into a single commit (history is kept in a different place) and
private information was moved in a separate private repository
Diffstat (limited to 'systems/eldiron/mail/postfix.nix')
-rw-r--r-- | systems/eldiron/mail/postfix.nix | 497 |
1 files changed, 497 insertions, 0 deletions
diff --git a/systems/eldiron/mail/postfix.nix b/systems/eldiron/mail/postfix.nix new file mode 100644 index 0000000..f95ee1b --- /dev/null +++ b/systems/eldiron/mail/postfix.nix | |||
@@ -0,0 +1,497 @@ | |||
1 | { lib, pkgs, config, options, ... }: | ||
2 | let | ||
3 | getDomains = p: lib.mapAttrsToList (n: v: v.fqdn) (lib.filterAttrs (n: v: v.receive) p.emailPolicies); | ||
4 | bydomain = builtins.mapAttrs (n: getDomains) config.myServices.dns.zones; | ||
5 | receiving_domains = lib.flatten (builtins.attrValues bydomain); | ||
6 | in | ||
7 | { | ||
8 | options.services.postfix.submissionOptions' = options.services.postfix.submissionOptions // { | ||
9 | type = with lib.types; attrsOf (either str (listOf str)); | ||
10 | apply = builtins.mapAttrs (n: v: if builtins.isList v then builtins.concatStringsSep "," v else v); | ||
11 | }; | ||
12 | config = lib.mkIf config.myServices.mail.enable { | ||
13 | myServices.dns.zones."immae.eu" = with config.myServices.dns.helpers; lib.mkMerge [ | ||
14 | mailMX | ||
15 | (mailCommon "immae.eu") | ||
16 | mailSend | ||
17 | { | ||
18 | # Virtual forwards and mailboxes for real users | ||
19 | emailPolicies."mail".receive = true; | ||
20 | # multi-domain generic mails: | ||
21 | # hostmaster, cron, httpd, naemon, postmaster | ||
22 | # system virtual mailboxes: | ||
23 | # devnull, printer, testconnect | ||
24 | emailPolicies."".receive = true; | ||
25 | subdomains.mail = lib.mkMerge [ (mailCommon "immae.eu") mailSend ]; | ||
26 | subdomains.smtp = ips servers.eldiron.ips.main; | ||
27 | |||
28 | # DMARC reports | ||
29 | subdomains._dmarc.subdomains._report.subdomains = let | ||
30 | getDomains = p: lib.mapAttrsToList (n: v: v.fqdn) p.emailPolicies; | ||
31 | bydomain = builtins.mapAttrs (n: getDomains) config.myServices.dns.zones; | ||
32 | hostsWithMail = lib.flatten (builtins.attrValues bydomain); | ||
33 | nvpairs = builtins.map (e: { name = e; value = { TXT = [ "v=DMARC1;" ]; }; }) hostsWithMail; | ||
34 | in | ||
35 | builtins.listToAttrs nvpairs; | ||
36 | } | ||
37 | ]; | ||
38 | |||
39 | myServices.chatonsProperties.hostings.mx-backup = { | ||
40 | file.datetime = "2022-08-22T01:00:00"; | ||
41 | hosting = { | ||
42 | name = "MX Backup"; | ||
43 | description = "Serveur e-mail secondaire"; | ||
44 | logo = "https://www.postfix.org/favicon.ico"; | ||
45 | website = "https://mail.immae.eu/"; | ||
46 | status.level = "OK"; | ||
47 | status.description = "OK"; | ||
48 | registration.load = "OPEN"; | ||
49 | install.type = "PACKAGE"; | ||
50 | }; | ||
51 | software = { | ||
52 | name = "Postfix"; | ||
53 | website = "http://www.postfix.org/"; | ||
54 | license.url = "http://postfix.mirrors.ovh.net/postfix-release/LICENSE"; | ||
55 | license.name = "Eclipse Public license (EPL 2.0) and IBM Public License (IPL 1.0)"; | ||
56 | version = pkgs.postfix.version; | ||
57 | source.url = "http://www.postfix.org/download.html"; | ||
58 | }; | ||
59 | }; | ||
60 | secrets.keys = { | ||
61 | "postfix/mysql_alias_maps" = { | ||
62 | user = config.services.postfix.user; | ||
63 | group = config.services.postfix.group; | ||
64 | permissions = "0440"; | ||
65 | text = '' | ||
66 | # We need to specify that option to trigger ssl connection | ||
67 | tls_ciphers = TLSv1.2 | ||
68 | user = ${config.myEnv.mail.postfix.mysql.user} | ||
69 | password = ${config.myEnv.mail.postfix.mysql.password} | ||
70 | hosts = unix:${config.myEnv.mail.postfix.mysql.socket} | ||
71 | dbname = ${config.myEnv.mail.postfix.mysql.database} | ||
72 | query = SELECT DISTINCT destination | ||
73 | FROM forwardings | ||
74 | WHERE | ||
75 | ((regex = 1 AND '%s' REGEXP CONCAT('^',source,'$') ) OR (regex = 0 AND source = '%s')) | ||
76 | AND active = 1 | ||
77 | AND '%s' NOT IN | ||
78 | ( | ||
79 | SELECT source | ||
80 | FROM forwardings_blacklisted | ||
81 | WHERE source = '%s' | ||
82 | ) UNION | ||
83 | SELECT 'devnull@immae.eu' | ||
84 | FROM forwardings_blacklisted | ||
85 | WHERE source = '%s' | ||
86 | ''; | ||
87 | }; | ||
88 | "postfix/ldap_mailboxes" = { | ||
89 | user = config.services.postfix.user; | ||
90 | group = config.services.postfix.group; | ||
91 | permissions = "0440"; | ||
92 | text = '' | ||
93 | server_host = ldaps://${config.myEnv.mail.dovecot.ldap.host}:636 | ||
94 | search_base = ${config.myEnv.mail.dovecot.ldap.base} | ||
95 | query_filter = ${config.myEnv.mail.dovecot.ldap.postfix_mailbox_filter} | ||
96 | bind_dn = ${config.myEnv.mail.dovecot.ldap.dn} | ||
97 | bind_pw = ${config.myEnv.mail.dovecot.ldap.password} | ||
98 | result_attribute = immaePostfixAddress | ||
99 | result_format = dummy | ||
100 | version = 3 | ||
101 | ''; | ||
102 | }; | ||
103 | "postfix/mysql_sender_login_maps" = { | ||
104 | user = config.services.postfix.user; | ||
105 | group = config.services.postfix.group; | ||
106 | permissions = "0440"; | ||
107 | text = '' | ||
108 | # We need to specify that option to trigger ssl connection | ||
109 | tls_ciphers = TLSv1.2 | ||
110 | user = ${config.myEnv.mail.postfix.mysql.user} | ||
111 | password = ${config.myEnv.mail.postfix.mysql.password} | ||
112 | hosts = unix:${config.myEnv.mail.postfix.mysql.socket} | ||
113 | dbname = ${config.myEnv.mail.postfix.mysql.database} | ||
114 | query = SELECT DISTINCT destination | ||
115 | FROM forwardings | ||
116 | WHERE | ||
117 | ( | ||
118 | (regex = 1 AND CONCAT(SUBSTRING_INDEX('%u', '+', 1), '@%d') REGEXP CONCAT('^',source,'$') ) | ||
119 | OR | ||
120 | (regex = 0 AND source = CONCAT(SUBSTRING_INDEX('%u', '+', 1), '@%d')) | ||
121 | ) | ||
122 | AND active = 1 | ||
123 | UNION SELECT CONCAT(SUBSTRING_INDEX('%u', '+', 1), '@%d') AS destination | ||
124 | ''; | ||
125 | }; | ||
126 | "postfix/mysql_sender_relays_maps" = { | ||
127 | user = config.services.postfix.user; | ||
128 | group = config.services.postfix.group; | ||
129 | permissions = "0440"; | ||
130 | text = '' | ||
131 | # We need to specify that option to trigger ssl connection | ||
132 | tls_ciphers = TLSv1.2 | ||
133 | user = ${config.myEnv.mail.postfix.mysql.user} | ||
134 | password = ${config.myEnv.mail.postfix.mysql.password} | ||
135 | hosts = unix:${config.myEnv.mail.postfix.mysql.socket} | ||
136 | dbname = ${config.myEnv.mail.postfix.mysql.database} | ||
137 | # INSERT INTO sender_relays | ||
138 | # (`from`, owner, relay, login, password, regex, active) | ||
139 | # VALUES | ||
140 | # ( 'sender@otherhost.org' | ||
141 | # , 'me@mail.immae.eu' | ||
142 | # , '[otherhost.org]:587' | ||
143 | # , 'otherhostlogin' | ||
144 | # , AES_ENCRYPT('otherhostpassword', '${config.myEnv.mail.postfix.mysql.password_encrypt}') | ||
145 | # , '0' | ||
146 | # , '1'); | ||
147 | |||
148 | query = SELECT DISTINCT `owner` | ||
149 | FROM sender_relays | ||
150 | WHERE | ||
151 | ((regex = 1 AND '%s' REGEXP CONCAT('^',`from`,'$') ) OR (regex = 0 AND `from` = '%s')) | ||
152 | AND active = 1 | ||
153 | ''; | ||
154 | }; | ||
155 | "postfix/mysql_sender_relays_hosts" = { | ||
156 | user = config.services.postfix.user; | ||
157 | group = config.services.postfix.group; | ||
158 | permissions = "0440"; | ||
159 | text = '' | ||
160 | # We need to specify that option to trigger ssl connection | ||
161 | tls_ciphers = TLSv1.2 | ||
162 | user = ${config.myEnv.mail.postfix.mysql.user} | ||
163 | password = ${config.myEnv.mail.postfix.mysql.password} | ||
164 | hosts = unix:${config.myEnv.mail.postfix.mysql.socket} | ||
165 | dbname = ${config.myEnv.mail.postfix.mysql.database} | ||
166 | |||
167 | query = SELECT DISTINCT relay | ||
168 | FROM sender_relays | ||
169 | WHERE | ||
170 | ((regex = 1 AND '%s' REGEXP CONCAT('^',`from`,'$') ) OR (regex = 0 AND `from` = '%s')) | ||
171 | AND active = 1 | ||
172 | ''; | ||
173 | }; | ||
174 | "postfix/mysql_sender_relays_creds" = { | ||
175 | user = config.services.postfix.user; | ||
176 | group = config.services.postfix.group; | ||
177 | permissions = "0440"; | ||
178 | text = '' | ||
179 | # We need to specify that option to trigger ssl connection | ||
180 | tls_ciphers = TLSv1.2 | ||
181 | user = ${config.myEnv.mail.postfix.mysql.user} | ||
182 | password = ${config.myEnv.mail.postfix.mysql.password} | ||
183 | hosts = unix:${config.myEnv.mail.postfix.mysql.socket} | ||
184 | dbname = ${config.myEnv.mail.postfix.mysql.database} | ||
185 | |||
186 | query = SELECT DISTINCT CONCAT(`login`, ':', AES_DECRYPT(`password`, '${config.myEnv.mail.postfix.mysql.password_encrypt}')) | ||
187 | FROM sender_relays | ||
188 | WHERE | ||
189 | ((regex = 1 AND '%s' REGEXP CONCAT('^',`from`,'$') ) OR (regex = 0 AND `from` = '%s')) | ||
190 | AND active = 1 | ||
191 | ''; | ||
192 | }; | ||
193 | "postfix/ldap_ejabberd_users_immae_fr" = { | ||
194 | user = config.services.postfix.user; | ||
195 | group = config.services.postfix.group; | ||
196 | permissions = "0440"; | ||
197 | text = '' | ||
198 | server_host = ldaps://${config.myEnv.jabber.ldap.host}:636 | ||
199 | search_base = ${config.myEnv.jabber.ldap.base} | ||
200 | query_filter = ${config.myEnv.jabber.postfix_user_filter} | ||
201 | domain = immae.fr | ||
202 | bind_dn = ${config.myEnv.jabber.ldap.dn} | ||
203 | bind_pw = ${config.myEnv.jabber.ldap.password} | ||
204 | result_attribute = immaeXmppUid | ||
205 | result_format = ejabberd@localhost | ||
206 | version = 3 | ||
207 | ''; | ||
208 | }; | ||
209 | }; | ||
210 | |||
211 | networking.firewall.allowedTCPPorts = [ 25 465 587 ]; | ||
212 | |||
213 | users.users.postfixscripts = { | ||
214 | group = "keys"; | ||
215 | uid = config.ids.uids.postfixscripts; | ||
216 | description = "Postfix scripts user"; | ||
217 | }; | ||
218 | users.users."${config.services.postfix.user}".extraGroups = [ "keys" ]; | ||
219 | services.filesWatcher.postfix = { | ||
220 | restart = true; | ||
221 | paths = [ | ||
222 | config.secrets.fullPaths."postfix/mysql_alias_maps" | ||
223 | config.secrets.fullPaths."postfix/ldap_mailboxes" | ||
224 | config.secrets.fullPaths."postfix/mysql_sender_login_maps" | ||
225 | config.secrets.fullPaths."postfix/ldap_ejabberd_users_immae_fr" | ||
226 | ]; | ||
227 | }; | ||
228 | services.postfix = { | ||
229 | extraAliases = let | ||
230 | testmail = pkgs.writeScript "testmail" '' | ||
231 | #! ${pkgs.stdenv.shell} | ||
232 | ${pkgs.coreutils}/bin/touch \ | ||
233 | "/var/lib/naemon/checks/email/$(${pkgs.procmail}/bin/formail -x To: | ${pkgs.coreutils}/bin/tr -d ' <>')" | ||
234 | ''; | ||
235 | in | ||
236 | ''testmail: "|${testmail}"''; | ||
237 | mapFiles = let | ||
238 | virtual_map = { | ||
239 | virtual = let | ||
240 | cfg = config.myEnv.monitoring.email_check.eldiron; | ||
241 | address = "${cfg.mail_address}@${cfg.mail_domain}"; | ||
242 | aliases = config.myEnv.mail.postfix.common_aliases; | ||
243 | admins = builtins.concatStringsSep "," config.myEnv.mail.postfix.admins; | ||
244 | in pkgs.writeText "postfix-virtual" ( | ||
245 | builtins.concatStringsSep "\n" ( | ||
246 | [ "${address} testmail@localhost" | ||
247 | ] ++ | ||
248 | map (a: "${a} ${admins}") config.myEnv.mail.postfix.other_aliases | ||
249 | ++ lib.lists.flatten ( | ||
250 | map (domain: | ||
251 | map (alias: "${alias}@${domain} ${admins}") aliases | ||
252 | ) receiving_domains | ||
253 | ) | ||
254 | )); | ||
255 | }; | ||
256 | sasl_access = { | ||
257 | host_sender_login = with lib.attrsets; let | ||
258 | addresses = zipAttrs (lib.flatten (mapAttrsToList | ||
259 | (n: v: (map (e: { "${e}" = "${n}@immae.eu"; }) v.emails)) config.myEnv.servers)); | ||
260 | aliases = config.myEnv.mail.postfix.common_aliases; | ||
261 | joined = builtins.concatStringsSep ","; | ||
262 | admins = joined config.myEnv.mail.postfix.admins; | ||
263 | in pkgs.writeText "host-sender-login" | ||
264 | (builtins.concatStringsSep "\n" ( | ||
265 | mapAttrsToList (n: v: "${n} ${joined v}") addresses | ||
266 | ++ lib.lists.flatten ( | ||
267 | map (domain: | ||
268 | map (alias: "${alias}@${domain} ${admins}") aliases | ||
269 | ) receiving_domains | ||
270 | ) | ||
271 | ++ map (a: "${a} ${admins}") config.myEnv.mail.postfix.other_aliases | ||
272 | )); | ||
273 | }; | ||
274 | in | ||
275 | virtual_map // sasl_access; | ||
276 | config = { | ||
277 | ### postfix module overrides | ||
278 | readme_directory = "${pkgs.postfix}/share/postfix/doc"; | ||
279 | smtp_tls_CAfile = lib.mkForce ""; | ||
280 | smtp_tls_cert_file = lib.mkForce ""; | ||
281 | smtp_tls_key_file = lib.mkForce ""; | ||
282 | |||
283 | message_size_limit = "1073741824"; # Don't put 0 here, it's not equivalent to "unlimited" | ||
284 | mailbox_size_limit = "1073741825"; # Workaround, local delivered mails should all go through scripts | ||
285 | alias_database = "\$alias_maps"; | ||
286 | |||
287 | ### Aliases scripts user | ||
288 | default_privs = "postfixscripts"; | ||
289 | |||
290 | ### Virtual mailboxes config | ||
291 | virtual_alias_maps = [ | ||
292 | "hash:/etc/postfix/virtual" | ||
293 | "mysql:${config.secrets.fullPaths."postfix/mysql_alias_maps"}" | ||
294 | "ldap:${config.secrets.fullPaths."postfix/ldap_ejabberd_users_immae_fr"}" | ||
295 | ]; | ||
296 | virtual_mailbox_domains = receiving_domains; | ||
297 | virtual_mailbox_maps = [ | ||
298 | "ldap:${config.secrets.fullPaths."postfix/ldap_mailboxes"}" | ||
299 | ]; | ||
300 | dovecot_destination_recipient_limit = "1"; | ||
301 | virtual_transport = "dovecot"; | ||
302 | |||
303 | ### Relay domains | ||
304 | smtpd_relay_restrictions = [ | ||
305 | "defer_unauth_destination" | ||
306 | ]; | ||
307 | |||
308 | ### Additional smtpd configuration | ||
309 | smtpd_tls_received_header = "yes"; | ||
310 | smtpd_tls_loglevel = "1"; | ||
311 | |||
312 | ### Email sending configuration | ||
313 | smtp_tls_security_level = "may"; | ||
314 | smtp_tls_loglevel = "1"; | ||
315 | |||
316 | ### Force ip bind for smtp | ||
317 | smtp_bind_address = builtins.head config.hostEnv.ips.main.ip4; | ||
318 | smtp_bind_address6 = builtins.head config.hostEnv.ips.main.ip6; | ||
319 | |||
320 | # Use some relays when authorized senders are not myself | ||
321 | smtp_sasl_mechanism_filter = [ | ||
322 | "plain" | ||
323 | "login" | ||
324 | ]; # GSSAPI Not correctly supported by postfix | ||
325 | smtp_sasl_auth_enable = "yes"; | ||
326 | smtp_sasl_password_maps = [ | ||
327 | "mysql:${config.secrets.fullPaths."postfix/mysql_sender_relays_creds"}" | ||
328 | ]; | ||
329 | smtp_sasl_security_options = "noanonymous"; | ||
330 | smtp_sender_dependent_authentication = "yes"; | ||
331 | sender_dependent_relayhost_maps = [ | ||
332 | "mysql:${config.secrets.fullPaths."postfix/mysql_sender_relays_hosts"}" | ||
333 | ]; | ||
334 | |||
335 | ### opendkim, opendmarc, openarc milters | ||
336 | non_smtpd_milters = [ | ||
337 | "unix:${config.myServices.mail.milters.sockets.opendkim}" | ||
338 | ]; | ||
339 | smtpd_milters = [ | ||
340 | "unix:${config.myServices.mail.milters.sockets.opendkim}" | ||
341 | "unix:${config.myServices.mail.milters.sockets.openarc}" | ||
342 | "unix:${config.myServices.mail.milters.sockets.opendmarc}" | ||
343 | ]; | ||
344 | |||
345 | smtp_use_tls = true; | ||
346 | smtpd_use_tls = true; | ||
347 | smtpd_tls_chain_files = [ | ||
348 | "/var/lib/acme/mail/full.pem" | ||
349 | "/var/lib/acme/mail-rsa/full.pem" | ||
350 | ]; | ||
351 | |||
352 | maximal_queue_lifetime = "6w"; | ||
353 | bounce_queue_lifetime = "6w"; | ||
354 | }; | ||
355 | enable = true; | ||
356 | enableSmtp = true; | ||
357 | enableSubmission = true; | ||
358 | submissionOptions = config.services.postfix.submissionOptions'; | ||
359 | submissionOptions' = { | ||
360 | # Don’t use "long form", only commas (cf | ||
361 | # http://www.postfix.org/master.5.html long form is not handled | ||
362 | # well by the submission function) | ||
363 | smtpd_tls_security_level = "encrypt"; | ||
364 | smtpd_sasl_auth_enable = "yes"; | ||
365 | smtpd_tls_auth_only = "yes"; | ||
366 | smtpd_sasl_tls_security_options = "noanonymous"; | ||
367 | smtpd_sasl_type = "dovecot"; | ||
368 | smtpd_sasl_path = "private/auth"; | ||
369 | smtpd_reject_unlisted_recipient = "no"; | ||
370 | smtpd_client_restrictions = [ | ||
371 | "permit_sasl_authenticated" | ||
372 | "reject" | ||
373 | ]; | ||
374 | smtpd_relay_restrictions = [ | ||
375 | "permit_sasl_authenticated" | ||
376 | "reject" | ||
377 | ]; | ||
378 | # Refuse to send e-mails with a From that is not handled | ||
379 | smtpd_sender_restrictions = [ | ||
380 | "reject_sender_login_mismatch" | ||
381 | "reject_unlisted_sender" | ||
382 | "permit_sasl_authenticated,reject" | ||
383 | ]; | ||
384 | smtpd_sender_login_maps = [ | ||
385 | "hash:/etc/postfix/host_sender_login" | ||
386 | "mysql:${config.secrets.fullPaths."postfix/mysql_sender_relays_maps"}" | ||
387 | "mysql:${config.secrets.fullPaths."postfix/mysql_sender_login_maps"}" | ||
388 | ]; | ||
389 | smtpd_recipient_restrictions = [ | ||
390 | "permit_sasl_authenticated" | ||
391 | "reject" | ||
392 | ]; | ||
393 | milter_macro_daemon_name = "ORIGINATING"; | ||
394 | smtpd_milters = [ | ||
395 | # FIXME: put it back when opensmtpd is upgraded and able to | ||
396 | # rewrite the from header | ||
397 | #"unix:/run/milter_verify_from/verify_from.sock" | ||
398 | "unix:${config.myServices.mail.milters.sockets.opendkim}" | ||
399 | ]; | ||
400 | }; | ||
401 | destination = ["localhost"]; | ||
402 | # This needs to reverse DNS | ||
403 | hostname = config.hostEnv.fqdn; | ||
404 | setSendmail = true; | ||
405 | recipientDelimiter = "+"; | ||
406 | masterConfig = { | ||
407 | submissions = { | ||
408 | type = "inet"; | ||
409 | private = false; | ||
410 | command = "smtpd"; | ||
411 | args = ["-o" "smtpd_tls_wrappermode=yes" ] ++ (let | ||
412 | mkKeyVal = opt: val: [ "-o" (opt + "=" + val) ]; | ||
413 | in lib.concatLists (lib.mapAttrsToList mkKeyVal config.services.postfix.submissionOptions) | ||
414 | ); | ||
415 | }; | ||
416 | dovecot = { | ||
417 | type = "unix"; | ||
418 | privileged = true; | ||
419 | chroot = false; | ||
420 | command = "pipe"; | ||
421 | args = let | ||
422 | # rspamd could be used as a milter, but then it cannot apply | ||
423 | # its checks "per user" (milter is not yet dispatched to | ||
424 | # users), so we wrap dovecot-lda inside rspamc per recipient | ||
425 | # here. | ||
426 | rspamc_dovecot = pkgs.writeScriptBin "rspamc_dovecot" '' | ||
427 | #! ${pkgs.stdenv.shell} | ||
428 | set -o pipefail | ||
429 | sender="$1" | ||
430 | original_recipient="$2" | ||
431 | user="$3" | ||
432 | |||
433 | ${pkgs.coreutils}/bin/cat - | \ | ||
434 | ${pkgs.rspamd}/bin/rspamc -h ${config.myServices.mail.rspamd.sockets.worker-controller} -c bayes -d "$user" --mime | \ | ||
435 | ${pkgs.dovecot}/libexec/dovecot/dovecot-lda -f "$sender" -a "$original_recipient" -d "$user" | ||
436 | if echo ''${PIPESTATUS[@]} | ${pkgs.gnugrep}/bin/grep -qE '^[0 ]+$'; then | ||
437 | exit 0 | ||
438 | else | ||
439 | # src/global/sys_exits.h to retry | ||
440 | exit 75 | ||
441 | fi | ||
442 | ''; | ||
443 | in [ | ||
444 | "flags=ODRhu" "user=vhost:vhost" | ||
445 | "argv=${rspamc_dovecot}/bin/rspamc_dovecot \${sender} \${original_recipient} \${user}@\${nexthop}" | ||
446 | ]; | ||
447 | }; | ||
448 | }; | ||
449 | }; | ||
450 | security.acme.certs."mail" = { | ||
451 | postRun = '' | ||
452 | systemctl restart postfix.service | ||
453 | ''; | ||
454 | extraDomainNames = [ "smtp.immae.eu" ]; | ||
455 | }; | ||
456 | security.acme.certs."mail-rsa" = { | ||
457 | postRun = '' | ||
458 | systemctl restart postfix.service | ||
459 | ''; | ||
460 | extraDomainNames = [ "smtp.immae.eu" ]; | ||
461 | }; | ||
462 | system.activationScripts.testmail = { | ||
463 | deps = [ "users" ]; | ||
464 | text = let | ||
465 | allCfg = config.myEnv.monitoring.email_check; | ||
466 | cfg = allCfg.eldiron; | ||
467 | reverseTargets = builtins.attrNames (lib.attrsets.filterAttrs (k: v: builtins.elem "eldiron" v.targets) allCfg); | ||
468 | to_email = cfg': host': | ||
469 | let sep = if lib.strings.hasInfix "+" cfg'.mail_address then "_" else "+"; | ||
470 | in "${cfg'.mail_address}${sep}${host'}@${cfg'.mail_domain}"; | ||
471 | mails_to_receive = builtins.concatStringsSep " " (map (to_email cfg) reverseTargets); | ||
472 | in '' | ||
473 | install -m 0555 -o postfixscripts -g keys -d /var/lib/naemon/checks/email | ||
474 | for f in ${mails_to_receive}; do | ||
475 | if [ ! -f /var/lib/naemon/checks/email/$f ]; then | ||
476 | install -m 0644 -o postfixscripts -g keys /dev/null -T /var/lib/naemon/checks/email/$f | ||
477 | touch -m -d @0 /var/lib/naemon/checks/email/$f | ||
478 | fi | ||
479 | done | ||
480 | ''; | ||
481 | }; | ||
482 | systemd.services.postfix.serviceConfig.Slice = "mail.slice"; | ||
483 | |||
484 | myServices.monitoring.fromMasterObjects.service = [ | ||
485 | { | ||
486 | service_description = "postfix SSL is up to date"; | ||
487 | host_name = config.hostEnv.fqdn; | ||
488 | use = "external-service"; | ||
489 | check_command = "check_smtp"; | ||
490 | |||
491 | servicegroups = "webstatus-ssl"; | ||
492 | _webstatus_name = "SMTP"; | ||
493 | _webstatus_url = "smtp.immae.eu"; | ||
494 | } | ||
495 | ]; | ||
496 | }; | ||
497 | } | ||