blob: bd2681acabea977f010e80f5a0064df6dfae54da (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
{ config, ... }: let
ipv6 = "2001:470:ee65::1337";
domain = config.global.userdata.domain;
username = config.global.userdata.name;
email = [
"${username}@${domain}"
"official@${domain}"
"postmaster@${domain}"
"hostmaster@${domain}"
];
credentials_directory = "/run/credentials/stalwart-mail.service";
in {
security.acme.certs.${domain}.postRun = "systemctl restart stalwart-mail.service";
sops.secrets = {
"mail.${domain}/dkim_rsa" = {};
"mail.${domain}/dkim_ed25519" = {};
"mail.${domain}/password" = {};
};
systemd.services.stalwart-mail.serviceConfig.LoadCredential = [
"password:${config.sops.secrets."mail.${domain}/password".path}"
"dkim_rsa:${config.sops.secrets."mail.${domain}/dkim_rsa".path}"
"dkim_ed25519:${config.sops.secrets."mail.${domain}/dkim_ed25519".path}"
"cert:${config.security.acme.certs.${domain}.directory}/fullchain.pem"
"key:${config.security.acme.certs.${domain}.directory}/key.pem"
];
services.stalwart-mail = {
enable = false;
openFirewall = true;
settings = {
queue.outbound = {
ip-strategy = "ipv6_then_ipv4";
source-ip.v6 = "['${ipv6}']";
tls.starttls = "optional";
};
server.listener = {
smtp = {
bind = [ "[${ipv6}]:25" "0.0.0.0:25" ];
protocol = "smtp";
};
submission = {
bind = "[::]:587";
protocol = "smtp";
};
submissions = {
bind = "[::]:465";
protocol = "smtp";
tls.implicit = true;
};
imaptls = {
bind = "[::]:993";
protocol = "imap";
};
http = {
bind = "[::]:8085";
protocol = "http";
};
};
signature = {
rsa = {
private-key = "%{file:/${credentials_directory}/dkim_rsa}%";
inherit domain;
selector = "rsa";
headers = ["From" "To" "Date" "Subject" "Message-ID"];
algorithm = "rsa-sha-256";
canonicalization = "relaxed/relaxed"; # what
expire = "10d";
report = true;
};
ed25519 = {
private-key = "%{file:/${credentials_directory}/dkim_ed25519}%";
inherit domain;
selector = "ed25519";
headers = ["From" "To" "Date" "Subject" "Message-ID"];
algorithm = "ed25519-sha256";
canonicalization = "relaxed/relaxed"; # what
expire = "10d";
report = true;
};
};
certificate."default" = {
cert = "%{file:/${credentials_directory}/cert}%";
private-key = "%{file:/${credentials_directory}/key}%";
};
storage = {
data = "rocksdb";
fts = "rocksdb";
blob = "rocksdb";
lookup = "rocksdb";
directory = "in-memory";
};
store.postgresql = {
type = "postgresql";
host = "localhost";
database = "stalwart";
user = "stalwart";
password = "ass";
timeout = "15s";
tls.enable = false;
pool.max-connections = 10;
};
directory."in-memory" = {
type = "memory";
options.subaddressing = true;
principals = [
{
inherit email;
secret = "%{file:/${credentials_directory}/password}%";
name = username;
type = "admin";
}
{ # for mta-sts & dmarc reports
email = "reports${domain}";
secret = "%{file:/${credentials_directory}/password}%";
name = "reports";
type = "individual";
}
];
};
};
};
}
|