2023-04-20 09:43:39 +00:00
|
|
|
# dovecot config options: <https://doc.dovecot.org/configuration_manual/>
|
2023-04-20 14:25:59 +00:00
|
|
|
#
|
|
|
|
# sieve docs:
|
|
|
|
# - sieve language examples: <https://doc.dovecot.org/configuration_manual/sieve/examples/>
|
|
|
|
# - sieve protocol/language: <https://proton.me/support/sieve-advanced-custom-filters>
|
|
|
|
|
|
|
|
{ config, lib, pkgs, ... }:
|
2023-04-20 09:43:39 +00:00
|
|
|
{
|
2023-05-31 04:25:39 +00:00
|
|
|
sane.ports.ports."143" = {
|
|
|
|
protocol = [ "tcp" ];
|
|
|
|
visibleTo.lan = true;
|
|
|
|
visibleTo.wan = true;
|
|
|
|
description = "colin-imap-imap.uninsane.org";
|
|
|
|
};
|
|
|
|
sane.ports.ports."993" = {
|
|
|
|
protocol = [ "tcp" ];
|
|
|
|
visibleTo.lan = true;
|
|
|
|
visibleTo.wan = true;
|
|
|
|
description = "colin-imaps-imap.uninsane.org";
|
|
|
|
};
|
2023-04-20 09:43:39 +00:00
|
|
|
|
|
|
|
# exists only to manage certs for dovecot
|
|
|
|
services.nginx.virtualHosts."imap.uninsane.org" = {
|
|
|
|
enableACME = true;
|
|
|
|
};
|
|
|
|
|
2023-06-07 23:34:00 +00:00
|
|
|
sane.dns.zones."uninsane.org".inet = {
|
2023-04-20 09:43:39 +00:00
|
|
|
CNAME."imap" = "native";
|
|
|
|
};
|
|
|
|
|
|
|
|
sops.secrets."dovecot_passwd" = {
|
|
|
|
owner = config.users.users.dovecot2.name;
|
|
|
|
# TODO: debug why mail can't be sent without this being world-readable
|
|
|
|
mode = "0444";
|
|
|
|
};
|
|
|
|
|
|
|
|
# inspired by https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/
|
|
|
|
services.dovecot2.enable = true;
|
2023-04-20 14:25:59 +00:00
|
|
|
# services.dovecot2.enableLmtp = true;
|
2023-04-20 09:43:39 +00:00
|
|
|
services.dovecot2.sslServerCert = "/var/lib/acme/imap.uninsane.org/fullchain.pem";
|
|
|
|
services.dovecot2.sslServerKey = "/var/lib/acme/imap.uninsane.org/key.pem";
|
|
|
|
services.dovecot2.enablePAM = false;
|
2023-04-20 14:25:59 +00:00
|
|
|
|
|
|
|
# sieve scripts require me to set a user for... idk why?
|
|
|
|
services.dovecot2.mailUser = "colin";
|
|
|
|
services.dovecot2.mailGroup = "users";
|
|
|
|
users.users.colin.isSystemUser = lib.mkForce false;
|
|
|
|
|
2023-04-20 09:43:39 +00:00
|
|
|
services.dovecot2.extraConfig =
|
|
|
|
let
|
|
|
|
passwdFile = config.sops.secrets.dovecot_passwd.path;
|
|
|
|
in
|
|
|
|
''
|
|
|
|
passdb {
|
|
|
|
driver = passwd-file
|
|
|
|
args = ${passwdFile}
|
|
|
|
}
|
|
|
|
userdb {
|
|
|
|
driver = passwd-file
|
|
|
|
args = ${passwdFile}
|
|
|
|
}
|
|
|
|
|
|
|
|
# allow postfix to query our auth db
|
|
|
|
service auth {
|
|
|
|
unix_listener auth {
|
|
|
|
mode = 0660
|
|
|
|
user = postfix
|
|
|
|
group = postfix
|
|
|
|
}
|
|
|
|
}
|
|
|
|
auth_mechanisms = plain login
|
|
|
|
|
2023-04-20 14:25:59 +00:00
|
|
|
# accept incoming messaging from postfix
|
|
|
|
# service lmtp {
|
|
|
|
# unix_listener dovecot-lmtp {
|
|
|
|
# mode = 0600
|
|
|
|
# user = postfix
|
|
|
|
# group = postfix
|
|
|
|
# }
|
|
|
|
# }
|
|
|
|
|
|
|
|
# plugin {
|
|
|
|
# sieve_plugins = sieve_imapsieve
|
|
|
|
# }
|
2023-04-20 09:43:39 +00:00
|
|
|
|
|
|
|
mail_debug = yes
|
|
|
|
auth_debug = yes
|
|
|
|
# verbose_ssl = yes
|
|
|
|
'';
|
2023-04-20 14:25:59 +00:00
|
|
|
|
|
|
|
services.dovecot2.mailboxes = {
|
|
|
|
# special-purpose mailboxes: "All" "Archive" "Drafts" "Flagged" "Junk" "Sent" "Trash"
|
|
|
|
# RFC6154 describes these special mailboxes: https://www.ietf.org/rfc/rfc6154.html
|
|
|
|
# how these boxes are treated is 100% up to the client and server to decide.
|
|
|
|
# client behavior:
|
|
|
|
# iOS
|
|
|
|
# - Drafts: ?
|
|
|
|
# - Sent: works
|
|
|
|
# - Trash: works
|
|
|
|
# - Junk: works ("mark" -> "move to Junk")
|
|
|
|
# aerc
|
|
|
|
# - Drafts: works
|
|
|
|
# - Sent: works
|
|
|
|
# - Trash: no; deleted messages are actually deleted
|
|
|
|
# use `:move trash` instead
|
|
|
|
# - Junk: ?
|
|
|
|
# Sent mailbox: all sent messages are copied to it. unclear if this happens server-side or client-side.
|
|
|
|
Drafts = { specialUse = "Drafts"; auto = "create"; };
|
|
|
|
Sent = { specialUse = "Sent"; auto = "create"; };
|
|
|
|
Trash = { specialUse = "Trash"; auto = "create"; };
|
|
|
|
Junk = { specialUse = "Junk"; auto = "create"; };
|
|
|
|
};
|
|
|
|
|
|
|
|
services.dovecot2.mailPlugins = {
|
|
|
|
perProtocol = {
|
|
|
|
# imap.enable = [
|
|
|
|
# "imap_sieve"
|
|
|
|
# ];
|
|
|
|
lda.enable = [
|
|
|
|
"sieve"
|
|
|
|
];
|
|
|
|
# lmtp.enable = [
|
|
|
|
# "sieve"
|
|
|
|
# ];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
services.dovecot2.modules = [
|
|
|
|
pkgs.dovecot_pigeonhole # enables sieve execution (?)
|
|
|
|
];
|
2024-01-16 06:28:25 +00:00
|
|
|
services.dovecot2.sieve = {
|
|
|
|
# maybe not all of these are needed. source: <https://github.com/NixOS/nixpkgs/pull/275031#issuecomment-1891052685>
|
|
|
|
plugins = [ "sieve_imapsieve" "sieve_extprograms" ];
|
2024-01-22 08:09:37 +00:00
|
|
|
# extensions = [ "fileinto" ];
|
|
|
|
# globalExtensions = [ "vnd.dovecot.pipe" "vnd.dovecot.environment" ];
|
2023-04-20 14:25:59 +00:00
|
|
|
# if any messages fail to pass (or lack) DKIM, move them to Junk
|
|
|
|
# XXX the key name ("after") is only used to order sieve execution/ordering
|
2024-01-16 06:28:25 +00:00
|
|
|
};
|
|
|
|
services.dovecot2.sieveScripts = {
|
2023-04-20 14:25:59 +00:00
|
|
|
after = builtins.toFile "ensuredkim.sieve" ''
|
|
|
|
require "fileinto";
|
|
|
|
|
|
|
|
if not header :contains "Authentication-Results" "dkim=pass" {
|
|
|
|
fileinto "Junk";
|
|
|
|
stop;
|
|
|
|
}
|
|
|
|
'';
|
|
|
|
};
|
2024-01-22 08:09:37 +00:00
|
|
|
|
|
|
|
systemd.services.dovecot2.serviceConfig.RestartSec = lib.mkForce "15s"; # nixos defaults this to 1s
|
2023-04-20 09:43:39 +00:00
|
|
|
}
|