Add dovecot
This commit is contained in:
parent
9f215c77aa
commit
b0b770c4d0
4 changed files with 225 additions and 2 deletions
118
config/services/dovecot.nix
Normal file
118
config/services/dovecot.nix
Normal file
|
@ -0,0 +1,118 @@
|
|||
{ pkgs, ... }:
|
||||
let
|
||||
listenIPs = (import ../../utils/getInternalIP.nix config).listenIP;
|
||||
sieves = import ../../packages/sieves.nix pkgs;
|
||||
|
||||
in
|
||||
{
|
||||
services.dovecot2 = {
|
||||
enable = true;
|
||||
enableImap = true;
|
||||
enableLmtp = true;
|
||||
enablePop3 = true;
|
||||
enableQuota = true;
|
||||
mailGroup = "vmail";
|
||||
mailUser = "vmail";
|
||||
mailLocation = "maildir:/var/vmail/%h/%n";
|
||||
mailPlugins = {
|
||||
globally.enable = [
|
||||
"old_stats"
|
||||
];
|
||||
perProtocol = {
|
||||
imap.enable = [
|
||||
"imap_sieve"
|
||||
];
|
||||
lda.enable = [
|
||||
"sieve"
|
||||
];
|
||||
lmtp.enable = [
|
||||
"lmtp_sieve"
|
||||
];
|
||||
};
|
||||
};
|
||||
mailboxes = {
|
||||
Drafts = {
|
||||
specialUse = "Drafts";
|
||||
auto = "subscribe";
|
||||
};
|
||||
Junk = {
|
||||
specialUse = "Junk";
|
||||
auto = "subscribe";
|
||||
};
|
||||
Trash = {
|
||||
specialUse = "Trash";
|
||||
auto = "subscribe";
|
||||
};
|
||||
Sent = {
|
||||
specialUse = "Sent";
|
||||
auto = "subscribe";
|
||||
};
|
||||
"Sent Messages" = {
|
||||
specialUse = "Sent";
|
||||
};
|
||||
"virtual/All" = {
|
||||
specialUse = "All";
|
||||
auto = "subscribe";
|
||||
};
|
||||
};
|
||||
sslServerCert = "/var/lib/acme/chir.rs/cert.pem";
|
||||
sslServerKey = "/var/lib/acme/chir.rs/key.pem";
|
||||
extraConfig = ''
|
||||
service old-stats {
|
||||
unix_listener old-stats {
|
||||
user = dovecot-exporter
|
||||
group = dovecot-exporter
|
||||
mode = 0660
|
||||
}
|
||||
fifo_listener old-stats-mail {
|
||||
mode = 0660
|
||||
user = dovecot
|
||||
group = dovecot
|
||||
}
|
||||
fifo_listener old-stats-user {
|
||||
mode = 0660
|
||||
user = dovecot
|
||||
group = dovecot
|
||||
}
|
||||
}
|
||||
plugin {
|
||||
old_stats_refresh = 30 secs
|
||||
old_stats_track_cmds = yes
|
||||
}
|
||||
plugin {
|
||||
sieve_plugins = sieve_imapsieve sieve_extprograms
|
||||
# From elsewhere to Spam folder or flag changed in Spam folder
|
||||
imapsieve_mailbox1_name = Junk
|
||||
imapsieve_mailbox1_causes = COPY FLAG
|
||||
imapsieve_mailbox1_before = file:${sieves.report-spam}/report-spam.sieve
|
||||
|
||||
# From Spam folder to elsewhere
|
||||
imapsieve_mailbox2_name = *
|
||||
imapsieve_mailbox2_from = Junk
|
||||
imapsieve_mailbox2_causes = COPY
|
||||
imapsieve_mailbox2_before = file:${sieves.report-ham}/report-ham.sieve
|
||||
|
||||
sieve_pipe_bin_dir = /nix/store
|
||||
|
||||
sieve_global_extensions = +vnd.dovecot.pipe
|
||||
sieve = ${sieves.default}/default.sieve
|
||||
}
|
||||
disable_plaintext_auth = yes
|
||||
auth_mechanisms = plain login
|
||||
|
||||
'';
|
||||
user = "dovecot";
|
||||
};
|
||||
services.prometheus.exporters.dovecot = {
|
||||
enable = true;
|
||||
listenAddress = listenIP;
|
||||
};
|
||||
sops.secrets."services/dovecot/rspamd_password" = { owner = "dovecot"; };
|
||||
services.postgresql.ensureUsers = [{
|
||||
name = "dovecot";
|
||||
ensurePermissions = {
|
||||
"DATABASE \"postfix\"" = "CONNECT";
|
||||
"ALL TABLES IN DATABASE \"postfix\"" = "SELECT"; # can't select more granular permissions
|
||||
};
|
||||
}];
|
||||
}
|
24
packages/sievec.nix
Normal file
24
packages/sievec.nix
Normal file
|
@ -0,0 +1,24 @@
|
|||
{ writeText, stdenv, dovecot_pigeonhole, ... } @ pkgs: { name, src, exts }:
|
||||
let dummyConfig = writeText "dovecot.cfg" ''
|
||||
plugin {
|
||||
sieve_plugins = sieve_imapsieve sieve_extprograms
|
||||
sieve_global_extensions = +vnd.dovecot.pipe
|
||||
}
|
||||
'';
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
inherit name;
|
||||
inherit src;
|
||||
|
||||
phases = [ "copyPhase" "compilePhase" ];
|
||||
|
||||
copyPhase = ''
|
||||
mkdir $out
|
||||
cp $src $out/${name}.sieve
|
||||
chmod 0755 $out/${name}.sieve
|
||||
set +x
|
||||
'';
|
||||
compilePhase = ''
|
||||
${dovecot_pigeonhole}/bin/sievec -c ${dummyConfig} $out/${name}.sieve $out/${name}.svbin -x "${toString exts}"
|
||||
'';
|
||||
}
|
79
packages/sieves.nix
Normal file
79
packages/sieves.nix
Normal file
|
@ -0,0 +1,79 @@
|
|||
{ lib, writeText, writeScript, zsh, coreutils-full, rspamd, ... } @ pkgs:
|
||||
let
|
||||
sievec = import ./sievec.nix pkgs;
|
||||
rspamd_host = "fd00:e621:e621:2::2";
|
||||
sa-learn-ham-script = writeScript "sa-learn-ham" ''
|
||||
#!${zsh}/bin/zsh
|
||||
|
||||
tmpfile=$(${coreutils-full}/bin/mktemp /tmp/spam.XXXXXX)
|
||||
${coreutils-full}/bin/cat > $tmpfile
|
||||
password=$(${coreutils-full}/bin/cat /run/secrets/services/dovecot/rspamd_password)
|
||||
|
||||
${coreutils-full}/bin/cat $tmpfile | ${rspamd}/bin/rspamc -P $password -h ${rspamd_host} learn_ham
|
||||
${coreutils-full}/bin/cat $tmpfile | ${rspamd}/bin/rspamc -P $password -h ${rspamd_host} -w 5 -f 11 fuzzy_del
|
||||
|
||||
${coreutils-full}/bin/rm $tmpfile
|
||||
'';
|
||||
|
||||
sa-learn-spam-script = writeScript "sa-learn-spam" ''
|
||||
#!${zsh}/bin/zsh
|
||||
|
||||
tmpfile=$(${coreutils-full}/bin/mktemp /tmp/spam.XXXXXX)
|
||||
${coreutils-full}/bin/cat > $tmpfile
|
||||
password=$(${coreutils-full}/bin/cat /run/secrets/services/dovecot/rspamd_password)
|
||||
|
||||
${coreutils-full}/bin/cat $tmpfile | ${rspamd}/bin/rspamc -P $password -h ${rspamd_host} learn_spam
|
||||
${coreutils-full}/bin/cat $tmpfile | ${rspamd}/bin/rspamc -P $password -h ${rspamd_host} -w 5 -f 11 fuzzy_add
|
||||
|
||||
${coreutils-full}/bin/rm $tmpfile
|
||||
'';
|
||||
removeStore = location: lib.removePrefix "/nix/store/" "${location}";
|
||||
in
|
||||
{
|
||||
default = sievec {
|
||||
name = "default";
|
||||
src = writeText "default.sieve" ''
|
||||
require "fileinto";
|
||||
if header :contains "X-Spam" "YES" {
|
||||
fileinto "Junk";
|
||||
}
|
||||
'';
|
||||
exts = [ "fileinto" ];
|
||||
};
|
||||
report-ham = sievec {
|
||||
name = "report-ham";
|
||||
src = writeText "report-ham.sieve" ''
|
||||
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
|
||||
|
||||
if environment :matches "imap.mailbox" "*" {
|
||||
set "mailbox" "$${1}";
|
||||
}
|
||||
|
||||
if string "$${mailbox}" [ "Trash", "train_ham", "train_prob", "train_spam" ] {
|
||||
stop;
|
||||
}
|
||||
|
||||
pipe :copy "${removeStore sa-learn-ham-script}";
|
||||
'';
|
||||
exts = [ "vnd.dovecot.pipe" "copy" "imapsieve" "environment" "variables" ];
|
||||
};
|
||||
report-spam = sievec {
|
||||
name = "report-spam";
|
||||
src = writeText "report-spam.sieve" ''
|
||||
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "imap4flags"];
|
||||
|
||||
if environment :is "imap.cause" "COPY" {
|
||||
pipe :copy "${removeStore sa-learn-spam-script}";
|
||||
}
|
||||
|
||||
# Catch replied or forwarded spam
|
||||
elsif anyof (allof (hasflag "\\Answered",
|
||||
environment :contains "imap.changedflags" "\\Answered"),
|
||||
allof (hasflag "$Forwarded",
|
||||
environment :contains "imap.changedflags" "$Forwarded")) {
|
||||
pipe :copy "${removeStore sa-learn-spam-script}";
|
||||
}
|
||||
'';
|
||||
exts = [ "vnd.dovecot.pipe" "copy" "imapsieve" "environment" "imap4flags" ];
|
||||
};
|
||||
}
|
|
@ -16,6 +16,8 @@ services:
|
|||
postfixadmin:
|
||||
dbpassword: ENC[AES256_GCM,data:37kEiKKgJVRIzzWXY3o/Wpk5UQ==,iv:LAJXgMr/rTMkds1r1kEWzhwNb6aPzsAhqUEeoLyBDbo=,tag:TI7oYxdpNzw2dXA4hLmVnQ==,type:str]
|
||||
setupPassword: ENC[AES256_GCM,data:2BiQLOZZ6zCh4F+DkeNpMGLeXoxmMtDkuAU4XGBNvso+f4jupowalLkhTG/kA8yUL6BWOxwtJGMEp5wO,iv:0guj3/elSzoOe/00wgi5Z4R4lVfWeWt8mUDao3RXK6I=,tag:1lFUqfeSGV04mfxaVrmSMg==,type:str]
|
||||
dovecot:
|
||||
rspamd_password: ENC[AES256_GCM,data:PYVfbmSR8Uq3gQGkXVhj6Pt4QIo=,iv:jG7BudJT6+RAprllh5dGnSiqr4hS/GtyZesc77bd8eY=,tag:GBRgqg74cp1CPhDOu8IyKw==,type:str]
|
||||
email:
|
||||
darkkirb@darkkirb.de: ENC[AES256_GCM,data:DgVyvDHsviJuGqM+YP4jjytnzJE=,iv:KhEJz2+Nl9sxjRe0FmHOXi64QtsxDZhagnYt08sqU4E=,tag:vrhBg9qWBiSLPop/5jyIwA==,type:str]
|
||||
lotte@chir.rs: ENC[AES256_GCM,data:bkzYVXizG/inJ/MS57G2pEiUkA==,iv:jviAx1B83wPhc128msfSs7oYwRQH+j7PU0aAmNbwi88=,tag:ylYl5k9R5BdLGAXOXVeLZg==,type:str]
|
||||
|
@ -44,8 +46,8 @@ sops:
|
|||
Ync4ejJHR0RXTkpqVzFRQXhEVlFVZjgKPo209jJf8Lwn1j3VmLC+j0633zdbt2yf
|
||||
bPwO7dlKYGbGeGObprNtBXBS2cUXHeuQ45vRpTtg1cpxYK+TfNH8vQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2022-01-20T08:56:25Z"
|
||||
mac: ENC[AES256_GCM,data:o7Ssj3mTwoYQN4TeveWxqn9oP/d7ZBw0I/KRfthhFv0ry+avBuIAr4ocgSKC6oCwnp3rNCr3pEsN+wN4kpidQ213ytvP8tSegn936i8WiU2ozD/jBHlRtRQg1abDau8rOps6W65dMBrqoGUDRVdrIsfp63K3myT8pv74u9dkYew=,iv:LU3chaUBP6FOhdR0Ua3YF+OsyEb2utmlnGxacZIcqc4=,tag:WgWXaduAXEbXj3czGHM+CA==,type:str]
|
||||
lastmodified: "2022-01-20T15:46:48Z"
|
||||
mac: ENC[AES256_GCM,data:jsQx0yZmcssxTXLzxx10yrSLfYqfa75LIQFRKWmHkTrd/a2w/ZZFfcorqjoNARtsx+F8Das++ZHpenEdHyxyOSPif5JCIsjrBD6RtJyaKVmIuDirhqUhMQNB2ZDLQifIIsA2qCzhJPThP/+ZJygnhUYiOKg86fangLpkAIxF7DM=,iv:R77YqOSBBMEZbwiPAhnDScYCA+DrTVsZfjNYw9S0iMU=,tag:3va+Z/r39RrD9iQ2BIApNw==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.7.1
|
||||
|
|
Loading…
Reference in a new issue