mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
Expect SOA mailbox in hostmaster@example.org format instead of hostmaster.example.org (#2037)
Co-authored-by: Yannik Sembritzki <yannik@sembritzki.org> Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
This commit is contained in:
committed by
GitHub
parent
9eacd42b63
commit
dc02d5b74f
@ -24,12 +24,14 @@ parameter_types:
|
||||
|
||||
```javascript
|
||||
D("example.com", REG_THIRDPARTY, DnsProvider("DNS_BIND"),
|
||||
SOA("@", "ns3.example.org.", "hostmaster.example.org.", 3600, 600, 604800, 1440),
|
||||
SOA("@", "ns3.example.org.", "hostmaster@example.org", 3600, 600, 604800, 1440),
|
||||
);
|
||||
```
|
||||
|
||||
## Notes
|
||||
The email address should be specified like a normal RFC822/RFC5322 address (user@hostname.com). It will be converted into the required format (e.g. BIND format: `user.hostname.com`) by the provider as required. This has the benefit of being more human-readable plus DNSControl can properly handle escaping and other issues.
|
||||
|
||||
## Notes
|
||||
* Previously, the accepted format for the SOA mailbox field was `hostmaster.example.org`. This has been changed to `hostmaster@example.org`
|
||||
* The serial number is managed automatically. It isn't even a field in `SOA()`.
|
||||
* Most providers automatically generate SOA records. They will ignore any `SOA()` statements.
|
||||
|
||||
|
11
pkg/soautil/soautil.go
Normal file
11
pkg/soautil/soautil.go
Normal file
@ -0,0 +1,11 @@
|
||||
package soautil
|
||||
|
||||
import "strings"
|
||||
|
||||
func RFC5322MailToBind(rfc5322Mail string) string {
|
||||
res := strings.SplitN(rfc5322Mail, "@", 2)
|
||||
user_part, domain_part := res[0], res[1]
|
||||
// RFC-1035 [Section-8]
|
||||
user_part = strings.ReplaceAll(user_part, ".", "\\.")
|
||||
return user_part + "." + domain_part
|
||||
}
|
28
pkg/soautil/soautil_test.go
Normal file
28
pkg/soautil/soautil_test.go
Normal file
@ -0,0 +1,28 @@
|
||||
package soautil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_RFC5322MailToBind(t *testing.T) {
|
||||
type args struct {
|
||||
rfc5322Mail string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
rfc5322Mail string
|
||||
bindMail string
|
||||
}{
|
||||
{"0", "hostmaster@example.com", "hostmaster.example.com"},
|
||||
{"1", "admin.dns@example.com", "admin\\.dns.example.com"},
|
||||
{"2", "hostmaster@sub.example.com", "hostmaster.sub.example.com"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := RFC5322MailToBind(tt.rfc5322Mail); !reflect.DeepEqual(got, tt.bindMail) {
|
||||
t.Errorf("RFC5322MailToBind(%v) = %v, want %v", tt.rfc5322Mail, got, tt.bindMail)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -1,6 +1,11 @@
|
||||
package bind
|
||||
|
||||
import "github.com/StackExchange/dnscontrol/v3/models"
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/StackExchange/dnscontrol/v3/models"
|
||||
"github.com/StackExchange/dnscontrol/v3/pkg/soautil"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func makeSoa(origin string, defSoa *SoaDefaults, existing, desired *models.RecordConfig) (*models.RecordConfig, uint32) {
|
||||
// Create a SOA record. Take data from desired, existing, default,
|
||||
@ -19,10 +24,18 @@ func makeSoa(origin string, defSoa *SoaDefaults, existing, desired *models.Recor
|
||||
desired = &models.RecordConfig{}
|
||||
}
|
||||
|
||||
soaMail := firstNonNull(desired.SoaMbox, existing.SoaMbox, defSoa.Mbox, "DEFAULT_NOT_SET.")
|
||||
if strings.Contains(soaMail, "@") {
|
||||
soaMail = soautil.RFC5322MailToBind(soaMail)
|
||||
} else {
|
||||
fmt.Println("WARNING: SOA hostmaster address must be in the format hostmaster@example.com")
|
||||
fmt.Println("WARNING: hostmaster.example.com is deprecated and will be dropped in a future version")
|
||||
}
|
||||
|
||||
soaRec.TTL = firstNonZero(desired.TTL, defSoa.TTL, existing.TTL, models.DefaultTTL)
|
||||
soaRec.SetTargetSOA(
|
||||
firstNonNull(desired.GetTargetField(), existing.GetTargetField(), defSoa.Ns, "DEFAULT_NOT_SET."),
|
||||
firstNonNull(desired.SoaMbox, existing.SoaMbox, defSoa.Mbox, "DEFAULT_NOT_SET."),
|
||||
soaMail,
|
||||
firstNonZero(desired.SoaSerial, existing.SoaSerial, defSoa.Serial, 1),
|
||||
firstNonZero(desired.SoaRefresh, existing.SoaRefresh, defSoa.Refresh, 3600),
|
||||
firstNonZero(desired.SoaRetry, existing.SoaRetry, defSoa.Retry, 600),
|
||||
|
@ -32,7 +32,7 @@ func Test_makeSoa(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// If everything is filled, leave the desired values in place.
|
||||
&SoaDefaults{"ns.example.com", "root.example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
|
||||
&SoaDefaults{"ns.example.com", "root@example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
|
||||
mkRC("a", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 10, SoaRefresh: 11, SoaRetry: 12, SoaExpire: 13, SoaMinttl: 14}),
|
||||
mkRC("b", &models.RecordConfig{SoaMbox: "bb", SoaSerial: 15, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19}),
|
||||
mkRC("b", &models.RecordConfig{SoaMbox: "bb", SoaSerial: 15, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19}),
|
||||
@ -40,7 +40,7 @@ func Test_makeSoa(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// Test incrementing serial.
|
||||
&SoaDefaults{"ns.example.com", "root.example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
|
||||
&SoaDefaults{"ns.example.com", "root@example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
|
||||
mkRC("a", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 2019022301, SoaRefresh: 11, SoaRetry: 12, SoaExpire: 13, SoaMinttl: 14}),
|
||||
mkRC("b", &models.RecordConfig{SoaMbox: "bb", SoaSerial: 0, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19}),
|
||||
mkRC("b", &models.RecordConfig{SoaMbox: "bb", SoaSerial: 2019022301, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19}),
|
||||
@ -48,7 +48,7 @@ func Test_makeSoa(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// Test incrementing serial_2.
|
||||
&SoaDefaults{"ns.example.com", "root.example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
|
||||
&SoaDefaults{"ns.example.com", "root@example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
|
||||
mkRC("a", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 0, SoaRefresh: 11, SoaRetry: 12, SoaExpire: 13, SoaMinttl: 14}),
|
||||
mkRC("b", &models.RecordConfig{SoaMbox: "bb", SoaSerial: 2019022304, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19}),
|
||||
mkRC("b", &models.RecordConfig{SoaMbox: "bb", SoaSerial: 2019022304, SoaRefresh: 16, SoaRetry: 17, SoaExpire: 18, SoaMinttl: 19}),
|
||||
@ -56,7 +56,7 @@ func Test_makeSoa(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// If there are gaps in existing or desired, fill in as appropriate.
|
||||
&SoaDefaults{"ns.example.com", "root.example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
|
||||
&SoaDefaults{"ns.example.com", "root@example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
|
||||
mkRC("", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 0, SoaRefresh: 11, SoaRetry: 0, SoaExpire: 13, SoaMinttl: 0}),
|
||||
mkRC("b", &models.RecordConfig{SoaMbox: "", SoaSerial: 15, SoaRefresh: 0, SoaRetry: 17, SoaExpire: 0, SoaMinttl: 19}),
|
||||
mkRC("b", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 15, SoaRefresh: 11, SoaRetry: 17, SoaExpire: 13, SoaMinttl: 19}),
|
||||
@ -64,7 +64,7 @@ func Test_makeSoa(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// Gaps + existing==nil
|
||||
&SoaDefaults{"ns.example.com", "root.example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
|
||||
&SoaDefaults{"ns.example.com", "root@example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
|
||||
nil,
|
||||
mkRC("b", &models.RecordConfig{SoaMbox: "", SoaSerial: 15, SoaRefresh: 0, SoaRetry: 17, SoaExpire: 0, SoaMinttl: 19}),
|
||||
mkRC("b", &models.RecordConfig{SoaMbox: "root.example.com", SoaSerial: 15, SoaRefresh: 2, SoaRetry: 17, SoaExpire: 4, SoaMinttl: 19}),
|
||||
@ -73,7 +73,7 @@ func Test_makeSoa(t *testing.T) {
|
||||
{
|
||||
// Gaps + desired==nil
|
||||
// NB(tom): In the code as of 2020-02-23, desired will never be nil.
|
||||
&SoaDefaults{"ns.example.com", "root.example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
|
||||
&SoaDefaults{"ns.example.com", "root@example.com", 1, 2, 3, 4, 5, models.DefaultTTL},
|
||||
mkRC("", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 0, SoaRefresh: 11, SoaRetry: 0, SoaExpire: 13, SoaMinttl: 0}),
|
||||
nil,
|
||||
mkRC("ns.example.com", &models.RecordConfig{SoaMbox: "aa", SoaSerial: 1, SoaRefresh: 11, SoaRetry: 3, SoaExpire: 13, SoaMinttl: 5}),
|
||||
|
Reference in New Issue
Block a user