when suggesting DNS records, leave "IN" out

people will either paste the records in their zone file. in that case, the
records will inherit "IN" from earlier records, and there will always be one
record. if anyone uses a different class, their smart enough to know they need
to add IN manually.

plenty of people will add their records through some clunky web interface of
their dns operator. they probably won't even have the choice to set the class,
it'll always be IN.
This commit is contained in:
Mechiel Lukkien 2023-10-13 08:16:46 +02:00
parent 52e71167a9
commit 850f4444d4
No known key found for this signature in database
9 changed files with 52 additions and 52 deletions

2
doc.go
View file

@ -660,7 +660,7 @@ Common DANE TLSA record parameters are: dane-ee spki sha2-256, or 3 1 1,
followed by a sha2-256 hash of the DER-encoded "SPKI" (subject public key info) followed by a sha2-256 hash of the DER-encoded "SPKI" (subject public key info)
from the certificate. An example DNS zone file entry: from the certificate. An example DNS zone file entry:
_25._tcp.example.com. IN TLSA 3 1 1 133b919c9d65d8b1488157315327334ead8d83372db57465ecabf53ee5748aee _25._tcp.example.com. TLSA 3 1 1 133b919c9d65d8b1488157315327334ead8d83372db57465ecabf53ee5748aee
The first usable information from the pem file is used to compose the TLSA The first usable information from the pem file is used to compose the TLSA
record. In case of selector "cert", a certificate is required. Otherwise the record. In case of selector "cert", a certificate is required. Otherwise the

View file

@ -133,7 +133,7 @@ func autoconfHandle(w http.ResponseWriter, r *http.Request) {
} }
// Autodiscover from Microsoft, also used by Thunderbird. // Autodiscover from Microsoft, also used by Thunderbird.
// User should create a DNS record: _autodiscover._tcp.<domain> IN SRV 0 0 443 <hostname or autodiscover.<domain>> // User should create a DNS record: _autodiscover._tcp.<domain> SRV 0 0 443 <hostname>
// //
// In practice, autodiscover does not seem to work wit microsoft clients. A // In practice, autodiscover does not seem to work wit microsoft clients. A
// connectivity test tool for outlook is available on // connectivity test tool for outlook is available on

View file

@ -1809,7 +1809,7 @@ Common DANE TLSA record parameters are: dane-ee spki sha2-256, or 3 1 1,
followed by a sha2-256 hash of the DER-encoded "SPKI" (subject public key info) followed by a sha2-256 hash of the DER-encoded "SPKI" (subject public key info)
from the certificate. An example DNS zone file entry: from the certificate. An example DNS zone file entry:
_25._tcp.example.com. IN TLSA 3 1 1 133b919c9d65d8b1488157315327334ead8d83372db57465ecabf53ee5748aee _25._tcp.example.com. TLSA 3 1 1 133b919c9d65d8b1488157315327334ead8d83372db57465ecabf53ee5748aee
The first usable information from the pem file is used to compose the TLSA The first usable information from the pem file is used to compose the TLSA
record. In case of selector "cert", a certificate is required. Otherwise the record. In case of selector "cert", a certificate is required. Otherwise the
@ -2131,7 +2131,7 @@ The DNS should be configured as a TXT record at $selector._domainkey.$domain.
record, err := r.Record() record, err := r.Record()
xcheckf(err, "making record") xcheckf(err, "making record")
fmt.Print("<selector>._domainkey.<your.domain.> IN TXT ") fmt.Print("<selector>._domainkey.<your.domain.> TXT ")
for record != "" { for record != "" {
s := record s := record
if len(s) > 255 { if len(s) > 255 {

View file

@ -495,9 +495,9 @@ func DomainRecords(domConf config.Domain, domain dns.Domain, hasDNSSEC bool) ([]
} }
var s string var s string
if hasDNSSEC { if hasDNSSEC {
s = fmt.Sprintf("_25._tcp.%-*s IN TLSA %s", 20+len(d)-len("_25._tcp."), h+".", tlsaRecord.Record()) s = fmt.Sprintf("_25._tcp.%-*s TLSA %s", 20+len(d)-len("_25._tcp."), h+".", tlsaRecord.Record())
} else { } else {
s = fmt.Sprintf(";; _25._tcp.%-*s IN TLSA %s", 20+len(d)-len(";; _25._tcp."), h+".", tlsaRecord.Record()) s = fmt.Sprintf(";; _25._tcp.%-*s TLSA %s", 20+len(d)-len(";; _25._tcp."), h+".", tlsaRecord.Record())
} }
records = append(records, s) records = append(records, s)
return nil return nil
@ -518,7 +518,7 @@ func DomainRecords(domConf config.Domain, domain dns.Domain, hasDNSSEC bool) ([]
if d != h { if d != h {
records = append(records, records = append(records,
"; For the machine, only needs to be created once, for the first domain added.", "; For the machine, only needs to be created once, for the first domain added.",
fmt.Sprintf(`%-*s IN TXT "v=spf1 a -all"`, 20+len(d), h+"."), // ../rfc/7208:2263 ../rfc/7208:2287 fmt.Sprintf(`%-*s TXT "v=spf1 a -all"`, 20+len(d), h+"."), // ../rfc/7208:2263 ../rfc/7208:2287
"", "",
) )
} }
@ -561,7 +561,7 @@ func DomainRecords(domConf config.Domain, domain dns.Domain, hasDNSSEC bool) ([]
"; of multiple strings (max size of each is 255 bytes).", "; of multiple strings (max size of each is 255 bytes).",
) )
} }
s := fmt.Sprintf("%s._domainkey.%s. IN TXT %s", name, d, TXTStrings(txt)) s := fmt.Sprintf("%s._domainkey.%s. TXT %s", name, d, TXTStrings(txt))
records = append(records, s) records = append(records, s)
} }
@ -582,14 +582,14 @@ func DomainRecords(domConf config.Domain, domain dns.Domain, hasDNSSEC bool) ([]
"; Specify the MX host is allowed to send for our domain and for itself (for DSNs).", "; Specify the MX host is allowed to send for our domain and for itself (for DSNs).",
"; ~all means softfail for anything else, which is done instead of -all to prevent older", "; ~all means softfail for anything else, which is done instead of -all to prevent older",
"; mail servers from rejecting the message because they never get to looking for a dkim/dmarc pass.", "; mail servers from rejecting the message because they never get to looking for a dkim/dmarc pass.",
fmt.Sprintf(`%s. IN TXT "v=spf1 mx ~all"`, d), fmt.Sprintf(`%s. TXT "v=spf1 mx ~all"`, d),
"", "",
"; Emails that fail the DMARC check (without aligned DKIM and without aligned SPF)", "; Emails that fail the DMARC check (without aligned DKIM and without aligned SPF)",
"; should be rejected, and request reports. If you email through mailing lists that", "; should be rejected, and request reports. If you email through mailing lists that",
"; strip DKIM-Signature headers and don't rewrite the From header, you may want to", "; strip DKIM-Signature headers and don't rewrite the From header, you may want to",
"; set the policy to p=none.", "; set the policy to p=none.",
fmt.Sprintf(`_dmarc.%s. IN TXT "%s"`, d, dmarcr.String()), fmt.Sprintf(`_dmarc.%s. TXT "%s"`, d, dmarcr.String()),
"", "",
) )
@ -598,8 +598,8 @@ func DomainRecords(domConf config.Domain, domain dns.Domain, hasDNSSEC bool) ([]
"; Remote servers can use MTA-STS to verify our TLS certificate with the", "; Remote servers can use MTA-STS to verify our TLS certificate with the",
"; WebPKI pool of CA's (certificate authorities) when delivering over SMTP with", "; WebPKI pool of CA's (certificate authorities) when delivering over SMTP with",
"; STARTTLSTLS.", "; STARTTLSTLS.",
fmt.Sprintf(`mta-sts.%s. IN CNAME %s.`, d, h), fmt.Sprintf(`mta-sts.%s. CNAME %s.`, d, h),
fmt.Sprintf(`_mta-sts.%s. IN TXT "v=STSv1; id=%s"`, d, sts.PolicyID), fmt.Sprintf(`_mta-sts.%s. TXT "v=STSv1; id=%s"`, d, sts.PolicyID),
"", "",
) )
} else { } else {
@ -618,36 +618,36 @@ func DomainRecords(domConf config.Domain, domain dns.Domain, hasDNSSEC bool) ([]
tlsrptr := tlsrpt.Record{Version: "TLSRPTv1", RUAs: [][]string{{uri.String()}}} tlsrptr := tlsrpt.Record{Version: "TLSRPTv1", RUAs: [][]string{{uri.String()}}}
records = append(records, records = append(records,
"; Request reporting about TLS failures.", "; Request reporting about TLS failures.",
fmt.Sprintf(`_smtp._tls.%s. IN TXT "%s"`, d, tlsrptr.String()), fmt.Sprintf(`_smtp._tls.%s. TXT "%s"`, d, tlsrptr.String()),
"", "",
) )
} }
records = append(records, records = append(records,
"; Autoconfig is used by Thunderbird. Autodiscover is (in theory) used by Microsoft.", "; Autoconfig is used by Thunderbird. Autodiscover is (in theory) used by Microsoft.",
fmt.Sprintf(`autoconfig.%s. IN CNAME %s.`, d, h), fmt.Sprintf(`autoconfig.%s. CNAME %s.`, d, h),
fmt.Sprintf(`_autodiscover._tcp.%s. IN SRV 0 1 443 autoconfig.%s.`, d, d), fmt.Sprintf(`_autodiscover._tcp.%s. SRV 0 1 443 autoconfig.%s.`, d, d),
"", "",
// ../rfc/6186:133 ../rfc/8314:692 // ../rfc/6186:133 ../rfc/8314:692
"; For secure IMAP and submission autoconfig, point to mail host.", "; For secure IMAP and submission autoconfig, point to mail host.",
fmt.Sprintf(`_imaps._tcp.%s. IN SRV 0 1 993 %s.`, d, h), fmt.Sprintf(`_imaps._tcp.%s. SRV 0 1 993 %s.`, d, h),
fmt.Sprintf(`_submissions._tcp.%s. IN SRV 0 1 465 %s.`, d, h), fmt.Sprintf(`_submissions._tcp.%s. SRV 0 1 465 %s.`, d, h),
"", "",
// ../rfc/6186:242 // ../rfc/6186:242
"; Next records specify POP3 and non-TLS ports are not to be used.", "; Next records specify POP3 and non-TLS ports are not to be used.",
"; These are optional and safe to leave out (e.g. if you have to click a lot in a", "; These are optional and safe to leave out (e.g. if you have to click a lot in a",
"; DNS admin web interface).", "; DNS admin web interface).",
fmt.Sprintf(`_imap._tcp.%s. IN SRV 0 1 143 .`, d), fmt.Sprintf(`_imap._tcp.%s. SRV 0 1 143 .`, d),
fmt.Sprintf(`_submission._tcp.%s. IN SRV 0 1 587 .`, d), fmt.Sprintf(`_submission._tcp.%s. SRV 0 1 587 .`, d),
fmt.Sprintf(`_pop3._tcp.%s. IN SRV 0 1 110 .`, d), fmt.Sprintf(`_pop3._tcp.%s. SRV 0 1 110 .`, d),
fmt.Sprintf(`_pop3s._tcp.%s. IN SRV 0 1 995 .`, d), fmt.Sprintf(`_pop3s._tcp.%s. SRV 0 1 995 .`, d),
"", "",
"; Optional:", "; Optional:",
"; You could mark Let's Encrypt as the only Certificate Authority allowed to", "; You could mark Let's Encrypt as the only Certificate Authority allowed to",
"; sign TLS certificates for your domain.", "; sign TLS certificates for your domain.",
fmt.Sprintf("%s. IN CAA 0 issue \"letsencrypt.org\"", d), fmt.Sprintf("%s. CAA 0 issue \"letsencrypt.org\"", d),
) )
return records, nil return records, nil
} }

View file

@ -5,14 +5,14 @@ $TTL 5m
@ NS dns.example. @ NS dns.example.
moxacmepebble.mox1 IN A 172.28.1.10 moxacmepebble.mox1 A 172.28.1.10
moxmail2.mox2 IN A 172.28.1.20 moxmail2.mox2 A 172.28.1.20
dns IN A 172.28.1.30 dns A 172.28.1.30
acmepebble IN A 172.28.1.40 acmepebble A 172.28.1.40
test IN A 172.28.1.50 test A 172.28.1.50
localserve.mox1 IN A 172.28.1.60 localserve.mox1 A 172.28.1.60
postfixmail.postfix IN A 172.28.1.70 postfixmail.postfix A 172.28.1.70
postfix MX 10 postfixmail.postfix.example. postfix MX 10 postfixmail.postfix.example.
postfixdkim0._domainkey.postfix IN TXT "v=DKIM1;h=sha256;t=s;k=ed25519;p=a4IsBTuMsSQjU+xVyx8KEd8eObis4FrCiV72OaEkvDY=" postfixdkim0._domainkey.postfix TXT "v=DKIM1;h=sha256;t=s;k=ed25519;p=a4IsBTuMsSQjU+xVyx8KEd8eObis4FrCiV72OaEkvDY="
postfix IN TXT "v=spf1 ip4:172.28.1.20 -all" postfix TXT "v=spf1 ip4:172.28.1.20 -all"

View file

@ -22,9 +22,9 @@ EOF
( (
cat /integration/example.zone; cat /integration/example.zone;
sed -n '/^;/,/IN CAA/p' output.txt | sed -n '/^;/,/CAA /p' output.txt |
# allow sending from postfix for mox1.example. # allow sending from postfix for mox1.example.
sed 's/mox1.example. *IN TXT "v=spf1 mx ~all"/mox1.example. IN TXT "v=spf1 mx ip4:172.28.1.70 ~all"/' sed 's/mox1.example. *TXT "v=spf1 mx ~all"/mox1.example. TXT "v=spf1 mx ip4:172.28.1.70 ~all"/'
) >/integration/example-integration.zone ) >/integration/example-integration.zone
unbound-control -s 172.28.1.30 reload # reload unbound with zone file changes unbound-control -s 172.28.1.30 reload # reload unbound with zone file changes

View file

@ -23,7 +23,7 @@ TLS:
EOF EOF
# A fresh file was set up by moxacmepebble. # A fresh file was set up by moxacmepebble.
sed -n '/^;/,/IN CAA/p' output.txt >>/integration/example-integration.zone sed -n '/^;/,/CAA /p' output.txt >>/integration/example-integration.zone
unbound-control -s 172.28.1.30 reload # reload unbound with zone file changes unbound-control -s 172.28.1.30 reload # reload unbound with zone file changes
mox -checkconsistency serve & mox -checkconsistency serve &

View file

@ -3,10 +3,10 @@ $TTL 5m
@ IN SOA dns.example. hostmaster.example. (1 0m 0m 0m 5m) @ IN SOA dns.example. hostmaster.example. (1 0m 0m 0m 5m)
10.1 IN PTR moxacmepebble.mox1.example. 10.1 PTR moxacmepebble.mox1.example.
20.1 IN PTR moxmail2.mox2.example. 20.1 PTR moxmail2.mox2.example.
30.1 IN PTR dns.example. 30.1 PTR dns.example.
40.1 IN PTR acmepebble.example. 40.1 PTR acmepebble.example.
50.1 IN PTR test.example. 50.1 PTR test.example.
60.1 IN PTR localserve.mox1.example. 60.1 PTR localserve.mox1.example.
70.1 IN PTR postfixmail.postfix.example. 70.1 PTR postfixmail.postfix.example.

View file

@ -976,10 +976,10 @@ EOF
if err != nil { if err != nil {
addf(&r.SPF.Errors, "Making SPF record for instructions: %s", err) addf(&r.SPF.Errors, "Making SPF record for instructions: %s", err)
} }
domainspf := fmt.Sprintf("%s IN TXT %s", domain.ASCII+".", mox.TXTStrings(dtxt)) domainspf := fmt.Sprintf("%s TXT %s", domain.ASCII+".", mox.TXTStrings(dtxt))
// Check SPF record for sending host. ../rfc/7208:2263 ../rfc/7208:2287 // Check SPF record for sending host. ../rfc/7208:2263 ../rfc/7208:2287
hostspf := fmt.Sprintf(`%s IN TXT "v=spf1 a -all"`, mox.Conf.Static.HostnameDomain.ASCII+".") hostspf := fmt.Sprintf(`%s TXT "v=spf1 a -all"`, mox.Conf.Static.HostnameDomain.ASCII+".")
addf(&r.SPF.Instructions, "Ensure DNS TXT records like the following exists:\n\n\t%s\n\t%s\n\nIf you have an existing mail setup, with other hosts also sending mail for you domain, you should add those IPs as well. You could replace \"-all\" with \"~all\" to treat mail sent from unlisted IPs as \"softfail\", or with \"?all\" for \"neutral\".", domainspf, hostspf) addf(&r.SPF.Instructions, "Ensure DNS TXT records like the following exists:\n\n\t%s\n\t%s\n\nIf you have an existing mail setup, with other hosts also sending mail for you domain, you should add those IPs as well. You could replace \"-all\" with \"~all\" to treat mail sent from unlisted IPs as \"softfail\", or with \"?all\" for \"neutral\".", domainspf, hostspf)
}() }()
@ -1058,7 +1058,7 @@ EOF
addf(&r.DKIM.Errors, "Making DKIM record for instructions: %s", err) addf(&r.DKIM.Errors, "Making DKIM record for instructions: %s", err)
continue continue
} }
instr += fmt.Sprintf("\n\t%s._domainkey IN TXT %s\n", sel, mox.TXTStrings(txt)) instr += fmt.Sprintf("\n\t%s._domainkey TXT %s\n", sel, mox.TXTStrings(txt))
} }
if instr != "" { if instr != "" {
instr = "Ensure the following DNS record(s) exists, so mail servers receiving emails from this domain can verify the signatures in the mail headers:\n" + instr instr = "Ensure the following DNS record(s) exists, so mail servers receiving emails from this domain can verify the signatures in the mail headers:\n" + instr
@ -1111,7 +1111,7 @@ EOF
} else if !accepts { } else if !accepts {
addf(&r.DMARC.Errors, "External destination does not accept reports (%s)", err) addf(&r.DMARC.Errors, "External destination does not accept reports (%s)", err)
} }
extInstr = fmt.Sprintf("Ensure a DNS TXT record exists in the domain of the destination address to opt-in to receiving reports from this domain:\n\n\t%s._report._dmarc.%s. IN TXT \"v=DMARC1;\"\n\n", domain.ASCII, domConf.DMARC.DNSDomain.ASCII) extInstr = fmt.Sprintf("Ensure a DNS TXT record exists in the domain of the destination address to opt-in to receiving reports from this domain:\n\n\t%s._report._dmarc.%s. TXT \"v=DMARC1;\"\n\n", domain.ASCII, domConf.DMARC.DNSDomain.ASCII)
} }
uri := url.URL{ uri := url.URL{
@ -1124,7 +1124,7 @@ EOF
} else { } else {
addf(&r.DMARC.Instructions, `Configure a DMARC destination in domain in config file.`) addf(&r.DMARC.Instructions, `Configure a DMARC destination in domain in config file.`)
} }
instr := fmt.Sprintf("Ensure a DNS TXT record like the following exists:\n\n\t_dmarc IN TXT %s\n\nYou can start with testing mode by replacing p=reject with p=none. You can also request for the policy to be applied to a percentage of emails instead of all, by adding pct=X, with X between 0 and 100. Keep in mind that receiving mail servers will apply some anti-spam assessment regardless of the policy and whether it is applied to the message. The ruf= part requests daily aggregate reports to be sent to the specified address, which is automatically configured and reports automatically analyzed.", mox.TXTStrings(dmarcr.String())) instr := fmt.Sprintf("Ensure a DNS TXT record like the following exists:\n\n\t_dmarc TXT %s\n\nYou can start with testing mode by replacing p=reject with p=none. You can also request for the policy to be applied to a percentage of emails instead of all, by adding pct=X, with X between 0 and 100. Keep in mind that receiving mail servers will apply some anti-spam assessment regardless of the policy and whether it is applied to the message. The ruf= part requests daily aggregate reports to be sent to the specified address, which is automatically configured and reports automatically analyzed.", mox.TXTStrings(dmarcr.String()))
addf(&r.DMARC.Instructions, instr) addf(&r.DMARC.Instructions, instr)
if extInstr != "" { if extInstr != "" {
addf(&r.DMARC.Instructions, extInstr) addf(&r.DMARC.Instructions, extInstr)
@ -1166,7 +1166,7 @@ EOF
Ensure a DNS TXT record like the following exists: Ensure a DNS TXT record like the following exists:
_smtp._tls IN TXT %s _smtp._tls TXT %s
`, mox.TXTStrings(tlsrptr.String())) `, mox.TXTStrings(tlsrptr.String()))
} else { } else {
addf(&r.TLSRPT.Errors, `Configure a TLSRPT destination in domain in config file.`) addf(&r.TLSRPT.Errors, `Configure a TLSRPT destination in domain in config file.`)
@ -1254,14 +1254,14 @@ When enabling MTA-STS, or updating a policy, always update the policy first (thr
addf(&r.MTASTS.Instructions, `Enable a policy through the configuration file. For new deployments, it is best to start with mode "testing" while enabling TLSRPT. Start with a short "max_age", so updates to your policy are picked up quickly. When confidence in the deployment is high enough, switch to "enforce" mode and a longer "max age". A max age in the order of weeks is recommended. If you foresee a change to your setup in the future, requiring different policies or MX records, you may want to dial back the "max age" ahead of time, similar to how you would handle TTL's in DNS record updates.`) addf(&r.MTASTS.Instructions, `Enable a policy through the configuration file. For new deployments, it is best to start with mode "testing" while enabling TLSRPT. Start with a short "max_age", so updates to your policy are picked up quickly. When confidence in the deployment is high enough, switch to "enforce" mode and a longer "max age". A max age in the order of weeks is recommended. If you foresee a change to your setup in the future, requiring different policies or MX records, you may want to dial back the "max age" ahead of time, similar to how you would handle TTL's in DNS record updates.`)
host := fmt.Sprintf("Ensure DNS CNAME/A/AAAA records exist that resolve mta-sts.%s to this mail server. For example:\n\n\t%s IN CNAME %s\n\n", domain.ASCII, "mta-sts."+domain.ASCII+".", mox.Conf.Static.HostnameDomain.ASCII+".") host := fmt.Sprintf("Ensure DNS CNAME/A/AAAA records exist that resolve mta-sts.%s to this mail server. For example:\n\n\t%s CNAME %s\n\n", domain.ASCII, "mta-sts."+domain.ASCII+".", mox.Conf.Static.HostnameDomain.ASCII+".")
addf(&r.MTASTS.Instructions, host) addf(&r.MTASTS.Instructions, host)
mtastsr := mtasts.Record{ mtastsr := mtasts.Record{
Version: "STSv1", Version: "STSv1",
ID: time.Now().Format("20060102T150405"), ID: time.Now().Format("20060102T150405"),
} }
dns := fmt.Sprintf("Ensure a DNS TXT record like the following exists:\n\n\t_mta-sts IN TXT %s\n\nConfigure the ID in the configuration file, it must be of the form [a-zA-Z0-9]{1,31}. It represents the version of the policy. For each policy change, you must change the ID to a new unique value. You could use a timestamp like 20220621T123000. When this field exists, an SMTP server will fetch a policy at https://mta-sts.%s/.well-known/mta-sts.txt. This policy is served by mox.", mox.TXTStrings(mtastsr.String()), domain.Name()) dns := fmt.Sprintf("Ensure a DNS TXT record like the following exists:\n\n\t_mta-sts TXT %s\n\nConfigure the ID in the configuration file, it must be of the form [a-zA-Z0-9]{1,31}. It represents the version of the policy. For each policy change, you must change the ID to a new unique value. You could use a timestamp like 20220621T123000. When this field exists, an SMTP server will fetch a policy at https://mta-sts.%s/.well-known/mta-sts.txt. This policy is served by mox.", mox.TXTStrings(mtastsr.String()), domain.Name())
addf(&r.MTASTS.Instructions, dns) addf(&r.MTASTS.Instructions, dns)
}() }()
@ -1318,7 +1318,7 @@ When enabling MTA-STS, or updating a policy, always update the policy first (thr
r.SRVConf.SRVs = map[string][]*net.SRV{} r.SRVConf.SRVs = map[string][]*net.SRV{}
for _, req := range reqs { for _, req := range reqs {
name := req.name + "_.tcp." + domain.ASCII name := req.name + "_.tcp." + domain.ASCII
instr += fmt.Sprintf("\t%s._tcp.%-*s IN SRV 0 1 %d %s\n", req.name, len("_submissions")-len(req.name)+len(domain.ASCII+"."), domain.ASCII+".", req.port, req.host) instr += fmt.Sprintf("\t%s._tcp.%-*s SRV 0 1 %d %s\n", req.name, len("_submissions")-len(req.name)+len(domain.ASCII+"."), domain.ASCII+".", req.port, req.host)
r.SRVConf.SRVs[req.name] = req.srvs r.SRVConf.SRVs[req.name] = req.srvs
if err != nil { if err != nil {
addf(&r.SRVConf.Errors, "Looking up SRV record %q: %s", name, err) addf(&r.SRVConf.Errors, "Looking up SRV record %q: %s", name, err)
@ -1337,7 +1337,7 @@ When enabling MTA-STS, or updating a policy, always update the policy first (thr
defer logPanic(ctx) defer logPanic(ctx)
defer wg.Done() defer wg.Done()
addf(&r.Autoconf.Instructions, "Ensure a DNS CNAME record like the following exists:\n\n\tautoconfig.%s IN 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+".") 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 + "." host := "autoconfig." + domain.ASCII + "."
ips, ourIPs, notOurIPs, err := lookupIPs(&r.Autoconf.Errors, host) ips, ourIPs, notOurIPs, err := lookupIPs(&r.Autoconf.Errors, host)
@ -1364,7 +1364,7 @@ When enabling MTA-STS, or updating a policy, always update the policy first (thr
defer logPanic(ctx) defer logPanic(ctx)
defer wg.Done() defer wg.Done()
addf(&r.Autodiscover.Instructions, "Ensure DNS records like the following exist:\n\n\t_autodiscover._tcp.%s IN SRV 0 1 443 autoconfig.%s\n\tautoconfig.%s IN CNAME %s\n\nNote: the trailing dots are relevant, it makes the host names absolute instead of relative to the domain name.", domain.ASCII+".", domain.ASCII+".", domain.ASCII+".", mox.Conf.Static.HostnameDomain.ASCII+".") addf(&r.Autodiscover.Instructions, "Ensure DNS records like the following exist:\n\n\t_autodiscover._tcp.%s SRV 0 1 443 autoconfig.%s\n\tautoconfig.%s CNAME %s\n\nNote: the trailing dots are relevant, it makes the host names absolute instead of relative to the domain name.", domain.ASCII+".", domain.ASCII+".", domain.ASCII+".", mox.Conf.Static.HostnameDomain.ASCII+".")
_, srvs, _, err := resolver.LookupSRV(ctx, "autodiscover", "tcp", domain.ASCII+".") _, srvs, _, err := resolver.LookupSRV(ctx, "autodiscover", "tcp", domain.ASCII+".")
if err != nil { if err != nil {