assume a dns cname record mail.<domain>, pointing to the hostname of the mail server, for clients to connect to

the autoconfig/autodiscover endpoints, and the printed client settings (in
quickstart, in the admin interface) now all point to the cname record (called
"client settings domain"). it is configurable per domain, and set to
"mail.<domain>" by default. for existing mox installs, the domain can be added
by editing the config file.

this makes it easier for a domain to migrate to another server in the future.
client settings don't have to be updated, the cname can just be changed.
before, the hostname of the mail server was configured in email clients.
migrating away would require changing settings in all clients.

if a client settings domain is configured, a TLS certificate for the name will
be requested through ACME, or must be configured manually.
This commit is contained in:
Mechiel Lukkien
2023-12-24 11:01:16 +01:00
parent e7478ed6ac
commit da3ed38a5c
8 changed files with 80 additions and 9 deletions

View File

@ -343,7 +343,8 @@ type SRVConfCheckResult struct {
}
type AutoconfCheckResult struct {
IPs []string
ClientSettingsDomainIPs []string
IPs []string
Result
}
@ -440,7 +441,7 @@ func checkDomain(ctx context.Context, resolver dns.Resolver, dialer *net.Dialer,
*l = append(*l, fmt.Sprintf(format, args...))
}
// host must be an absolute dns name, ending with a dot.
// Host must be an absolute dns name, ending with a dot.
lookupIPs := func(errors *[]string, host string) (ips []string, ourIPs, notOurIPs []net.IP, rerr error) {
addrs, _, err := resolver.LookupHost(ctx, host)
if err != nil {
@ -1383,6 +1384,23 @@ When enabling MTA-STS, or updating a policy, always update the policy first (thr
defer logPanic(ctx)
defer wg.Done()
if domConf.ClientSettingsDomain != "" {
addf(&r.Autoconf.Instructions, "Ensure a DNS CNAME record like the following exists:\n\n\t%s CNAME %s\n\nNote: the trailing dot is relevant, it makes the host name absolute instead of relative to the domain name.", domConf.ClientSettingsDNSDomain.ASCII+".", mox.Conf.Static.HostnameDomain.ASCII+".")
ips, ourIPs, notOurIPs, err := lookupIPs(&r.Autoconf.Errors, domConf.ClientSettingsDNSDomain.ASCII+".")
if err != nil {
addf(&r.Autoconf.Errors, "Looking up client settings DNS CNAME: %s", err)
}
r.Autoconf.ClientSettingsDomainIPs = ips
if !isUnspecifiedNAT {
if len(ourIPs) == 0 {
addf(&r.Autoconf.Errors, "Client settings domain does not point to one of our IPs.")
} else if len(notOurIPs) > 0 {
addf(&r.Autoconf.Errors, "Client settings domain points to some IPs that are not ours: %v", notOurIPs)
}
}
}
addf(&r.Autoconf.Instructions, "Ensure a DNS CNAME record like the following exists:\n\n\tautoconfig.%s CNAME %s\n\nNote: the trailing dot is relevant, it makes the host name absolute instead of relative to the domain name.", domain.ASCII+".", mox.Conf.Static.HostnameDomain.ASCII+".")
host := "autoconfig." + domain.ASCII + "."

View File

@ -1025,8 +1025,9 @@ const domainDNSCheck = async (d) => {
}),
),
]
const detailsAutoconf = !checks.Autoconf.IPs ? [] : [
dom.div('IPs: ' + checks.Autoconf.IPs.join(', ')),
const detailsAutoconf = [
...(!checks.Autoconf.ClientSettingsDomainIPs ? [] : [dom.div('Client settings domain IPs: ' + checks.Autoconf.ClientSettingsDomainIPs.join(', '))]),
...(!checks.Autoconf.IPs ? [] : [dom.div('IPs: ' + checks.Autoconf.IPs.join(', '))]),
]
const detailsAutodiscover = !checks.Autodiscover.Records ? [] : [
dom.table(

View File

@ -2225,6 +2225,14 @@
"Name": "AutoconfCheckResult",
"Docs": "",
"Fields": [
{
"Name": "ClientSettingsDomainIPs",
"Docs": "",
"Typewords": [
"[]",
"string"
]
},
{
"Name": "IPs",
"Docs": "",