diff --git a/default.nix b/default.nix index ac75bce..56d7ebd 100644 --- a/default.nix +++ b/default.nix @@ -1298,6 +1298,7 @@ in imports = [ ./mail-server/assertions.nix + ./mail-server/autoconfig ./mail-server/borgbackup.nix ./mail-server/debug.nix ./mail-server/rsnapshot.nix diff --git a/mail-server/autoconfig/default.nix b/mail-server/autoconfig/default.nix new file mode 100644 index 0000000..4877941 --- /dev/null +++ b/mail-server/autoconfig/default.nix @@ -0,0 +1,100 @@ +{ config, lib, pkgs, ... }: +with lib; +let + ms = config.mailserver; + cfg = ms.autoconfig; +in +{ + imports = [ ./webroot.nix ]; + + options.mailserver.autoconfig = mkOption { + description = '' + Generate a simple static Mozilla-style autoconfig. + + See + https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration + for further information on the file format. + + Note that for each domain in `domains`, this will generate a + nginx `virtualHost` for the `autoconfig` subdomain of that + domain. + + In order for autoconfig to work, those domains must be + accessible (i.e. have DNS records). + ''; + type = types.submodule { + options = { + enable = mkEnableOption "Mozilla-style autoconfig (requires nginx)"; + + emailProviderId = mkOption { + type = types.str; + example = "example.com"; + default = ms.fqdn; + defaultText = "config.mailserver.fqdn"; + description = '' + An ID for the email provider. + ''; + }; + + domains = mkOption { + type = types.listOf types.str; + example = [ "example.com" "example.net" ]; + default = ms.domains; + defaultText = "config.mailserver.domains"; + description = '' + A list of domains for which to enable autoconfig. + ''; + }; + + displayName = mkOption { + type = types.str; + example = "Joe's Email Provider"; + default = cfg.emailProviderId; + defaultText = "config.mailserver.autoconfig.id"; + description = '' + A user-readable name for the email provider. + ''; + }; + + displayShortName = mkOption { + type = types.str; + example = "JoeMail"; + default = cfg.displayName; + defaultText = "config.mailserver.autoconfig.displayName"; + description = '' + A "short" user-readable name for the email provider. + ''; + }; + + templateFile = mkOption { + type = types.path; + example = "/path/to/template.xml"; + default = ./template.xml; + description = '' + A path to a template file to use. + ''; + }; + + extraEmailProvider = mkOption { + type = types.lines; + default = ""; + description = '' + Extra XML to be embedded at the end of the element. + ''; + }; + + webRoot = mkOption { + type = types.path; + visible = false; + }; + }; + }; + }; + + config = mkIf config.mailserver.autoconfig.enable { + services.nginx.enable = true; + services.nginx.virtualHosts = mkMerge (map (domain: { + "autoconfig.${domain}".root = cfg.webRoot; + }) cfg.domains); + }; +} diff --git a/mail-server/autoconfig/template.xml b/mail-server/autoconfig/template.xml new file mode 100644 index 0000000..ab305db --- /dev/null +++ b/mail-server/autoconfig/template.xml @@ -0,0 +1,28 @@ + + + + + @domains@ + @displayName@ + @displayShortName + @imapSslServer@ + @imapServer@ + @pop3SslServer@ + @pop3Server@ + + @fqdn@ + 587 + STARTTLS + password-cleartext + %EMAILADDRESS% + + + @fqdn@ + 25 + STARTTLS + password-cleartext + %EMAILADDRESS% + + @extraEmailProvider@ + + diff --git a/mail-server/autoconfig/webroot.nix b/mail-server/autoconfig/webroot.nix new file mode 100644 index 0000000..ea9a319 --- /dev/null +++ b/mail-server/autoconfig/webroot.nix @@ -0,0 +1,49 @@ +{ config, lib, pkgs, ... }: +with lib; +let + ms = config.mailserver; + cfg = ms.autoconfig; + + # none of the available parameters are configurable in + # simple-mailserver so these templates aren't configurable either + incomingServer = enable: port: socketType: optionalString enable '' + + ${ms.fqdn} + ${builtins.toString port} + ${socketType} + password-cleartext + %EMAILADDRESS% + + ''; + + # we currently only support STARTTLS for outgoing servers + outgoingServer = port: '' + + ${ms.fqdn} + ${builtins.toString port} + STARTTLS + password-cleartext + %EMAILADDRESS% + + ''; +in { + mailserver.autoconfig.webRoot = pkgs.substituteAll ({ + name = "config-v1.1.xml"; + dir = "mail"; + src = cfg.templateFile; + } // { + hostname = ms.fqdn; + inherit (cfg) + emailProviderId displayName displayShortName extraEmailProvider; + imapSslServer = incomingServer ms.enableImapSsl 993 "SSL"; + imapServer = incomingServer ms.enableImapSsl 143 "STARTTLS"; + pop3SslServer = incomingServer ms.enablePop3Ssl 995 "SSL"; + pop3Server = incomingServer ms.enablePop3 110 "STARTTLS"; + smtpServer = outgoingServer 25; + submissionServer = outgoingServer 587; + domains = concatMapStringsSep + "\n " + (x: "${x}") + cfg.domains; + }); +}