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