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