]> Git — Sourcephile - sourcephile-nix.git/blob - servers/mermet/postfix.nix
nix: fix GPG_TTY
[sourcephile-nix.git] / servers / mermet / postfix.nix
1 { pkgs, lib, config, ... }:
2 let
3 inherit (builtins) attrNames readFile toPath;
4 inherit (builtins.extraBuiltins) pass;
5 inherit (lib) types;
6 inherit (pkgs.lib) loadFile unlines unwords unlinesAttrs;
7 inherit (config) networking;
8 inherit (config.services) postfix dovecot2 openldap;
9
10 submissionHeaderCleanupRules = pkgs.writeText "submission_header_cleanup_rules" ''
11 # Removes sensitive headers from mails handed in via the submission or smtps port.
12 # See https://thomas-leister.de/mailserver-debian-stretch/
13 # Uses "pcre" style regex.
14
15 /^Received:/ IGNORE
16 /^User-Agent:/ IGNORE
17 /^X-Enigmail:/ IGNORE
18 /^X-Mailer:/ IGNORE
19 /^X-Originating-IP:/ IGNORE
20 '';
21 in
22 {
23 systemd.services.postfix.after = [
24 "openldap.service"
25 "postfix.${networking.domainBase}.key.pem-key.service"
26 ];
27 deployment.keys = {
28 "postfix.${networking.domainBase}.key.pem" = {
29 text = pass "x509/${networking.domainBase}/key.pem";
30 user = postfix.user;
31 group = "root";
32 destDir = "/run/keys/";
33 permissions = "0400"; # WARNING: not enforced when deployment.storeKeysOnMachine = true
34 };
35 };
36 services.postfix = {
37 enable = true;
38 aliases = {
39 "root@${networking.domain}" = [
40 "julm@${networking.domain}"
41 ];
42 "admin@${networking.domain}" = [
43 "julm@${networking.domain}"
44 ];
45 "webmaster@${networking.domain}" = [
46 "julm@${networking.domain}"
47 ];
48 "postmaster@${networking.domain}" = [
49 "julm@${networking.domain}"
50 ];
51 };
52 #hostname = networking.domain;
53 #domain = "localdomain";
54 networksStyle = "host";
55 #mapFiles."valias" = toFile "valias" (unlines (all_valiases_postfix ++ catchAllPostfix));
56 # See https://blog.grimneko.de/2011/12/24/a-bunch-of-tips-for-improving-your-postfix-setup/
57 # for details on how this file looks. By using the same file as valias,
58 # every alias is uniquely owned by its user.
59 # The user's own address is already in all_valiases_postfix.
60 #mapFiles."vaccounts" = toFile "vaccounts" (unlines all_valiases_postfix);
61 mapFiles."ldap-virtual_alias_maps.cf" = pkgs.writeText "ldap-virtual_alias_maps.cf" ''
62 version = 3
63 debuglevel = 0
64 server_host = ldapi://
65 bind = sasl
66 sasl_mechs = EXTERNAL
67 search_base = ou=posix,${openldap.domainSuffix}
68 scope = sub
69 dereference = 0
70 query_filter = (&(mailAlias=%s)(mailEnabled=TRUE))
71 result_format = %s
72 result_attribute = mail
73 '';
74 mapFiles."ldap-forward.cf" = pkgs.writeText "ldap-forward.cf" ''
75 version = 3
76 debuglevel = 0
77 server_host = ldapi://
78 bind = sasl
79 sasl_mechs = EXTERNAL
80 search_base = ou=posix,${openldap.domainSuffix}
81 scope = sub
82 dereference = 0
83 query_filter = (&(mail=%s)(mailEnabled=TRUE))
84 result_format = %s
85 result_attribute = mailForwardingAddress
86 '';
87 sslCert = loadFile (../../../sec/openssl + "/${networking.domainBase}/cert.self-signed.pem");
88 sslKey = "/run/keys/postfix.${networking.domainBase}.key.pem";
89 #enableSubmission = true;
90 #enableSmtp = true;
91 destination = [
92 "localhost"
93 "localhost.localdomain"
94 networking.hostName
95 "${networking.hostName}.localdomain"
96 ];
97 networks = [
98 "127.0.0.0/8"
99 "[::1]/128"
100 ];
101 recipientDelimiter = "+";
102 config = {
103 # Appending .domain is the MUA's job
104 append_dot_mydomain = false;
105 # No console bell on new mail
106 biff = false;
107 body_checks = "";
108 #content_filter = "amavisfeed:[127.0.0.1]:10024";
109 #debug_peer_level = 4;
110 #debug_peer_list = ".$myhostname";
111 default_extra_recipient_limit = "5000";
112 # Uncomment the next line to generate "delayed mail" warnings
113 #delay_warning_time = "4h";
114 # Stops some techniques used to harvest email addresses
115 disable_vrfy_command = true;
116 duplicate_filter_limit = "5000";
117 enable_long_queue_ids = false;
118 # Pass unexisting $mydestination recipients to dovecot
119 fallback_transport = "lmtp:unix:private/dovecot-lmtp";
120 forward_path = [
121 ''$home/.forward''${recipient_delimiter}''${extension}''
122 "$home/.forward"
123 ];
124 #header_checks = "regexp:/var/lib/postfix/conf/header_checks";
125 #inet_interfaces = "all";
126 line_length_limit = "2048";
127
128 # Let $fallback_transport check existence of recipients
129 local_recipient_maps = "";
130 #mail_spool_directory = "/var/spool/mail";
131 # NOTE: nixpkgs's default
132 #local_header_rewrite_clients = "";
133 #home_mailbox = "Maildir/";
134 #mailbox_command = ''
135 # ${pkgs.procmail}/bin/procmail -t -a "$SENDER" -a "$RECIPIENT" -a "$USER" -a "$EXTENSION" -a "$DOMAIN" -a "$ORIGINAL_RECIPIENT" "$HOME/.procmailrc"
136 #'';
137 mailbox_size_limit = "204800000";
138
139 masquerade_classes = [ "envelope_sender" "header_sender" "header_recipient" ];
140 masquerade_domains = "";
141 masquerade_exceptions = "root";
142 maximal_queue_lifetime = "5d";
143 message_size_limit = "20480000";
144 mime_header_checks = "";
145 milter_header_checks = "";
146 nested_header_checks = "";
147 #non_smtpd_milters = "";
148 parent_domain_matches_subdomains = [
149 #"debug_peer_list"
150 #"fast_flush_domains"
151 #"mynetworks"
152 #"permit_mx_backup_networks"
153 #"qmqpd_authorized_clients"
154 #"smtpd_access_maps"
155 ];
156 permit_mx_backup_networks = "";
157 #policy-spf_time_limit = "3600s";
158 propagate_unmatched_extensions = [ "canonical" "virtual" "alias" ];
159 queue_minfree = "0";
160 #receive_override_options = "no_address_mappings";
161 # no_unknown_recipient_checks
162 # Do not try to reject unknown recipients (SMTP server only).
163 # This is typically specified AFTER an external content filter.
164 # no_address_mappings
165 # Disable canonical address mapping, virtual alias map expansion,
166 # address masquerading, and automatic BCC (blind carbon-copy) recipients.
167 # This is typically specified BEFORE an external content filter (eg. amavis).
168 # no_header_body_checks
169 # Disable header/body_checks. This is typically specified AFTER
170 # an external content filter.
171 # no_milters
172 # Disable Milter (mail filter) applications.
173 # This is typically specified AFTER an external content filter.
174 # Parse the extension in email address, eg. contact+extension@
175 relayhost = "";
176 #relay_clientcerts = hash:/var/lib/postfix/conf/relay_clientcerts
177 # This is where to put backup MX domains
178 relay_domains = "$mydestination";
179 relay_recipient_maps = "";
180 smtp_body_checks = "";
181 #smtp_cname_overrides_servername = false;
182 smtp_connect_timeout = "60s";
183 #smtp_header_checks = "regexp:/var/lib/postfix/smtp_header_checks";
184 smtp_mime_header_checks = "";
185 smtp_nested_header_checks = "";
186 smtp_tls_exclude_ciphers = [ "ADH" "MD5" "CAMELLIA" "SEED" "3DES" "DES" "RC4" "eNULL" "aNULL" ];
187 #smtp_tls_fingerprint_digest = "sha1";
188 smtp_tls_loglevel = "1";
189 #smtp_tls_note_starttls_offer = true;
190 #smtp_tls_policy_maps = "hash:/var/lib/postfix/conf/tls_policy";
191 # Only allow TLSv* protocols
192 smtp_tls_protocols = [ "!SSLv2" "!SSLv3" ];
193 smtp_tls_scert_verifydepth = "5";
194 #smtp_tls_secure_cert_match = [ "nexthop" "dot-nexthop" ];
195 smtp_tls_security_level = "may";
196 smtp_tls_session_cache_database = "btree:$data_directory/smtp_tls_session_cache";
197 #smtp_tls_session_cache_timeout = "3600s";
198 #smtp_tls_verify_cert_match = "hostname";
199 # Useful to test restrictions
200 smtpd_authorized_xclient_hosts = "127.0.0.1";
201 smtpd_banner = "${networking.hostName} ESMTP $mail_name (NixOS)";
202 smtpd_client_connection_count_limit = "50";
203 smtpd_client_connection_rate_limit = "0";
204 smtpd_client_event_limit_exceptions = "$mynetworks";
205 smtpd_client_message_rate_limit = "0";
206 smtpd_client_new_tls_session_rate_limit = "0";
207 smtpd_client_port_logging = false;
208 smtpd_client_recipient_rate_limit = "0";
209 smtpd_client_restrictions = [
210 #"check_client_access hash:/var/lib/postfix/conf/client_blacklist"
211 ];
212 smtpd_data_restrictions = [
213 "reject_unauth_pipelining"
214 # Force the smtp client to wait OK before sending
215 "permit"
216 ];
217 # Disable opportunistic encryption
218 smtpd_discard_ehlo_keywords = "starttls";
219 #smtpd_end_of_data_restrictions = "";
220 # Ban 5 sec on error
221 smtpd_error_sleep_time = "5";
222 smtpd_helo_required = true;
223 smtpd_helo_restrictions = [
224 "reject_invalid_helo_hostname"
225 "reject_non_fqdn_helo_hostname"
226 #"reject_unknown_helo_hostname"
227 # May be useful to fight spam
228 "permit"
229 ];
230 #smtpd_milters = "";
231 smtpd_peername_lookup = true;
232 smtpd_recipient_limit = "5000";
233 smtpd_recipient_overshoot_limit = "5000";
234 smtpd_recipient_restrictions = [
235 "reject_non_fqdn_recipient"
236 #"reject_invalid_hostname"
237 "reject_unknown_recipient_domain"
238 #"reject_non_fqdn_sender"
239 "reject_unauth_pipelining"
240 #"check_policy_service inet:localhost:12340"
241 # check quota
242 "permit_mynetworks"
243 #"permit_tls_clientcerts"
244 "permit_sasl_authenticated"
245 "reject_unverified_recipient"
246 # $fallback_transport is responsible of checking the existence of the recipient
247 # WARNING: verify(8) has a cache, dumpable if verify(8) is stopped, with:
248 # postmap -s btree:/var/lib/postfix/data/verify_cache
249 # Bypass SPF check and postgrey if the recipient is not for us or someone in backup_mx
250 "reject_unauth_destination"
251 # Check SPF
252 #"check_policy_service unix:private/spfcheck"
253 # Greylisting using postgrey
254 #"check_policy_service unix:${postgrey.socket.path}"
255 "permit_auth_destination"
256 "reject"
257 #"reject_unknown_sender_domain"
258 # Maybe better in smtpd_sender_restrictions
259 #"reject_rbl_client bl.spamcop.net"
260 #"reject_rbl_client list.dsbl.org"
261 #"reject_rbl_client zen.spamhaus.org"
262 #"reject_rbl_client dnsbl.sorbs.net"
263 ];
264 smtpd_relay_restrictions = [
265 "permit_mynetworks"
266 "permit_sasl_authenticated"
267 # NOTE: permit auth through dovecot's SASL
268 "reject_unauth_destination"
269 ];
270 #smtpd_restriction_classes = "";
271 broken_sasl_auth_clients = false;
272 #smtpd_sasl_auth_enable = true;
273 #smtpd_sasl_path = "private/auth";
274 #smtpd_sasl_security_options = "noanonymous";
275 #smtpd_sasl_type = "dovecot";
276 smtpd_sender_restrictions = [
277 "permit_mynetworks"
278 #"permit_tls_clientcerts"
279 "permit_sasl_authenticated"
280 # NOTE: permit auth through dovecot's SASL
281 #"check_sender_access hash:/var/lib/postfix/conf/sender_access"
282 "reject_unauth_pipelining"
283 "reject_non_fqdn_sender"
284 #"reject_sender_login_mismatch"
285 #"reject_unknown_sender_domain"
286 "permit"
287 ];
288 smtpd_starttls_timeout = "300s";
289 #smtpd_tls_always_issue_session_ids = true;
290 # No SASL AUTH without TLS
291 smtpd_tls_auth_only = true;
292 #smtpd_tls_CApath = "/etc/postfix/x509/ca/";
293 smtpd_tls_ask_ccert = false;
294 #smtpd_tls_ccert_verifydepth = "5";
295 smtpd_tls_ciphers = "high";
296 smtpd_tls_eecdh_grade = "ultra";
297 # Disable weak ciphers as reported by https://ssl-tools.net
298 # https://serverfault.com/questions/744168/how-to-disable-rc4-on-postfix
299 smtpd_tls_exclude_ciphers = [ "ADH" "MD5" "CAMELLIA" "SEED" "3DES" "DES" "RC4" "eNULL" "aNULL" ];
300 smtpd_tls_fingerprint_digest = "sha512";
301 # Log only a summary message on TLS handshake completion
302 smtpd_tls_loglevel = "1";
303 smtpd_tls_mandatory_ciphers = "high";
304 smtpd_tls_mandatory_protocols = [ "!SSLv2" "!SSLv3" ];
305 # Only allow TLSv*
306 smtpd_tls_protocols = [ "!SSLv2" "!SSLv3" ];
307 #smtpd_tls_received_header = false;
308 smtpd_tls_req_ccert = false;
309 # Postfix 2.3 and later
310 # encrypt
311 # Mandatory TLS encryption: announce STARTTLS support to SMTP clients, and require that clients use TLS
312 # encryption. According to [1720]RFC 2487 this MUST NOT be applied in case of a publicly-referenced
313 # SMTP server. Instead, this option should be used only on dedicated servers.
314 smtpd_tls_security_level = "may";
315 smtpd_tls_session_cache_database = "btree:$data_directory/smtpd_tls_session_cache";
316 #smtpd_tls_session_cache_timeout = "3600s";
317 # Stops mail from poorly written software
318 strict_rfc821_envelopes = true;
319 #sympa_destination_recipient_limit = "1";
320 #sympabounce_destination_recipient_limit = "1";
321 # postconf(5) discourages to change this
322 #tls_high_cipherlist = "AES256-SHA";
323 #tls_random_bytes = "32";
324 # Must not be in a chroot
325 #tls_random_exchange_name = "$data_directory/prng_exch";
326 #tls_random_prng_update_period = "3600s";
327 #tls_random_reseed_period = "3600s";
328 # Use a non blocking source of randomness
329 tls_random_source = "dev:/dev/urandom";
330 transport_maps = [
331 #"ldap:transport"
332 #"hash:/etc/postfix/transport-dovecot"
333 #"hash:/etc/postfix/$mydomain/transport"
334 #"hash:/etc/dovecot/transport"
335 #"regexp:/etc/sympa/transport"
336 ];
337 # Rejects immediately what $fallback_transport rejects
338 unverified_recipient_reject_code = "550";
339 # Do not specify virtual alias domain names in mydestination
340 # or relay_domains configuration parameters
341 #
342 # With a virtual alias domain, the Postfix SMTP server
343 # accepts mail for known-user@virtual-alias.domain, and
344 # rejects mail for unknown-user@virtual-alias.domain as
345 # undeliverable.
346 virtual_alias_domains = [];
347 virtual_alias_maps = [
348 #"hash:/etc/postfix/virtual_alias_maps"
349 #"hash:/etc/postfix/virtual_domain_alias_maps"
350 "ldap:/etc/postfix/ldap-forward.cf"
351 "ldap:/etc/postfix/ldap-virtual_alias_maps.cf"
352 #"hash:/etc/postfix/virtual_alias-dovecot"
353 #"hash:/var/lib/postfix/conf/valias"
354 #"regexp:/etc/sympa/virtual_alias"
355 ];
356 #virtual_uid_maps = "static:5000";
357 #virtual_gid_maps = "static:5000";
358 #virtual_mailbox_base = dovecot2.mailDir;
359 virtual_mailbox_domains = [ networking.domain ] ++ networking.domainAliases;
360 #virtual_mailbox_maps = "hash:/etc/postfix/virtual_mailbox_maps";
361 virtual_transport = "lmtp:unix:private/dovecot-lmtp";
362 };
363 #submissionOptions = {
364 # smtpd_tls_security_level = "encrypt";
365 # smtpd_sasl_auth_enable = "yes";
366 # smtpd_sasl_type = "dovecot";
367 # smtpd_sasl_path = "private/auth";
368 # smtpd_sasl_security_options = "noanonymous";
369 # smtpd_sasl_local_domain = "$myhostname";
370 # smtpd_client_restrictions = "permit_sasl_authenticated,reject";
371 # smtpd_sender_login_maps = "hash:/etc/postfix/vaccounts";
372 # smtpd_sender_restrictions = "reject_sender_login_mismatch";
373 # smtpd_recipient_restrictions = "reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject";
374 # cleanup_service_name = "submission-header-cleanup";
375 #};
376 extraMasterConf = ''
377 #spfcheck unix - n n - 0 spawn
378 # user=policyd-spf argv=/usr/sbin/postfix-policyd-spf-perl
379 465 inet n - - - - smtpd
380 -o milter_macro_daemon_name=ORIGINATING
381 -o smtpd_client_restrictions=permit_sasl_authenticated,reject
382 -o smtpd_recipient_restrictions=reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject
383 -o smtpd_sasl_auth_enable=yes
384 -o smtpd_sasl_local_domain=$myhostname
385 -o smtpd_sasl_path=private/auth
386 -o smtpd_sasl_security_options=noanonymous
387 -o smtpd_sasl_type=dovecot
388 -o smtpd_tls_ask_ccert=no
389 -o smtpd_tls_auth_only=yes
390 -o smtpd_tls_ccert_verifydepth=0
391 -o smtpd_tls_loglevel=1
392 -o smtpd_tls_req_ccert=no
393 -o smtpd_tls_security_level=encrypt
394 -o smtpd_tls_wrappermode=yes
395 # -o smtpd_sender_restrictions=reject_sender_login_mismatch
396 # -o smtpd_sender_login_maps=hash:/etc/postfix/vaccounts
397 # -o cleanup_service_name=submission-header-cleanup
398 submission-header-cleanup unix n - n - 0 cleanup
399 -o header_checks=pcre:${submissionHeaderCleanupRules}
400 #spfcheck unix - n n - 0 spawn
401 # user=policyd-spf argv=/usr/bin/postfix-policyd-spf-perl
402 #uucp unix - n n - - pipe
403 # flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
404 #smtp inet n - - - - smtpd
405 # -o cleanup_service_name=pre-cleanup
406 # -o content_filter=amavis:[127.0.0.1]:10024
407 # -o smtpd_sender_restrictions=reject_unauth_pipelining,reject_non_fqdn_sender,permit
408 # -o receive_override_options=no_address_mappings
409 #amavis unix - - n - 2 lmtp
410 # -o lmtp_data_done_timeout=1200
411 # -o lmtp_send_xforward_command=yes
412 # -o lmtp_tls_note_starttls_offer=no
413 #127.0.0.1:10025 inet n - n - - smtpd
414 # -o content_filter=
415 # -o local_header_rewrite_clients=
416 # -o local_recipient_maps=
417 # -o mynetworks=127.0.0.0/8
418 # -o receive_override_options=no_header_body_checks,no_milters,no_unknown_recipient_checks
419 # -o relay_recipient_maps=
420 # -o smtpd_client_connection_count_limit=0
421 # -o smtpd_client_connection_rate_limit=0
422 # -o smtpd_client_restrictions=permit_mynetworks,reject
423 # -o smtpd_data_restrictions=reject_unauth_pipelining
424 # -o smtpd_delay_reject=no
425 # -o smtpd_end_of_data_restrictions=
426 # -o smtpd_error_sleep_time=0
427 # -o smtpd_hard_error_limit=1000
428 # -o smtpd_helo_restrictions=
429 # -o smtpd_milters=
430 # -o smtpd_recipient_restrictions=permit_mynetworks,reject
431 # -o smtpd_restriction_classes=
432 # -o smtpd_sender_restrictions=
433 # -o smtpd_soft_error_limit=1001
434 # -o strict_rfc821_envelopes=yes
435 #submission inet n - - - - smtpd
436 # -o cleanup_service_name=pre-cleanup
437 # -o content_filter=amavis:[127.0.0.1]:10024
438 # -o milter_macro_daemon_name=ORIGINATING
439 # -o receive_override_options=no_address_mappings
440 # -o smtpd_sender_restrictions=permit_tls_clientcerts,reject
441 # -o smtpd_tls_ask_ccert=yes
442 # -o smtpd_tls_auth_only=yes
443 # -o smtpd_tls_ccert_verifydepth=2
444 # -o smtpd_tls_loglevel=1
445 # -o smtpd_tls_req_ccert=yes
446 # -o smtpd_tls_security_level=encrypt
447 #smtps inet n - - - - smtpd
448 # -o milter_macro_daemon_name=ORIGINATING
449 # -o smtpd_client_restrictions=permit_sasl_authenticated,reject
450 # -o smtpd_sasl_auth_enable=yes
451 # -o smtpd_tls_ask_ccert=yes
452 # -o smtpd_tls_auth_only=yes
453 # -o smtpd_tls_ccert_verifydepth=0
454 # -o smtpd_tls_loglevel=1
455 # -o smtpd_tls_req_ccert=no
456 # -o smtpd_tls_security_level=encrypt
457 # -o smtpd_tls_wrappermode=yes
458 #pickup fifo n - - 60 1 pickup
459 # -o cleanup_service_name=pre-cleanup
460 # -o content_filter=amavis:[127.0.0.1]:10024
461 #pre-cleanup unix n - - - 0 cleanup
462 # -o virtual_alias_maps=
463 #cleanup unix n - - - 0 cleanup
464 # -o mime_header_checks=
465 # -o nested_header_checks=
466 # -o body_checks=
467 # -o header_checks=
468 #-- SYMPA begin
469 #sympa unix - n n - - pipe
470 # flags=R user=sympa argv=/usr/lib/sympa/bin/queue ''${recipient}
471 #sympabounce unix - n n - - pipe
472 # flags=R user=sympa argv=/usr/lib/sympa/bin/bouncequeue ''${recipient}
473 #-- SYMPA end
474 '';
475 #noclue unix - n n - - pipe
476 # flags=q user=noclue argv=/usr/local/bin/noclue-delivery ${recipient} ${sender}
477 };
478 }