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