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