Add SIP/JABBER labels to underscore exception list (#453)

* Improve comments in checkLabel
* Reformat labelUnderscores to make it easier to add to
* Add to exception list for label warnings
* Add underscores in hostnames to the opinions list.
This commit is contained in:
Tom Limoncelli 2019-03-04 12:11:25 -05:00 committed by GitHub
parent 511c0bf7de
commit 963bd32e20
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 4 deletions

View file

@ -91,7 +91,7 @@ is desired and the compiler does the hard work for you.
Some examples: Some examples:
* Macros and iterators permit you to state something once, correctly, and repeat it many places. * Macros and iterators permit you to state something once, correctly, and repeat it many places.
* TXT strings are expressed as JavaScript strings, with no weird DNS-required special escape charactors. DNSControl does the escaping for you. * TXT strings are expressed as JavaScript strings, with no weird DNS-required special escape characters. DNSControl does the escaping for you.
* Domain names with Unicode are listed as real Unicode. Punycode translation is done for you. * Domain names with Unicode are listed as real Unicode. Punycode translation is done for you.
* IP addresses are expressed as IP addresses; and reversing them to in-addr.arpa addresses is done for you. * IP addresses are expressed as IP addresses; and reversing them to in-addr.arpa addresses is done for you.
* SPF records are stated in the most verbose way; DNSControl optimizes it for you in a safe, opt-in way. * SPF records are stated in the most verbose way; DNSControl optimizes it for you in a safe, opt-in way.
@ -130,3 +130,30 @@ like that.
Therefore, we require all CNAME, MX, and NS targets to be FQDNs (they must Therefore, we require all CNAME, MX, and NS targets to be FQDNs (they must
end with a "."), or to be a shortname (no dots at all). Everything end with a "."), or to be a shortname (no dots at all). Everything
else is ambiguous and therefore an error. else is ambiguous and therefore an error.
# Opinion #7 Hostnames don't have underscores
DNSControl prints warnings if a hostname includes an underscore
(`_`) because underscores are not permitted in hostnames.
We want to prevent a naive user from including an underscore
when they meant to use a hyphen (`-`).
Hostnames are more restrictive than general DNS labels.
To quote [the Wikipedia entry on hostnames](https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_hostnames)
"While a hostname may not contain other characters, such as the
underscore character (`_`), other DNS names may contain the
underscore. Systems such as DomainKeys and service records use
the underscore as a means to assure that their special character
is not confused with hostnames. For example,
`_http._sctp.www.example.com` specifies a service pointer for an
SCTP capable webserver host (www) in the domain example.com."
However that leads to an interesting problem. When is a DNS label
a hostname and when it it just a DNS label? There is no way to
know for sure because code can't guess intention.
Therefore we print a warning if a label has an underscore in it,
unless the rtype is SRV, TLSA, TXT, or if the name starts with
certain prefixes such as `_dmarc`. We're always willing to
[add more exceptions](https://github.com/StackExchange/dnscontrol/pull/453/files).

View file

@ -86,7 +86,15 @@ func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []strin
// underscores in names are often used erroneously. They are valid for dns records, but invalid for urls. // underscores in names are often used erroneously. They are valid for dns records, but invalid for urls.
// here we list common records expected to have underscores. Anything else containing an underscore will print a warning. // here we list common records expected to have underscores. Anything else containing an underscore will print a warning.
var labelUnderscores = []string{"_domainkey", "_dmarc", "_amazonses", "_acme-challenge"} var labelUnderscores = []string{
"_acme-challenge",
"_amazonses",
"_dmarc",
"_domainkey",
"_jabber",
"_sip",
"_xmpp",
}
// these record types may contain underscores // these record types may contain underscores
var rTypeUnderscores = []string{"SRV", "TLSA", "TXT"} var rTypeUnderscores = []string{"SRV", "TLSA", "TXT"}
@ -106,18 +114,23 @@ func checkLabel(label string, rType string, domain string, meta map[string]strin
return errors.Errorf(`label %s ends with domain name %s. Record names should not be fully qualified. Add {skip_fqdn_check:"true"} to this record if you really want to make %s.%s`, label, domain, label, domain) return errors.Errorf(`label %s ends with domain name %s. Record names should not be fully qualified. Add {skip_fqdn_check:"true"} to this record if you really want to make %s.%s`, label, domain, label, domain)
} }
} }
// check for underscores last
// Underscores are permitted in labels, but we print a warning unless they
// are used in a way we consider typical. Yes, we're opinionated here.
// Don't warn for certain rtypes:
for _, ex := range rTypeUnderscores { for _, ex := range rTypeUnderscores {
if rType == ex { if rType == ex {
return nil return nil
} }
} }
// Don't warn for certain label substrings
for _, ex := range labelUnderscores { for _, ex := range labelUnderscores {
if strings.Contains(label, ex) { if strings.Contains(label, ex) {
return nil return nil
} }
} }
// underscores are warnings // Otherwise, warn.
if strings.ContainsRune(label, '_') { if strings.ContainsRune(label, '_') {
return Warning{errors.Errorf("label %s.%s contains an underscore", label, domain)} return Warning{errors.Errorf("label %s.%s contains an underscore", label, domain)}
} }