diff options
Diffstat (limited to 'hosts/surtr/email/default.nix')
-rw-r--r-- | hosts/surtr/email/default.nix | 101 |
1 files changed, 28 insertions, 73 deletions
diff --git a/hosts/surtr/email/default.nix b/hosts/surtr/email/default.nix index 49f156eb..da1c005d 100644 --- a/hosts/surtr/email/default.nix +++ b/hosts/surtr/email/default.nix | |||
@@ -2,34 +2,7 @@ | |||
2 | 2 | ||
3 | with lib; | 3 | with lib; |
4 | 4 | ||
5 | let | 5 | { |
6 | postfix_map = tableType: tableName: "${tableType}:/run/postfix/maps/${tableName}"; | ||
7 | postfix_hash = postfix_map "hash"; | ||
8 | in { | ||
9 | options = { | ||
10 | services.postfix.mapFilesRun = mkOption { | ||
11 | type = types.attrsOf (types.either types.path (types.submodule { | ||
12 | options = { | ||
13 | type = mkOption { | ||
14 | type = types.str; | ||
15 | default = "hash"; | ||
16 | }; | ||
17 | |||
18 | path = mkOption { | ||
19 | type = types.nullOr types.path; | ||
20 | default = null; | ||
21 | }; | ||
22 | |||
23 | text = mkOption { | ||
24 | type = types.nullOr types.lines; | ||
25 | default = null; | ||
26 | }; | ||
27 | }; | ||
28 | })); | ||
29 | default = {}; | ||
30 | }; | ||
31 | }; | ||
32 | |||
33 | config = { | 6 | config = { |
34 | services.postfix = { | 7 | services.postfix = { |
35 | enable = true; | 8 | enable = true; |
@@ -41,25 +14,9 @@ in { | |||
41 | sslCert = "/run/credentials/postfix.service/surtr.yggdrasil.li.pem"; | 14 | sslCert = "/run/credentials/postfix.service/surtr.yggdrasil.li.pem"; |
42 | sslKey = "/run/credentials/postfix.service/surtr.yggdrasil.li.key.pem"; | 15 | sslKey = "/run/credentials/postfix.service/surtr.yggdrasil.li.key.pem"; |
43 | networks = ["127.0.0.0/8" "[::ffff:127.0.0.0]/104" "[::1]/128" "10.141.0.0/16"]; | 16 | networks = ["127.0.0.0/8" "[::ffff:127.0.0.0]/104" "[::1]/128" "10.141.0.0/16"]; |
44 | mapFilesRun = { | 17 | config = let |
45 | "relay_ccert" = { text = ""; }; | 18 | relay_ccert = "texthash:${pkgs.writeText "relay_ccert" ""}"; |
46 | "sni" = { text = '' | 19 | in { |
47 | bouncy.email /run/credentials/postfix.service/bouncy.email.sni.pem | ||
48 | mailin.bouncy.email /run/credentials/postfix.service/mailin.bouncy.email.sni.pem | ||
49 | mailsub.bouncy.email /run/credentials/postfix.service/mailsub.bouncy.email.sni.pem | ||
50 | .bouncy.email /run/credentials/postfix.service/bouncy.email.sni.pem | ||
51 | '';}; | ||
52 | "esmtp_access" = { type = "cidr"; text = '' | ||
53 | # Allow DSN requests from local subnet only | ||
54 | 192.168.0.0/16 silent-discard | ||
55 | 172.16.0.0/12 silent-discard | ||
56 | 10.0.0.0/8 silent-discard | ||
57 | 0.0.0.0/0 silent-discard, dsn | ||
58 | fd00::/8 silent-discard | ||
59 | ::/0 silent-discard, dsn | ||
60 | '';}; | ||
61 | }; | ||
62 | config = { | ||
63 | #the dh params | 20 | #the dh params |
64 | smtpd_tls_dh1024_param_file = toString config.security.dhparams.params."postfix-1024".path; | 21 | smtpd_tls_dh1024_param_file = toString config.security.dhparams.params."postfix-1024".path; |
65 | smtpd_tls_dh512_param_file = toString config.security.dhparams.params."postfix-512".path; | 22 | smtpd_tls_dh512_param_file = toString config.security.dhparams.params."postfix-512".path; |
@@ -89,7 +46,12 @@ in { | |||
89 | smtp_tls_security_level = "dane"; | 46 | smtp_tls_security_level = "dane"; |
90 | smtp_dns_support_level = "dnssec"; | 47 | smtp_dns_support_level = "dnssec"; |
91 | 48 | ||
92 | tls_server_sni_maps = postfix_hash "sni"; | 49 | tls_server_sni_maps = ''cidr:${pkgs.writeText "sni" '' |
50 | bouncy.email /run/credentials/postfix.service/bouncy.email.sni.pem | ||
51 | mailin.bouncy.email /run/credentials/postfix.service/mailin.bouncy.email.sni.pem | ||
52 | mailsub.bouncy.email /run/credentials/postfix.service/mailsub.bouncy.email.sni.pem | ||
53 | .bouncy.email /run/credentials/postfix.service/bouncy.email.sni.pem | ||
54 | ''}''; | ||
93 | 55 | ||
94 | local_recipient_maps = ""; | 56 | local_recipient_maps = ""; |
95 | 57 | ||
@@ -107,7 +69,7 @@ in { | |||
107 | "reject_non_fqdn_recipient" | 69 | "reject_non_fqdn_recipient" |
108 | "reject_unknown_recipient_domain" | 70 | "reject_unknown_recipient_domain" |
109 | "permit_mynetworks" | 71 | "permit_mynetworks" |
110 | "check_ccert_access ${postfix_hash "relay_ccert"}" | 72 | "check_ccert_access ${relay_ccert}" |
111 | "reject_non_fqdn_helo_hostname" | 73 | "reject_non_fqdn_helo_hostname" |
112 | "reject_invalid_helo_hostname" | 74 | "reject_invalid_helo_hostname" |
113 | "reject_unauth_destination" | 75 | "reject_unauth_destination" |
@@ -117,7 +79,7 @@ in { | |||
117 | 79 | ||
118 | smtpd_relay_restrictions = [ | 80 | smtpd_relay_restrictions = [ |
119 | "permit_mynetworks" | 81 | "permit_mynetworks" |
120 | "check_ccert_access ${postfix_hash "relay_ccert"}" | 82 | "check_ccert_access ${relay_ccert}" |
121 | "reject_unauth_destination" | 83 | "reject_unauth_destination" |
122 | ]; | 84 | ]; |
123 | 85 | ||
@@ -137,7 +99,15 @@ in { | |||
137 | maximal_queue_lifetime = "100m"; | 99 | maximal_queue_lifetime = "100m"; |
138 | bounce_queue_lifetime = "20m"; | 100 | bounce_queue_lifetime = "20m"; |
139 | 101 | ||
140 | smtpd_discard_ehlo_keyword_address_maps = postfix_map "cidr" "esmtp_access"; | 102 | smtpd_discard_ehlo_keyword_address_maps = "cidr:${pkgs.writeText "esmtp_access" '' |
103 | # Allow DSN requests from local subnet only | ||
104 | 192.168.0.0/16 silent-discard | ||
105 | 172.16.0.0/12 silent-discard | ||
106 | 10.0.0.0/8 silent-discard | ||
107 | 0.0.0.0/0 silent-discard, dsn | ||
108 | fd00::/8 silent-discard | ||
109 | ::/0 silent-discard, dsn | ||
110 | ''}"; | ||
141 | 111 | ||
142 | sender_canonical_maps = "tcp:localhost:${toString config.services.postsrsd.forwardPort}"; | 112 | sender_canonical_maps = "tcp:localhost:${toString config.services.postsrsd.forwardPort}"; |
143 | sender_canonical_classes = "envelope_sender"; | 113 | sender_canonical_classes = "envelope_sender"; |
@@ -204,27 +174,12 @@ in { | |||
204 | "surtr.yggdrasil.li" = {}; | 174 | "surtr.yggdrasil.li" = {}; |
205 | }; | 175 | }; |
206 | 176 | ||
207 | systemd.services.postfix = { | 177 | systemd.services.postfix.serviceConfig.LoadCredential = [ |
208 | preStart = concatStringsSep "\n" (mapAttrsToList (to: from: let | 178 | "surtr.yggdrasil.li.key.pem:${config.security.acme.certs."surtr.yggdrasil.li".directory}/key.pem" |
209 | cont = {type, path, text}: assert !(isNull path && isNull text); let | 179 | "surtr.yggdrasil.li.pem:${config.security.acme.certs."surtr.yggdrasil.li".directory}/fullchain.pem" |
210 | path' = if isNull path then pkgs.writeText to text else path; | 180 | "bouncy.email.sni.pem:${config.security.acme.certs."bouncy.email".directory}/sni.pem" |
211 | in '' | 181 | "mailin.bouncy.email.sni.pem:${config.security.acme.certs."mailin.bouncy.email".directory}/sni.pem" |
212 | ln -sf ${path'} /run/postfix/maps/${to} | 182 | "mailsub.bouncy.email.sni.pem:${config.security.acme.certs."mailsub.bouncy.email".directory}/sni.pem" |
213 | postmap ${type}:/run/postfix/maps/${to} | 183 | ]; |
214 | ''; | ||
215 | in if builtins.isPath from then cont { path = from; } else cont from | ||
216 | ) config.services.postfix.mapFilesRun); | ||
217 | |||
218 | serviceConfig = { | ||
219 | RuntimeDirectory = ["postfix/maps"]; | ||
220 | LoadCredential = [ | ||
221 | "surtr.yggdrasil.li.key.pem:${config.security.acme.certs."surtr.yggdrasil.li".directory}/key.pem" | ||
222 | "surtr.yggdrasil.li.pem:${config.security.acme.certs."surtr.yggdrasil.li".directory}/fullchain.pem" | ||
223 | "bouncy.email.sni.pem:${config.security.acme.certs."bouncy.email".directory}/sni.pem" | ||
224 | "mailin.bouncy.email.sni.pem:${config.security.acme.certs."mailin.bouncy.email".directory}/sni.pem" | ||
225 | "mailsub.bouncy.email.sni.pem:${config.security.acme.certs."mailsub.bouncy.email".directory}/sni.pem" | ||
226 | ]; | ||
227 | }; | ||
228 | }; | ||
229 | }; | 184 | }; |
230 | } | 185 | } |