]> git.immae.eu Git - perso/Immae/Config/Nix.git/blob - modules/private/mail/dovecot.nix
Configure mail (dovecot, postfix, spam checks)
[perso/Immae/Config/Nix.git] / modules / private / mail / dovecot.nix
1 { lib, pkgs, config, myconfig, ... }:
2 let
3 sieve_bin = pkgs.runCommand "sieve_bin" {
4 buildInputs = [ pkgs.makeWrapper ];
5 } ''
6 cp -a ${./sieve_bin} $out
7 chmod -R u+w $out
8 patchShebangs $out
9 for i in $out/*; do
10 wrapProgram "$i" --prefix PATH : ${lib.makeBinPath [ pkgs.coreutils ]}
11 done
12 '';
13 in
14 {
15 config.secrets.keys = [
16 {
17 dest = "dovecot/ldap";
18 user = config.services.dovecot2.user;
19 group = config.services.dovecot2.group;
20 permissions = "0400";
21 text = ''
22 hosts = ${myconfig.env.mail.dovecot.ldap.host}
23 tls = yes
24
25 dn = ${myconfig.env.mail.dovecot.ldap.dn}
26 dnpass = ${myconfig.env.mail.dovecot.ldap.password}
27
28 auth_bind = yes
29
30 ldap_version = 3
31
32 base = ${myconfig.env.mail.dovecot.ldap.base}
33 scope = subtree
34
35 user_filter = ${myconfig.env.mail.dovecot.ldap.filter}
36 pass_filter = ${myconfig.env.mail.dovecot.ldap.filter}
37
38 user_attrs = ${myconfig.env.mail.dovecot.ldap.user_attrs}
39 pass_attrs = ${myconfig.env.mail.dovecot.ldap.pass_attrs}
40 '';
41 }
42 ];
43
44 config.users.users.vhost = {
45 group = "vhost";
46 uid = config.ids.uids.vhost;
47 };
48 config.users.groups.vhost.gid = config.ids.gids.vhost;
49
50 # https://blog.zeninc.net/index.php?post/2018/04/01/Un-annuaire-pour-les-gouverner-tous.......
51 config.services.dovecot2 = {
52 enable = true;
53 enablePAM = false;
54 enablePop3 = true;
55 enableImap = true;
56 enableLmtp = true;
57 protocols = [ "sieve" ];
58 modules = [
59 pkgs.dovecot_pigeonhole
60 pkgs.dovecot_deleted-to-trash
61 pkgs.dovecot_fts-xapian
62 ];
63 mailUser = "vhost";
64 mailGroup = "vhost";
65 createMailUser = false;
66 mailboxes = [
67 { name = "Trash"; auto = "subscribe"; specialUse = "Trash"; }
68 { name = "Junk"; auto = "subscribe"; specialUse = "Junk"; }
69 { name = "Sent"; auto = "subscribe"; specialUse = "Sent"; }
70 { name = "Drafts"; auto = "subscribe"; specialUse = "Drafts"; }
71 ];
72 mailLocation = "mbox:~/Mail:INBOX=~/Mail/Inbox:INDEX=~/.imap";
73 sslServerCert = "/var/lib/acme/mail/fullchain.pem";
74 sslServerKey = "/var/lib/acme/mail/key.pem";
75 sslCACert = "/var/lib/acme/mail/fullchain.pem";
76 extraConfig = builtins.concatStringsSep "\n" [
77 ''
78 postmaster_address = postmaster@immae.eu
79 mail_attribute_dict = file:%h/dovecot-attributes
80 imap_idle_notify_interval = 20 mins
81 namespace inbox {
82 type = private
83 separator = /
84 inbox = yes
85 list = yes
86 }
87 ''
88
89 # Full text search
90 ''
91 # needs to be bigger than any mailbox size
92 default_vsz_limit = 2GB
93 mail_plugins = $mail_plugins fts fts_xapian
94 plugin {
95 plugin = fts fts_xapian
96 fts = xapian
97 fts_xapian = partial=2 full=20
98 fts_autoindex = yes
99 fts_autoindex_exclude = \Junk
100 fts_autoindex_exclude2 = \Trash
101 fts_autoindex_exclude3 = Virtual/*
102 }
103 ''
104
105 # Antispam
106 # https://docs.iredmail.org/dovecot.imapsieve.html
107 ''
108 # imap_sieve plugin added below
109
110 plugin {
111 sieve_plugins = sieve_imapsieve sieve_extprograms
112 imapsieve_url = sieve://127.0.0.1:4190
113
114 # From elsewhere to Junk folder
115 imapsieve_mailbox1_name = Junk
116 imapsieve_mailbox1_causes = COPY APPEND
117 imapsieve_mailbox1_before = file:${./sieve_scripts}/report_spam.sieve;bindir=/var/lib/vhost/.imapsieve_bin
118
119 # From Junk folder to elsewhere
120 imapsieve_mailbox2_name = *
121 imapsieve_mailbox2_from = Junk
122 imapsieve_mailbox2_causes = COPY
123 imapsieve_mailbox2_before = file:${./sieve_scripts}/report_ham.sieve;bindir=/var/lib/vhost/.imapsieve_bin
124
125 sieve_pipe_bin_dir = ${sieve_bin}
126
127 sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
128 }
129 ''
130 # Services to listen
131 ''
132 service imap-login {
133 inet_listener imap {
134 }
135 inet_listener imaps {
136 }
137 }
138 service pop3-login {
139 inet_listener pop3 {
140 }
141 inet_listener pop3s {
142 }
143 }
144 service imap {
145 }
146 service pop3 {
147 }
148 service auth {
149 unix_listener auth-userdb {
150 }
151 unix_listener ${config.services.postfix.config.queue_directory}/private/auth {
152 mode = 0666
153 }
154 }
155 service auth-worker {
156 }
157 service dict {
158 unix_listener dict {
159 }
160 }
161 service stats {
162 unix_listener stats-reader {
163 user = vhost
164 group = vhost
165 mode = 0660
166 }
167 unix_listener stats-writer {
168 user = vhost
169 group = vhost
170 mode = 0660
171 }
172 }
173 ''
174
175 # Authentification
176 ''
177 first_valid_uid = ${toString config.ids.uids.vhost}
178 disable_plaintext_auth = yes
179 passdb {
180 driver = ldap
181 args = ${config.secrets.fullPaths."dovecot/ldap"}
182 }
183 userdb {
184 driver = static
185 args = user=%u uid=vhost gid=vhost home=/var/lib/vhost/%d/%n/ mail=mbox:~/Mail:INBOX=~/Mail/Inbox:INDEX=~/.imap
186 }
187 ''
188
189 # Zlib
190 ''
191 mail_plugins = $mail_plugins zlib
192 plugin {
193 zlib_save_level = 6
194 zlib_save = gz
195 }
196 ''
197
198 # Sieve
199 ''
200 plugin {
201 sieve = file:~/sieve;bindir=~/.sieve-bin;active=~/.dovecot.sieve
202 }
203 service managesieve-login {
204 }
205 service managesieve {
206 }
207 ''
208
209 # Deleted to trash
210 ''
211 plugin {
212 deleted_to_trash_folder = Trash
213 }
214 ''
215
216 # Virtual mailboxes
217 ''
218 mail_plugins = $mail_plugins virtual
219 namespace Virtual {
220 prefix = Virtual/
221 location = virtual:~/Virtual
222 }
223 ''
224
225 # Protocol specific configuration
226 # Needs to come last if there are mail_plugins entries
227 ''
228 protocol imap {
229 mail_plugins = $mail_plugins deleted_to_trash imap_sieve
230 }
231 protocol lda {
232 mail_plugins = $mail_plugins sieve
233 }
234 ''
235 ];
236 };
237 config.networking.firewall.allowedTCPPorts = [ 110 143 993 995 4190 ];
238 config.system.activationScripts.dovecot = {
239 deps = [ "users" ];
240 text =''
241 install -m 0755 -o vhost -g vhost -d /var/lib/vhost
242 '';
243 };
244
245 config.security.acme.certs."mail" = {
246 postRun = ''
247 systemctl restart dovecot2.service
248 '';
249 extraDomains = {
250 "imap.immae.eu" = null;
251 "pop3.immae.eu" = null;
252 };
253 };
254 }
255