summaryrefslogtreecommitdiff
path: root/hosts/surtr
diff options
context:
space:
mode:
Diffstat (limited to 'hosts/surtr')
-rw-r--r--hosts/surtr/email/default.nix21
-rw-r--r--hosts/surtr/postgresql.nix37
2 files changed, 51 insertions, 7 deletions
diff --git a/hosts/surtr/email/default.nix b/hosts/surtr/email/default.nix
index 2ddff519..57883864 100644
--- a/hosts/surtr/email/default.nix
+++ b/hosts/surtr/email/default.nix
@@ -37,7 +37,7 @@ in {
37 services.postfix = { 37 services.postfix = {
38 enable = true; 38 enable = true;
39 hostname = "surtr.yggdrasil.li"; 39 hostname = "surtr.yggdrasil.li";
40 recipientDelimiter = "+"; 40 recipientDelimiter = "";
41 setSendmail = true; 41 setSendmail = true;
42 postmasterAlias = ""; rootAlias = ""; extraAliases = ""; 42 postmasterAlias = ""; rootAlias = ""; extraAliases = "";
43 destination = []; 43 destination = [];
@@ -100,6 +100,11 @@ in {
100 "reject_unauth_pipelining" 100 "reject_unauth_pipelining"
101 "reject_non_fqdn_recipient" 101 "reject_non_fqdn_recipient"
102 "reject_unknown_recipient_domain" 102 "reject_unknown_recipient_domain"
103 "check_recipient_access pgsql:${pkgs.writeText "check_recipient_access.cf" ''
104 hosts = postgresql:///email
105 dbname = email
106 query = SELECT action FROM virtual_mailbox_access WHERE lookup = '%s'
107 ''}"
103 "permit_mynetworks" 108 "permit_mynetworks"
104 "check_ccert_access ${relay_ccert}" 109 "check_ccert_access ${relay_ccert}"
105 "reject_non_fqdn_helo_hostname" 110 "reject_non_fqdn_helo_hostname"
@@ -156,7 +161,8 @@ in {
156 dbname = email 161 dbname = email
157 query = SELECT 1 FROM virtual_mailbox_mapping WHERE lookup = '%s' 162 query = SELECT 1 FROM virtual_mailbox_mapping WHERE lookup = '%s'
158 ''}''; 163 ''}'';
159 virtual_transport = "lmtp:unix:/run/postfix/dovecot-lmtp"; 164 dvlmtp_destination_recipient_limit = "1";
165 virtual_transport = "dvlmtp:unix:/run/postfix/dovecot-lmtp";
160 }; 166 };
161 masterConfig = { 167 masterConfig = {
162 smtps = { 168 smtps = {
@@ -174,6 +180,12 @@ in {
174 "-o" ''smtpd_milters=${config.services.opendkim.socket}'' 180 "-o" ''smtpd_milters=${config.services.opendkim.socket}''
175 ]; 181 ];
176 }; 182 };
183 dvlmtp = {
184 command = "lmtp";
185 args = [
186 "flags=DORX"
187 ];
188 };
177 }; 189 };
178 }; 190 };
179 191
@@ -375,7 +387,7 @@ in {
375 args = ${pkgs.writeText "dovecot-sql.conf" '' 387 args = ${pkgs.writeText "dovecot-sql.conf" ''
376 driver = pgsql 388 driver = pgsql
377 connect = dbname=email 389 connect = dbname=email
378 user_query = SELECT DISTINCT ON (local IS NULL) "user", quota_rule, 'dovecot2' as uid, 'dovecot2' as gid FROM lmtp_mapping WHERE (local = '%n' AND domain = '%d') OR (local IS NULL AND domain = '%d') ORDER BY (local IS NULL) ASC 390 user_query = SELECT DISTINCT ON (extension IS NULL, local IS NULL) "user", quota_rule, 'dovecot2' as uid, 'dovecot2' as gid FROM lmtp_mapping WHERE CASE WHEN extension IS NOT NULL AND local IS NOT NULL THEN ('%n' :: citext) = local || '+' || extension AND domain = ('%d' :: citext) WHEN local IS NOT NULL THEN (local = ('%n' :: citext) OR ('%n' :: citext) ILIKE local || '+%%') AND domain = ('%d' :: citext) WHEN extension IS NOT NULL THEN ('%n' :: citext) ILIKE '%%+' || extension AND domain = ('%d' :: citext) ELSE domain = ('%d' :: citext) END ORDER BY (extension IS NULL) ASC, (local IS NULL) ASC
379 ''} 391 ''}
380 392
381 skip = never 393 skip = never
@@ -387,7 +399,8 @@ in {
387 mail_plugins = $mail_plugins quota 399 mail_plugins = $mail_plugins quota
388 mailbox_list_index = yes 400 mailbox_list_index = yes
389 postmaster_address = postmaster@yggdrasil.li 401 postmaster_address = postmaster@yggdrasil.li
390 recipient_delimiter = + 402 recipient_delimiter =
403 auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-+_@
391 404
392 service lmtp { 405 service lmtp {
393 vsz_limit = 1G 406 vsz_limit = 1G
diff --git a/hosts/surtr/postgresql.nix b/hosts/surtr/postgresql.nix
index abd2cb26..a5e93ecf 100644
--- a/hosts/surtr/postgresql.nix
+++ b/hosts/surtr/postgresql.nix
@@ -1,4 +1,4 @@
1{ pkgs, sources, ... }: 1{ pkgs, sources, config, ... }:
2let 2let
3 versioning = sources.psql-versioning.src; 3 versioning = sources.psql-versioning.src;
4in { 4in {
@@ -22,8 +22,19 @@ in {
22 ''; 22 '';
23 }; 23 };
24 24
25 systemd.services.postgresql = { 25 systemd.services.migrate-postgresql = {
26 postStart = '' 26 after = [ "postgresql.service" ];
27 bindsTo = [ "postgresql.service" ];
28 wantedBy = [ "postgresql.service" ];
29
30 serviceConfig = {
31 Type = "oneshot";
32 inherit (config.systemd.services.postgresql.serviceConfig) User Group;
33 RemainAfterExit = true;
34 };
35
36 path = [ config.services.postgresql.package ];
37 script = ''
27 psql email postgres -eXf ${pkgs.writeText "email.sql" '' 38 psql email postgres -eXf ${pkgs.writeText "email.sql" ''
28 \i ${versioning + "/install.versioning.sql"} 39 \i ${versioning + "/install.versioning.sql"}
29 40
@@ -78,6 +89,26 @@ in {
78 CREATE VIEW imap_user ("user", quota_rule) AS SELECT mailbox AS "user", quota_rule FROM mailbox_quota_rule; 89 CREATE VIEW imap_user ("user", quota_rule) AS SELECT mailbox AS "user", quota_rule FROM mailbox_quota_rule;
79 CREATE VIEW lmtp_mapping ("user", quota_rule, local, domain) AS SELECT mailbox_quota_rule.mailbox AS "user", quota_rule, local, domain FROM mailbox_quota_rule INNER JOIN mailbox_mapping ON mailbox_quota_rule.id = mailbox_mapping.mailbox; 90 CREATE VIEW lmtp_mapping ("user", quota_rule, local, domain) AS SELECT mailbox_quota_rule.mailbox AS "user", quota_rule, local, domain FROM mailbox_quota_rule INNER JOIN mailbox_mapping ON mailbox_quota_rule.id = mailbox_mapping.mailbox;
80 COMMIT; 91 COMMIT;
92
93 BEGIN;
94 SELECT _v.register_patch('003-extensions', ARRAY['000-base', '002-citext'], null);
95
96 ALTER TABLE mailbox_mapping ADD COLUMN extension citext CHECK (CASE WHEN extension IS NOT NULL THEN extension NOT LIKE '%+%' ELSE true END);
97
98 DROP VIEW virtual_mailbox_mapping;
99 DROP VIEW lmtp_mapping;
100
101 CREATE VIEW virtual_mailbox_mapping (lookup) AS SELECT (CASE WHEN local IS NULL THEN ''' ELSE local END) || (CASE WHEN extension IS NULL THEN ''' ELSE '+' || extension END) || '@' || domain AS lookup FROM mailbox_mapping WHERE mailbox IS NOT NULL;
102 CREATE VIEW virtual_mailbox_access (lookup, action) AS SELECT (CASE WHEN local IS NULL THEN ''' ELSE local END) || (CASE WHEN extension IS NULL THEN ''' ELSE '+' || extension END) || '@' || domain AS lookup, CASE WHEN mailbox IS NULL THEN 'REJECT' ELSE 'DUNNO' END AS action FROM mailbox_mapping;
103 CREATE VIEW lmtp_mapping ("user", quota_rule, local, extension, domain) AS SELECT mailbox_quota_rule.mailbox AS "user", quota_rule, local, extension, domain FROM mailbox_quota_rule INNER JOIN mailbox_mapping ON mailbox_quota_rule.id = mailbox_mapping.mailbox;
104 COMMIT;
105
106 BEGIN;
107 SELECT _v.register_patch('004-cascade', ARRAY['000-base'], null);
108
109 ALTER TABLE mailbox_mapping DROP CONSTRAINT mailbox_mapping_mailbox_fkey;
110 ALTER TABLE mailbox_mapping ADD CONSTRAINT mailbox_mapping_mailbox_fkey FOREIGN KEY (mailbox) REFERENCES mailbox(id) ON DELETE CASCADE ON UPDATE RESTRICT;
111 COMMIT;
81 ''} 112 ''}
82 ''; 113 '';
83 }; 114 };