181 lines
5.5 KiB
Nix
181 lines
5.5 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
let
|
|
cfg = config.fudo.services.mail-server;
|
|
|
|
hostname = config.instance.hostname;
|
|
domain-name = config.instance.local-domain;
|
|
domain = config.fudo.domains.${domain-name};
|
|
|
|
mailserver-host = domain.primary-mailserver;
|
|
mailserver-domain-name = config.fudo.hosts.${mailserver-host}.domain;
|
|
mailserver-domain = config.fudo.domains.${mailserver-domain-name};
|
|
|
|
mailserver-host-fqdn = "${mailserver-host}.${mailserver-domain-name}";
|
|
|
|
isMailServer = hostname == mailserver-host;
|
|
|
|
isLocalMailserver = domain-name == mailserver-domain-name;
|
|
|
|
metricsEnabled = mailserver-domain.prometheus-hosts != [];
|
|
|
|
host-certs = config.fudo.acme.host-domains.${hostname};
|
|
|
|
in {
|
|
options.fudo.services.mail-server = with types; {
|
|
debug = mkEnableOption "Enable debug options for mailserver.";
|
|
|
|
state-directory = mkOption {
|
|
type = str;
|
|
description = "Directory at which to store mailserver state.";
|
|
};
|
|
};
|
|
|
|
config = {
|
|
services.nginx = mkIf (isMailServer && metricsEnabled) {
|
|
enable = true;
|
|
recommendedOptimisation = true;
|
|
recommendedProxySettings = true;
|
|
|
|
virtualHosts."mail-stats.${mailserver-domain-name}" = let
|
|
trusted-networks = config.instance.local-networks;
|
|
trustedNetworkString = optionalString (length trusted-networks > 0)
|
|
(concatStringsSep "\n"
|
|
(map (network: "allow ${network};")
|
|
trusted-networks)) + "\n\ndeny all;";
|
|
in {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
|
|
locations = let
|
|
monitor-cfg = config.fudo.mail-server.monitoring;
|
|
in {
|
|
"/metrics/dovecot" = {
|
|
proxyPass = "http://127.0.0.1:${toString monitor-cfg.dovecot-listen-port}/metrics";
|
|
extraConfig = trustedNetworkString;
|
|
};
|
|
"/metrics/postfix" = {
|
|
proxyPass = "http://127.0.0.1:${toString monitor-cfg.postfix-listen-port}/metrics";
|
|
extraConfig = trustedNetworkString;
|
|
};
|
|
"/metrics/rspamd" = {
|
|
proxyPass = "http://127.0.0.1:${toString monitor-cfg.rspamd-listen-port}/metrics";
|
|
extraConfig = trustedNetworkString;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
fudo = {
|
|
acme.host-domains = mkIf isMailServer {
|
|
${hostname} = {
|
|
"imap.${mailserver-domain-name}" = {
|
|
admin-email = "admin@${mailserver-domain-name}";
|
|
local-copies.dovecot = {
|
|
user = config.services.dovecot2.user;
|
|
dependent-services = [ "dovecot2.services" ];
|
|
};
|
|
};
|
|
"smtp.${mailserver-domain-name}" = {
|
|
admin-email = "admin@${mailserver-domain-name}";
|
|
local-copies.postfix = {
|
|
user = config.services.postfix.user;
|
|
dependent-services = [ "postfix.services" ];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
zones = mkIf isLocalMailserver {
|
|
${mailserver-domain.zone} = let
|
|
server-ipv4 = pkgs.lib.network.host-ipv4 config mailserver-host;
|
|
server-ipv6 = pkgs.lib.network.host-ipv6 config mailserver-host;
|
|
|
|
srv-record = host: port: [{
|
|
host = "${host}.${mailserver-domain-name}";
|
|
port = port;
|
|
}];
|
|
|
|
in {
|
|
hosts = genAttrs [ "imap" "smtp" ] (alias: {
|
|
ipv4-address = server-ipv4;
|
|
ipv6-address = server-ipv6;
|
|
description = "Primary ${toUpper alias} server for ${mailserver-domain-name}.";
|
|
});
|
|
|
|
mx = [ "smtp.${mailserver-domain-name}" ];
|
|
|
|
aliases = mkIf metricsEnabled {
|
|
mail-stats = "${mailserver-host-fqdn}.";
|
|
};
|
|
|
|
srv-records.tcp = {
|
|
pop3 = srv-record "imap" 110;
|
|
pop3s = srv-record "imap" 995;
|
|
|
|
imap = srv-record "imap" 143;
|
|
imaps = srv-record "imap" 993;
|
|
|
|
smtp = srv-record "smtp" 25;
|
|
submission = srv-record "smtp" 587;
|
|
};
|
|
|
|
metric-records = mkIf metricsEnabled
|
|
(genAttrs [ "dovecot" "postfix" "rspamd" ]
|
|
(_: srv-record "mail-stats" 443));
|
|
};
|
|
};
|
|
|
|
metrics.prometheus.service-discovery-dns = mkIf metricsEnabled
|
|
(genAttrs [ "dovecot" "postfix" "rspamd" ]
|
|
(mtype: [ "${mtype}._metrics._tcp.${mailserver-domain-name}" ]));
|
|
|
|
mail-server = mkIf isLocalMailserver {
|
|
enable = isMailServer;
|
|
|
|
domain = mailserver-domain-name;
|
|
mail-hostname = "smtp.${mailserver-domain-name}";
|
|
monitoring.enable = metricsEnabled;
|
|
|
|
debug = cfg.debug;
|
|
|
|
clamav.enable = true;
|
|
|
|
dkim.signing = true;
|
|
|
|
dovecot = let
|
|
cert-copy = host-certs."imap.${mailserver-domain-name}".local-copies.dovecot;
|
|
in {
|
|
ssl-certificate = cert-copy.full-certificate;
|
|
ssl-private-key = cert-copy.private-key;
|
|
};
|
|
|
|
postfix = let
|
|
cert-copy = host-certs."smtp.${mailserver-domain-name}".local-copies.postfix;
|
|
in {
|
|
ssl-certificate = cert-copy.full-certificate;
|
|
ssl-private-key = cert-copy.private-key;
|
|
};
|
|
|
|
local-domains = [ mailserver-host-fqdn "smtp.${mailserver-domain-name}" ];
|
|
|
|
mail-directory = "${cfg.state-directory}/mail";
|
|
state-directory = "${cfg.state-directory}/state";
|
|
|
|
trusted-networks = config.instance.local-networks;
|
|
|
|
alias-users = genAttrs [
|
|
"root"
|
|
"postmaster"
|
|
"hostmaster"
|
|
"webmaster"
|
|
"system"
|
|
"admin"
|
|
"dmarc-report"
|
|
] (alias: config.instance.local-admins);
|
|
};
|
|
};
|
|
};
|
|
}
|