]> Git — Sourcephile - sourcephile-nix.git/blob - servers/mermet/postfix.nix
postfix: fix and clarify mail routing
[sourcephile-nix.git] / servers / mermet / postfix.nix
1 { pkgs, lib, config, ... }:
2 let
3 inherit (builtins) attrNames concatStringsSep readFile toPath;
4 inherit (builtins.extraBuiltins) pass;
5 inherit (lib) types;
6 inherit (pkgs.lib) loadFile unlines unwords unlinesAttrs;
7 inherit (config) networking users;
8 inherit (config.services) postfix dovecot2 openldap;
9 in
10 {
11 imports = [
12 postfix/sourcephile.fr.nix
13 ];
14 options = {
15 services.postfix.submissions.smtpd_sender_login_maps = lib.mkOption {
16 type = types.listOf types.str;
17 default = [];
18 };
19 };
20 config = {
21 systemd.services.postfix.after = [
22 "openldap.service"
23 ];
24 services.postfix = {
25 enable = true;
26 networksStyle = "host";
27 hostname = "localhost";
28 domain = "localdomain";
29 origin = "localhost.localdomain";
30 destination = [
31 "localhost"
32 "localhost.localdomain"
33 networking.hostName
34 "${networking.hostName}.${networking.domain}"
35 ];
36 postmasterAlias = "root";
37 rootAlias = "root@${networking.domain}";
38 sslCert = loadFile (../../../sec/openssl + "/${networking.domain}/cert.self-signed.pem");
39 sslKey = "/run/keys/${networking.domain}.key.pem";
40 networks = [
41 "127.0.0.0/8"
42 "[::1]/128"
43 ];
44 # Parse the extension in email address, eg. contact+extension@
45 recipientDelimiter = "+";
46 config = {
47 debug_peer_level = "4";
48 debug_peer_list = [
49 #"chomsky.autogeree.net"
50 #"localhost"
51 ];
52
53 #
54 # Sending to the world
55 #
56 # Appending .domain is the MUA's job
57 append_dot_mydomain = false;
58 smtp_body_checks = "";
59 #smtp_cname_overrides_servername = false;
60 smtp_connect_timeout = "60s";
61 #smtp_header_checks = "regexp:/var/lib/postfix/smtp_header_checks";
62 smtp_mime_header_checks = "";
63 smtp_nested_header_checks = "";
64 smtp_tls_exclude_ciphers = [ "ADH" "MD5" "CAMELLIA" "SEED" "3DES" "DES" "RC4" "eNULL" "aNULL" ];
65 #smtp_tls_fingerprint_digest = "sha1";
66 smtp_tls_loglevel = "1";
67 #smtp_tls_note_starttls_offer = true;
68 #smtp_tls_policy_maps = "hash:/var/lib/postfix/conf/tls_policy";
69 # Only allow TLSv* protocols
70 smtp_tls_protocols = [ "!SSLv2" "!SSLv3" ];
71 #smtp_tls_scert_verifydepth = "5";
72 #smtp_tls_secure_cert_match = [ "nexthop" "dot-nexthop" ];
73 smtp_tls_security_level = "may";
74 smtp_tls_session_cache_database = "btree:$data_directory/smtp_tls_session_cache";
75 #smtp_tls_session_cache_timeout = "3600s";
76 #smtp_tls_verify_cert_match = "hostname";
77
78 #
79 # Receiving from the world
80 #
81 message_size_limit = "20480000";
82 maximal_queue_lifetime = "5d";
83 default_extra_recipient_limit = "5000";
84 line_length_limit = "2048";
85 duplicate_filter_limit = "5000";
86 # Stops mail from poorly written software
87 strict_rfc821_envelopes = true;
88 mime_header_checks = [];
89 milter_header_checks = [];
90 nested_header_checks = [];
91 body_checks = [];
92 content_filter = "";
93 permit_mx_backup_networks = [];
94 propagate_unmatched_extensions = [ "canonical" "virtual" "alias" ];
95 #masquerade_classes = [ "envelope_sender" "header_sender" "header_recipient" ];
96 #masquerade_domains = "";
97 #masquerade_exceptions = "root";
98 queue_minfree = "0";
99 # Stops some techniques used to harvest email addresses
100 disable_vrfy_command = true;
101 enable_long_queue_ids = false;
102 # Useful to test restrictions
103 smtpd_authorized_xclient_hosts = "127.0.0.1";
104 smtpd_banner = "${networking.hostName} ESMTP $mail_name (NixOS)";
105 smtpd_client_connection_count_limit = "50";
106 smtpd_client_connection_rate_limit = "0";
107 smtpd_client_event_limit_exceptions = "$mynetworks";
108 smtpd_client_message_rate_limit = "0";
109 smtpd_client_new_tls_session_rate_limit = "0";
110 smtpd_client_port_logging = false;
111 smtpd_client_recipient_rate_limit = "0";
112 # Ban 5 sec on error
113 smtpd_error_sleep_time = "5";
114 # Needed to enforce reject_unknown_helo_hostname
115 smtpd_helo_required = true;
116 smtpd_helo_restrictions = [
117 "reject_invalid_helo_hostname"
118 "reject_non_fqdn_helo_hostname"
119 # Don't talk to mail systems that don't know their own hostname.
120 "reject_unknown_helo_hostname"
121 "permit"
122 ];
123 smtpd_sender_restrictions = [
124 "reject_non_fqdn_sender"
125 "permit"
126 ];
127 # Check the RCPT TO, before smtpd_recipient_restrictions
128 smtpd_relay_restrictions = [
129 "permit_mynetworks"
130 # Check the recipient's address in virtual_mailbox_domains and virtual_mailbox_maps
131 "permit_auth_destination"
132 # The world is only authorized to use our relay for the above destinations.
133 "reject"
134 ];
135 smtpd_recipient_restrictions = [
136 "reject_non_fqdn_recipient"
137 "reject_unknown_recipient_domain"
138 "reject_unlisted_recipient"
139 # WARNING: verify(8) has a cache, dumpable if verify(8) is stopped, with:
140 # postmap -s btree:/var/lib/postfix/data/verify_cache
141 "reject_unverified_recipient"
142 "permit"
143 ];
144 # Trust the verify database
145 unverified_recipient_reject_code = "550";
146 smtpd_client_restrictions = [];
147 smtpd_data_restrictions = [
148 # Force the smtpd's client to wait OK before sending
149 "reject_unauth_pipelining"
150 "permit"
151 ];
152 smtpd_end_of_data_restrictions = [
153 # Enforce mail volume quota via policy service callouts.
154 #check_policy_service unix:private/policy
155 ];
156 #smtpd_milters = "";
157 smtpd_peername_lookup = true;
158 smtpd_recipient_limit = "5000";
159 smtpd_recipient_overshoot_limit = "5000";
160 #smtpd_restriction_classes = "";
161 #smtpd_sasl_auth_enable = true;
162 #smtpd_sasl_path = "private/auth";
163 #smtpd_sasl_security_options = "noanonymous";
164 #smtpd_sasl_type = "dovecot";
165 smtpd_starttls_timeout = "300s";
166 #smtpd_tls_always_issue_session_ids = true;
167 #smtpd_tls_CApath = "/etc/postfix/x509/ca/";
168 smtpd_tls_ask_ccert = false;
169 #smtpd_tls_ccert_verifydepth = "5";
170 smtpd_tls_ciphers = "high";
171 smtpd_tls_eecdh_grade = "ultra";
172 # Disable weak ciphers as reported by https://ssl-tools.net
173 # https://serverfault.com/questions/744168/how-to-disable-rc4-on-postfix
174 smtpd_tls_exclude_ciphers = [ "ADH" "MD5" "CAMELLIA" "SEED" "3DES" "DES" "RC4" "eNULL" "aNULL" ];
175 smtpd_tls_fingerprint_digest = "sha512";
176 # Log only a summary message on TLS handshake completion
177 smtpd_tls_loglevel = "1";
178 smtpd_tls_mandatory_ciphers = "high";
179 smtpd_tls_mandatory_protocols = [ "!SSLv2" "!SSLv3" ];
180 # Only allow TLSv*
181 smtpd_tls_protocols = [ "!SSLv2" "!SSLv3" ];
182 #smtpd_tls_received_header = false;
183 smtpd_tls_req_ccert = false;
184 # Postfix 2.3 and later
185 # encrypt
186 # Mandatory TLS encryption: announce STARTTLS support to SMTP clients, and require that clients use TLS
187 # encryption. According to [1720]RFC 2487 this MUST NOT be applied in case of a publicly-referenced
188 # SMTP server. Instead, this option should be used only on dedicated servers.
189 smtpd_tls_security_level = "may";
190 smtpd_tls_session_cache_database = "btree:$data_directory/smtpd_tls_session_cache";
191 #smtpd_tls_session_cache_timeout = "3600s";
192
193 relayhost = [];
194 #relay_clientcerts = hash:/var/lib/postfix/conf/relay_clientcerts
195 # This is where to put backup MX domains
196 relay_domains = [];
197 relay_recipient_maps = [];
198
199 # postconf(5) discourages to change this
200 #tls_high_cipherlist = "AES256-SHA";
201 #tls_random_bytes = "32";
202 # Must not be in a chroot
203 #tls_random_exchange_name = "$data_directory/prng_exch";
204 #tls_random_prng_update_period = "3600s";
205 #tls_random_reseed_period = "3600s";
206 # Use a non blocking source of randomness
207 tls_random_source = "dev:/dev/urandom";
208
209 # Only explicitely aliased accounts have a mail, not all the passwd
210 local_recipient_maps = "$alias_maps";
211 # Note that the local transport rewrites the envelope recipient
212 # according to the alias_maps, and thus the aliasing is transparent
213 # to the nexthop (eg. dovecot)
214 #local_transport = local:$myhostname
215 # No console bell on new mail
216 biff = false;
217 forward_path = [
218 /*
219 "$home/.forward''${recipient_delimiter}''${extension}"
220 "$home/.forward"
221 */
222 ];
223
224 # Filled by the postfix/*.nix
225 virtual_mailbox_domains = [];
226 virtual_mailbox_maps = [];
227 virtual_transport = "lmtp:unix:private/dovecot-lmtp";
228
229 # There is no fallback
230 fallback_transport = "";
231 };
232 virtualMapType = "hash";
233 masterConfig =
234 let
235 mkVal = value:
236 if lib.isList value
237 then concatStringsSep "," value
238 else
239 if value == true then "yes"
240 else if value == false then "no"
241 else toString value;
242 mkKeyVal = opt: val: [ "-o" (opt + "=" + mkVal val) ];
243 mkArgs = args: lib.concatLists (lib.mapAttrsToList mkKeyVal args);
244 in {
245 # Implicit TLS on port 465
246 # https://tools.ietf.org/html/rfc8314#section-3.3
247 submissions = {
248 type = "inet";
249 private = false;
250 command = "smtpd";
251 args = mkArgs {
252 syslog_name = "postfix/submissions";
253 # Implicit TLS, not STARTTLS
254 smtpd_tls_wrappermode = true;
255 smtpd_tls_mandatory_protocols = [ "!SSLv2" "!SSLv3" "!TLSv1.1" "!TLSv1.2" ];
256 milter_macro_daemon_name = "ORIGINATING";
257 smtpd_client_restrictions = [
258 "permit_sasl_authenticated"
259 "reject"
260 ];
261 smtpd_relay_restrictions = [
262 "reject_unauth_destination"
263 # SASL authorizes to send to the world
264 "permit"
265 ];
266 smtpd_sasl_auth_enable = true;
267 smtpd_sasl_type = "dovecot";
268 smtpd_sasl_path = "private/auth";
269 smtpd_sasl_local_domain = "$myhostname";
270 # Offer SASL authentication only after a TLS-encrypted session has been established
271 smtpd_tls_auth_only = true;
272 smtpd_sasl_tls_security_options = [ "noanonymous" ];
273 # Do not put SASL logins in mail headers
274 smtpd_sasl_authenticated_header = false;
275 # Who cares about (old) Outlook
276 broken_sasl_auth_clients = false;
277 smtpd_sender_login_maps = postfix.submissions.smtpd_sender_login_maps;
278 smtpd_sender_restrictions = [
279 "reject_non_fqdn_sender"
280 # Check that the SASL user is using only its own
281 # mail addresses on the envelope, as indicated in smtpd_sender_login_maps
282 "reject_sender_login_mismatch"
283 "permit"
284 ];
285 # No X.509 certificates for users, for now
286 smtpd_tls_ask_ccert = false;
287 smtpd_tls_ccert_verifydepth = 0;
288 smtpd_tls_loglevel = 1;
289 smtpd_tls_req_ccert = false;
290 cleanup_service_name = "submissions-header-cleanup";
291 };
292 };
293 submissions-header-cleanup = {
294 type = "unix";
295 private = false;
296 maxproc = 0;
297 command = "cleanup";
298 args = mkArgs {
299 header_checks = "pcre:" + pkgs.writeText "submission_header_cleanup_rules" ''
300 # Removes sensitive headers from mails handed in via the submission or smtps port.
301 # See https://thomas-leister.de/mailserver-debian-stretch/
302 # Uses "pcre" style regex.
303
304 /^Received:/ IGNORE
305 /^User-Agent:/ IGNORE
306 /^X-Enigmail:/ IGNORE
307 /^X-Mailer:/ IGNORE
308 /^X-Originating-IP:/ IGNORE
309 '';
310 };
311 };
312 };
313 extraMasterConf = ''
314 #spfcheck unix - n n - 0 spawn
315 # user=policyd-spf argv=/usr/sbin/postfix-policyd-spf-perl
316 # -o smtpd_sender_restrictions=reject_sender_login_mismatch
317 # -o smtpd_sender_login_maps=hash:/etc/postfix/vaccounts
318 # -o cleanup_service_name=submissions-header-cleanup
319 #spfcheck unix - n n - 0 spawn
320 # user=policyd-spf argv=/usr/bin/postfix-policyd-spf-perl
321 #uucp unix - n n - - pipe
322 # flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
323 #smtp inet n - - - - smtpd
324 # -o cleanup_service_name=pre-cleanup
325 # -o content_filter=amavis:[127.0.0.1]:10024
326 # -o smtpd_sender_restrictions=reject_unauth_pipelining,reject_non_fqdn_sender,permit
327 # -o receive_override_options=no_address_mappings
328 #amavis unix - - n - 2 lmtp
329 # -o lmtp_data_done_timeout=1200
330 # -o lmtp_send_xforward_command=yes
331 # -o lmtp_tls_note_starttls_offer=no
332 #127.0.0.1:10025 inet n - n - - smtpd
333 # -o content_filter=
334 # -o local_header_rewrite_clients=
335 # -o local_recipient_maps=
336 # -o mynetworks=127.0.0.0/8
337 # -o receive_override_options=no_header_body_checks,no_milters,no_unknown_recipient_checks
338 # -o relay_recipient_maps=
339 # -o smtpd_client_connection_count_limit=0
340 # -o smtpd_client_connection_rate_limit=0
341 # -o smtpd_client_restrictions=permit_mynetworks,reject
342 # -o smtpd_data_restrictions=reject_unauth_pipelining
343 # -o smtpd_delay_reject=no
344 # -o smtpd_end_of_data_restrictions=
345 # -o smtpd_error_sleep_time=0
346 # -o smtpd_hard_error_limit=1000
347 # -o smtpd_helo_restrictions=
348 # -o smtpd_milters=
349 # -o smtpd_recipient_restrictions=permit_mynetworks,reject
350 # -o smtpd_restriction_classes=
351 # -o smtpd_sender_restrictions=
352 # -o smtpd_soft_error_limit=1001
353 # -o strict_rfc821_envelopes=yes
354 #submission inet n - - - - smtpd
355 # -o cleanup_service_name=pre-cleanup
356 # -o content_filter=amavis:[127.0.0.1]:10024
357 # -o milter_macro_daemon_name=ORIGINATING
358 # -o receive_override_options=no_address_mappings
359 # -o smtpd_sender_restrictions=permit_tls_clientcerts,reject
360 # -o smtpd_tls_ask_ccert=yes
361 # -o smtpd_tls_auth_only=yes
362 # -o smtpd_tls_ccert_verifydepth=2
363 # -o smtpd_tls_loglevel=1
364 # -o smtpd_tls_req_ccert=yes
365 # -o smtpd_tls_security_level=encrypt
366 #smtps inet n - - - - smtpd
367 # -o milter_macro_daemon_name=ORIGINATING
368 # -o smtpd_client_restrictions=permit_sasl_authenticated,reject
369 # -o smtpd_sasl_auth_enable=yes
370 # -o smtpd_tls_ask_ccert=yes
371 # -o smtpd_tls_auth_only=yes
372 # -o smtpd_tls_ccert_verifydepth=0
373 # -o smtpd_tls_loglevel=1
374 # -o smtpd_tls_req_ccert=no
375 # -o smtpd_tls_security_level=encrypt
376 # -o smtpd_tls_wrappermode=yes
377 #pickup fifo n - - 60 1 pickup
378 # -o cleanup_service_name=pre-cleanup
379 # -o content_filter=amavis:[127.0.0.1]:10024
380 #pre-cleanup unix n - - - 0 cleanup
381 # -o virtual_alias_maps=
382 #cleanup unix n - - - 0 cleanup
383 # -o mime_header_checks=
384 # -o nested_header_checks=
385 # -o body_checks=
386 # -o header_checks=
387 #-- SYMPA begin
388 #sympa unix - n n - - pipe
389 # flags=R user=sympa argv=/usr/lib/sympa/bin/queue ''${recipient}
390 #sympabounce unix - n n - - pipe
391 # flags=R user=sympa argv=/usr/lib/sympa/bin/bouncequeue ''${recipient}
392 #-- SYMPA end
393 '';
394 #noclue unix - n n - - pipe
395 # flags=q user=noclue argv=/usr/local/bin/noclue-delivery ${recipient} ${sender}
396 };
397 };
398 }