1 { pkgs, lib, config, ... }:
4 inherit (config) networking users;
5 inherit (config.services) postfix;
9 #postfix/autogeree.net.nix
10 #postfix/sourcephile.fr.nix
12 users.groups.acme.members = [ postfix.user ];
14 networking.nftables.ruleset = ''
15 add rule inet filter net2fw tcp dport 25 counter accept comment "SMTP"
16 add rule inet filter net2fw tcp dport 465 counter accept comment "submissions"
17 add rule inet filter fw2net meta skuid ${postfix.user} tcp dport 25 counter accept comment "SMTP"
22 networksStyle = "host";
23 hostname ="${networking.hostName}.${networking.domain}";
24 domain = networking.domain;
25 origin = "$myhostname";
28 "localhost.localdomain"
31 postmasterAlias = "root";
32 rootAlias = "root@${networking.domain}";
33 sslKey = "/var/lib/acme/${networking.domain}/key.pem";
34 sslCert = "/var/lib/acme/${networking.domain}/fullchain.pem";
40 # Parse the extension in email address, eg. contact+extension@
41 recipientDelimiter = "+";
43 debug_peer_level = "4";
45 #"chomsky.autogeree.net"
47 #"mail.sourcephile.fr"
51 # Sending to the world
53 # Appending .domain is the MUA's job
54 append_dot_mydomain = false;
55 smtp_body_checks = "";
56 #smtp_cname_overrides_servername = false;
57 smtp_connect_timeout = "60s";
58 #smtp_header_checks = "regexp:/var/lib/postfix/smtp_header_checks";
59 smtp_mime_header_checks = "";
60 smtp_nested_header_checks = "";
61 smtp_tls_exclude_ciphers = [ "ADH" "MD5" "CAMELLIA" "SEED" "3DES" "DES" "RC4" "eNULL" "aNULL" ];
62 #smtp_tls_fingerprint_digest = "sha1";
63 smtp_tls_loglevel = "1";
64 #smtp_tls_note_starttls_offer = true;
65 #smtp_tls_policy_maps = "hash:/var/lib/postfix/conf/tls_policy";
66 # Only allow TLSv* protocols
67 smtp_tls_protocols = [ "!SSLv2" "!SSLv3" ];
68 #smtp_tls_scert_verifydepth = "5";
69 #smtp_tls_secure_cert_match = [ "nexthop" "dot-nexthop" ];
70 smtp_tls_security_level = "may";
71 smtp_tls_session_cache_database = "btree:$data_directory/smtp_tls_session_cache";
72 #smtp_tls_session_cache_timeout = "3600s";
73 #smtp_tls_verify_cert_match = "hostname";
76 # Receiving from the world
78 message_size_limit = "20480000";
79 maximal_queue_lifetime = "5d";
80 default_extra_recipient_limit = "5000";
81 line_length_limit = "2048";
82 duplicate_filter_limit = "5000";
83 # Stops mail from poorly written software
84 strict_rfc821_envelopes = true;
85 mime_header_checks = [];
86 milter_header_checks = [];
87 nested_header_checks = [];
90 permit_mx_backup_networks = [];
91 propagate_unmatched_extensions = [ "canonical" "virtual" "alias" ];
92 #masquerade_classes = [ "envelope_sender" "header_sender" "header_recipient" ];
93 #masquerade_domains = "";
94 #masquerade_exceptions = "root";
96 # Stops some techniques used to harvest email addresses
97 disable_vrfy_command = true;
98 enable_long_queue_ids = false;
99 # Useful to test restrictions
100 smtpd_authorized_xclient_hosts = "127.0.0.1";
101 smtpd_banner = "$myhostname ESMTP $mail_name (NixOS)";
102 smtpd_client_connection_count_limit = "50";
103 smtpd_client_connection_rate_limit = "0";
104 smtpd_client_event_limit_exceptions = "$mynetworks";
105 smtpd_client_message_rate_limit = "0";
106 smtpd_client_new_tls_session_rate_limit = "0";
107 smtpd_client_port_logging = false;
108 smtpd_client_recipient_rate_limit = "0";
110 smtpd_error_sleep_time = "5";
111 # Needed to enforce reject_unknown_helo_hostname
112 smtpd_helo_required = true;
113 smtpd_helo_restrictions = [
114 "reject_invalid_helo_hostname"
115 "reject_non_fqdn_helo_hostname"
116 # Don't talk to mail systems that don't know their own hostname.
117 "reject_unknown_helo_hostname"
120 smtpd_client_restrictions = [
122 # Set in postfix/*.nix and used in submissions/smptd
123 # with reject_sender_login_mismatch
124 smtpd_sender_login_maps = [];
125 smtpd_sender_restrictions = [
126 "reject_non_fqdn_sender"
129 smtpd_reject_unlisted_recipient = true;
130 # Check the RCPT TO, before smtpd_recipient_restrictions
131 # Restrictions based on what is allowed or not,
132 # these are applied before smtpd_recipient_restrictions
133 smtpd_relay_restrictions = [
135 # Check the recipient's address in virtual_mailbox_domains and virtual_mailbox_maps
136 "permit_auth_destination"
137 # The world is only authorized to use our relay for the above destinations.
140 # Restrictions based on what is working or not
141 smtpd_recipient_restrictions = [
142 # Reject if the domain is not fully qualified
143 "reject_non_fqdn_recipient"
144 # Reject if the domain is not working, even before bothering to check the address
145 "reject_unknown_recipient_domain"
146 # Reject if the address is not working
147 # WARNING: this does not work if the recipient is greylisting.
148 # WARNING: verify(8) has a cache, dumpable if verify(8) is stopped, with:
149 # postmap -s btree:/var/lib/postfix/data/verify_cache
150 #"reject_unverified_recipient"
153 # Trust the verify database
154 #unverified_recipient_reject_code = "550";
155 smtpd_data_restrictions = [
156 # Force the smtpd's client to wait OK before sending
157 "reject_unauth_pipelining"
160 smtpd_end_of_data_restrictions = [
161 # Enforce mail volume quota via policy service callouts.
162 #check_policy_service unix:private/policy
165 smtpd_peername_lookup = true;
166 smtpd_recipient_limit = "5000";
167 smtpd_recipient_overshoot_limit = "5000";
168 #smtpd_restriction_classes = "";
169 #smtpd_sasl_auth_enable = true;
170 #smtpd_sasl_path = "private/auth";
171 #smtpd_sasl_security_options = "noanonymous";
172 #smtpd_sasl_type = "dovecot";
173 smtpd_starttls_timeout = "300s";
174 #smtpd_tls_always_issue_session_ids = true;
175 #smtpd_tls_CApath = "/etc/postfix/x509/ca/";
176 smtpd_tls_ask_ccert = false;
177 #smtpd_tls_ccert_verifydepth = "5";
178 smtpd_tls_ciphers = "high";
179 smtpd_tls_eecdh_grade = "auto";
180 # Disable weak ciphers as reported by https://ssl-tools.net
181 # https://serverfault.com/questions/744168/how-to-disable-rc4-on-postfix
182 smtpd_tls_exclude_ciphers = [ "ADH" "MD5" "CAMELLIA" "SEED" "3DES" "DES" "RC4" "eNULL" "aNULL" ];
183 smtpd_tls_fingerprint_digest = "sha512";
184 # Log only a summary message on TLS handshake completion
185 smtpd_tls_loglevel = "1";
186 smtpd_tls_mandatory_ciphers = "high";
187 smtpd_tls_mandatory_protocols = [ "!SSLv2" "!SSLv3" ];
189 smtpd_tls_protocols = [ "!SSLv2" "!SSLv3" ];
190 #smtpd_tls_received_header = false;
191 smtpd_tls_req_ccert = false;
192 # Postfix 2.3 and later
194 # Mandatory TLS encryption: announce STARTTLS support to SMTP clients, and require that clients use TLS
195 # encryption. According to [1720]RFC 2487 this MUST NOT be applied in case of a publicly-referenced
196 # SMTP server. Instead, this option should be used only on dedicated servers.
197 smtpd_tls_security_level = "may";
198 smtpd_tls_session_cache_database = "btree:$data_directory/smtpd_tls_session_cache";
199 #smtpd_tls_session_cache_timeout = "3600s";
200 #smtpd_tls_chain_files =
203 #relay_clientcerts = hash:/var/lib/postfix/conf/relay_clientcerts
204 # This is where to put backup MX domains
206 relay_recipient_maps = [];
208 # Use a non blocking source of randomness
209 tls_random_source = "dev:/dev/urandom";
210 # Map each domain to a specific X.509 certificate
211 tls_server_sni_maps = "hash:/run/keys/postfix-sni";
213 # Only explicitely aliased accounts have a mail, not all the passwd
214 local_recipient_maps = "$alias_maps";
215 # Note that the local transport rewrites the envelope recipient
216 # according to the alias_maps, and thus the aliasing is transparent
217 # to the nexthop (eg. dovecot)
218 #local_transport = local:$myhostname
219 # No console bell on new mail
223 "$home/.forward''${recipient_delimiter}''${extension}"
228 # Filled by the postfix/*.nix
229 virtual_mailbox_domains = [];
230 # Completed by the postfix/*.nix
231 virtual_mailbox_maps = [
232 "hash:/etc/postfix/virtual"
234 #virtual_transport = "lmtp:unix:private/dovecot-lmtp";
236 dovecot_destination_recipient_limit = "1";
237 virtual_transport = "dovecot";
240 # There is no fallback
241 fallback_transport = "";
243 virtualMapType = "hash";
248 then lib.concatStringsSep "," value
250 if value == true then "yes"
251 else if value == false then "no"
253 mkKeyVal = opt: val: [ "-o" (opt + "=" + mkVal val) ];
254 mkArgs = args: lib.concatLists (lib.mapAttrsToList mkKeyVal args);
258 cleanup_service_name = "submissions-header-cleanup";
262 # Implicit TLS on port 465
263 # https://tools.ietf.org/html/rfc8314#section-3.3
269 syslog_name = "postfix/submissions";
270 # Implicit TLS, not STARTTLS
271 smtpd_tls_wrappermode = true;
272 smtpd_tls_mandatory_protocols = [
274 # FIXME: to be removed when K-9 Mail will support TLSv1.3,
275 # K-9 Mail 5.600 does not.
278 milter_macro_daemon_name = "ORIGINATING";
279 smtpd_helo_restrictions = [
280 "permit_sasl_authenticated"
281 ] ++ postfix.config.smtpd_helo_restrictions;
282 smtpd_relay_restrictions = [
283 # SASL authorizes to send to the world
284 "permit_sasl_authenticated"
287 smtpd_sasl_auth_enable = true;
288 smtpd_sasl_type = "dovecot";
289 smtpd_sasl_path = "private/auth";
290 smtpd_sasl_local_domain = "";
291 # Offer SASL authentication only after a TLS-encrypted session has been established
292 smtpd_tls_auth_only = true;
293 smtpd_sasl_tls_security_options = [ "noanonymous" ];
294 # Do not put SASL logins in mail headers
295 smtpd_sasl_authenticated_header = false;
296 # Who cares about (old) Outlook
297 broken_sasl_auth_clients = false;
298 smtpd_sender_restrictions = [
299 "reject_non_fqdn_sender"
300 # Check that the SASL user is using only its own
301 # mail addresses on the envelope, as indicated in smtpd_sender_login_maps
302 "reject_sender_login_mismatch"
305 # No X.509 certificates for users, for now
306 smtpd_tls_ask_ccert = false;
307 smtpd_tls_ccert_verifydepth = 0;
308 smtpd_tls_loglevel = 1;
309 smtpd_tls_req_ccert = false;
310 cleanup_service_name = "submissions-header-cleanup";