Merge branch 'autoconfig' into 'master'

Add support for Mozilla-style autoconfig

See merge request simple-nixos-mailserver/nixos-mailserver!188
This commit is contained in:
James Kay 2024-12-24 01:26:24 +00:00
commit 92a1729f36
4 changed files with 178 additions and 0 deletions

View file

@ -1298,6 +1298,7 @@ in
imports = [ imports = [
./mail-server/assertions.nix ./mail-server/assertions.nix
./mail-server/autoconfig
./mail-server/borgbackup.nix ./mail-server/borgbackup.nix
./mail-server/debug.nix ./mail-server/debug.nix
./mail-server/rsnapshot.nix ./mail-server/rsnapshot.nix

View file

@ -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 <emailProvider> 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);
};
}

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<clientConfig version="1.1">
<emailProvider id="@emailProviderId@">
@domains@
<displayName>@displayName@</displayName>
<displayShortName>@displayShortName</displayShortName>
@imapSslServer@
@imapServer@
@pop3SslServer@
@pop3Server@
<outgoingServer type="smtp">
<hostname>@fqdn@</hostname>
<port>587</port>
<socketType>STARTTLS</socketType>
<authentication>password-cleartext</authentication>
<username>%EMAILADDRESS%</username>
</outgoingServer>
<outgoingServer type="smtp">
<hostname>@fqdn@</hostname>
<port>25</port>
<socketType>STARTTLS</socketType>
<authentication>password-cleartext</authentication>
<username>%EMAILADDRESS%</username>
</outgoingServer>
@extraEmailProvider@
</emailProvider>
</clientConfig>

View file

@ -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 ''
<incomingServer type="imap">
<hostname>${ms.fqdn}</hostname>
<port>${builtins.toString port}</port>
<socketType>${socketType}</socketType>
<authentication>password-cleartext</authentication>
<username>%EMAILADDRESS%</username>
</incomingServer>
'';
# we currently only support STARTTLS for outgoing servers
outgoingServer = port: ''
<outgoingServer type="smtp">
<hostname>${ms.fqdn}</hostname>
<port>${builtins.toString port}</port>
<socketType>STARTTLS</socketType>
<authentication>password-cleartext</authentication>
<username>%EMAILADDRESS%</username>
</outgoingServer>
'';
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: "<domain>${x}</domain>")
cfg.domains;
});
}