Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/maddy: Add listeners option #153372

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
257 changes: 200 additions & 57 deletions nixos/modules/services/mail/maddy.nix
Expand Up @@ -46,57 +46,6 @@ let
}
}

smtp tcp://0.0.0.0:25 {
limits {
all rate 20 1s
all concurrency 10
}
dmarc yes
check {
require_mx_record
dkim
spf
}
source $(local_domains) {
reject 501 5.1.8 "Use Submission for outgoing SMTP"
}
default_source {
destination postmaster $(local_domains) {
deliver_to &local_routing
}
default_destination {
reject 550 5.1.1 "User doesn't exist"
}
}
}

submission tcp://0.0.0.0:587 {
limits {
all rate 50 1s
}
auth &local_authdb
source $(local_domains) {
check {
authorize_sender {
prepare_email &local_rewrites
user_to_email identity
}
}
destination postmaster $(local_domains) {
deliver_to &local_routing
}
default_destination {
modify {
dkim $(primary_domain) $(local_domains) default
}
deliver_to &remote_queue
}
}
default_source {
reject 501 5.1.8 "Non-local sender domain"
}
}

target.remote outbound_delivery {
limits {
destination rate 20 1s
Expand Down Expand Up @@ -127,13 +76,65 @@ let
}
}
}
'';

imap tcp://0.0.0.0:143 {
auth &local_authdb
storage &local_mailboxes
defaultSubmissionConfig = ''
limits {
all rate 50 1s
}
auth &local_authdb
source $(local_domains) {
check {
authorize_sender {
prepare_email &local_rewrites
user_to_email identity
}
}
destination postmaster $(local_domains) {
deliver_to &local_routing
}
default_destination {
modify {
dkim $(primary_domain) $(local_domains) default
}
deliver_to &remote_queue
}
}
default_source {
reject 501 5.1.8 "Non-local sender domain"
}
'';

defaultSmtpConfig = ''
limits {
all rate 20 1s
all concurrency 10
}
dmarc yes
check {
require_mx_record
dkim
spf
}
source $(local_domains) {
reject 501 5.1.8 "Use Submission for outgoing SMTP"
}
default_source {
destination postmaster $(local_domains) {
deliver_to &local_routing
}
default_destination {
reject 550 5.1.1 "User doesn't exist"
}
}
'';

defaultImapConfig = ''
auth &local_authdb
storage &local_mailboxes
'';


in {
options = {
services.maddy = {
Expand Down Expand Up @@ -321,6 +322,126 @@ in {
});
};

imap = {
enable = mkOption {
type = types.bool;
default = true;
description = "Enable Imap connection.";
};

listenAddress = mkOption {
description = "Imap listening host";
default = "0.0.0.0";
type = types.str;
};

port = mkOption {
type = types.ints.u16;
default = 143;
description = "Server port to listen for Imap requests.";
};

tlsEnable = mkOption {
type = types.bool;
default = false;
description = "Enable Imap tls connection.";
};

tlsListenAddress = mkOption {
description = "TLS Imap listening host";
default = "0.0.0.0";
type = types.str;
};

tlsPort = mkOption {
type = types.ints.u16;
default = 993;
description = "Server port to listen for Imap tls requests.";
};

config = mkOption {
type = with types; nullOr lines;
default = defaultImapConfig;
description = ''
Default Imap config.
'';
};
};

smtp = {
enable = mkOption {
type = types.bool;
default = true;
description = "Enable Smtp connection.";
};

listenAddress = mkOption {
description = "Smtp listening host";
default = "0.0.0.0";
type = types.str;
};

port = mkOption {
type = types.ints.u16;
default = 25;
description = "Server port to listen for Smtp requests.";
};

config = mkOption {
type = with types; nullOr lines;
default = defaultSmtpConfig;
description = ''
Default Smtp config.
'';
};
};

submission = {
enable = mkOption {
type = types.bool;
default = true;
description = "Enable Submission connection.";
};

listenAddress = mkOption {
description = "Submission listening host";
default = "0.0.0.0";
type = types.str;
};

port = mkOption {
type = types.ints.u16;
default = 587;
description = "Server port to listen for Submission requests.";
};

tlsEnable = mkOption {
type = types.bool;
default = false;
description = "Enable Submission tls connection.";
};

tlsListenAddress = mkOption {
description = "Submission TLS listening host";
default = "0.0.0.0";
type = types.str;
};

tlsPort = mkOption {
type = types.ints.u16;
default = 465;
description = "Server port to listen for Submission tls requests.";
};

config = mkOption {
type = with types; nullOr lines;
default = defaultSubmissionConfig;
description = ''
Default Submission config.
'';
};
};

};
};

Expand Down Expand Up @@ -395,6 +516,24 @@ in {
tls off
'' else ""}

${optionalString (cfg.smtp.enable) ''
smtp tcp://${cfg.smtp.listenAddress}:${toString cfg.smtp.port} {
${cfg.smtp.config}
}
''}

${optionalString (cfg.imap.enable || cfg.imap.tlsEnable) ''
imap ${optionalString (cfg.imap.enable) "tcp://${cfg.imap.listenAddress}:${toString cfg.imap.port}"} ${optionalString (cfg.imap.tlsEnable) "tls://${cfg.imap.tlsListenAddress}:${toString cfg.imap.tlsPort}"} {
${cfg.imap.config}
}
''}

${optionalString (cfg.submission.enable || cfg.submission.tlsEnable) ''
submission ${optionalString (cfg.submission.enable) "tcp://${cfg.submission.listenAddress}:${toString cfg.submission.port}"} ${optionalString (cfg.submission.tlsEnable) "tls://${cfg.submission.tlsListenAddress}:${toString cfg.submission.tlsPort}"} {
${cfg.submission.config}
}
''}

${cfg.config}
'';
};
Expand All @@ -411,9 +550,13 @@ in {
${cfg.group} = { };
};

networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ 25 143 587 ];
};
networking.firewall.allowedTCPPorts = mkMerge [
(mkIf cfg.smtp.enable [ cfg.smtp.port ])
(mkIf cfg.imap.enable [ cfg.imap.port ])
(mkIf cfg.imap.tlsEnable [ cfg.imap.tlsPort ])
(mkIf cfg.submission.enable [ cfg.submission.port ])
(mkIf cfg.submission.tlsEnable [ cfg.submission.tlsPort ])
];

environment.systemPackages = [
pkgs.maddy
Expand Down
13 changes: 2 additions & 11 deletions nixos/tests/maddy/tls.nix
Expand Up @@ -26,18 +26,9 @@ in {
keyPath = "${certs.${domain}.key}";
}];
};
# Enable TLS listeners. Configuring this via the module is not yet
# implemented.
config = builtins.replaceStrings [
"imap tcp://0.0.0.0:143"
"submission tcp://0.0.0.0:587"
] [
"imap tls://0.0.0.0:993 tcp://0.0.0.0:143"
"submission tls://0.0.0.0:465 tcp://0.0.0.0:587"
] options.services.maddy.config.default;
submission.tlsEnable = true;
imap.tlsEnable = true;
};
# Not covered by openFirewall yet
networking.firewall.allowedTCPPorts = [ 993 465 ];
};

client = { nodes, ... }: {
Expand Down