mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-12-09 05:36:27 +08:00
ALIDNS: Fix integration test
This commit is contained in:
parent
51492f802c
commit
7c801c8030
4 changed files with 53 additions and 2 deletions
|
|
@ -372,7 +372,6 @@ func makeTests() []*TestGroup {
|
||||||
// RFC 7505 NullMX at Apex
|
// RFC 7505 NullMX at Apex
|
||||||
testgroup("NullMXApex",
|
testgroup("NullMXApex",
|
||||||
not(
|
not(
|
||||||
"ALIDNS", // ALIDNS does not support NullMX.
|
|
||||||
"TRANSIP", // TRANSIP is slow and doesn't support NullMX. Skip to save time.
|
"TRANSIP", // TRANSIP is slow and doesn't support NullMX. Skip to save time.
|
||||||
),
|
),
|
||||||
tc("create", // Install a Null MX.
|
tc("create", // Install a Null MX.
|
||||||
|
|
@ -596,6 +595,7 @@ func makeTests() []*TestGroup {
|
||||||
// SOFTLAYER: fails at direct internationalization, punycode works, of course.
|
// SOFTLAYER: fails at direct internationalization, punycode works, of course.
|
||||||
tc("Internationalized name", a("ööö", "1.2.3.4")),
|
tc("Internationalized name", a("ööö", "1.2.3.4")),
|
||||||
tc("Change IDN", a("ööö", "2.2.2.2")),
|
tc("Change IDN", a("ööö", "2.2.2.2")),
|
||||||
|
tc("Chinese label", a("中文", "1.2.3.4")),
|
||||||
tc("Internationalized CNAME Target", cname("a", "ööö.com.")),
|
tc("Internationalized CNAME Target", cname("a", "ööö.com.")),
|
||||||
),
|
),
|
||||||
testgroup("IDNAs in CNAME targets",
|
testgroup("IDNAs in CNAME targets",
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,20 @@ func (aud *Auditor) Audit(records models.Records) (errs []error) {
|
||||||
|
|
||||||
// For each record, call the checks for that type, gather errors.
|
// For each record, call the checks for that type, gather errors.
|
||||||
for _, rc := range records {
|
for _, rc := range records {
|
||||||
|
// First, run type-specific checks
|
||||||
for _, f := range aud.checksFor[rc.Type] {
|
for _, f := range aud.checksFor[rc.Type] {
|
||||||
e := f(rc)
|
e := f(rc)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
errs = append(errs, e)
|
errs = append(errs, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Then, run wildcard checks that apply to all record types
|
||||||
|
for _, f := range aud.checksFor["*"] {
|
||||||
|
e := f(rc)
|
||||||
|
if e != nil {
|
||||||
|
errs = append(errs, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return errs
|
return errs
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,46 @@
|
||||||
package alidns
|
package alidns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v4/models"
|
"github.com/StackExchange/dnscontrol/v4/models"
|
||||||
"github.com/StackExchange/dnscontrol/v4/pkg/rejectif"
|
"github.com/StackExchange/dnscontrol/v4/pkg/rejectif"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// isValidAliDNSString checks if a string contains only ASCII or Chinese characters.
|
||||||
|
// Alibaba Cloud DNS allows: a-z, A-Z, 0-9, -, _, ., *, @, and Chinese characters (汉字).
|
||||||
|
func isValidAliDNSString(s string) bool {
|
||||||
|
for _, r := range s {
|
||||||
|
if r > unicode.MaxASCII {
|
||||||
|
// Allow CJK Unified Ideographs (Chinese characters): U+4E00 to U+9FFF
|
||||||
|
// and CJK Extension A: U+3400 to U+4DBF
|
||||||
|
if (r >= 0x4E00 && r <= 0x9FFF) || (r >= 0x3400 && r <= 0x4DBF) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// labelConstraint detects labels that contain non-ASCII characters except Chinese characters.
|
||||||
|
func labelConstraint(rc *models.RecordConfig) error {
|
||||||
|
if !isValidAliDNSString(rc.GetLabel()) {
|
||||||
|
return errors.New("label contains non-ASCII characters (only Chinese is allowed)")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// targetConstraint detects target values that contain non-ASCII characters except Chinese characters.
|
||||||
|
// This applies to CNAME, MX, NS, SRV targets.
|
||||||
|
func targetConstraint(rc *models.RecordConfig) error {
|
||||||
|
if !isValidAliDNSString(rc.GetTargetField()) {
|
||||||
|
return errors.New("target contains non-ASCII characters (only Chinese is allowed)")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// AuditRecords returns a list of errors corresponding to the records
|
// AuditRecords returns a list of errors corresponding to the records
|
||||||
// that aren't supported by this provider. If all records are
|
// that aren't supported by this provider. If all records are
|
||||||
// supported, an empty list is returned.
|
// supported, an empty list is returned.
|
||||||
|
|
@ -17,5 +53,7 @@ func AuditRecords(records []*models.RecordConfig) []error {
|
||||||
a.Add("TXT", rejectif.TxtHasDoubleQuotes) // Last verified at 2025-12-03: Alibaba strips quotes
|
a.Add("TXT", rejectif.TxtHasDoubleQuotes) // Last verified at 2025-12-03: Alibaba strips quotes
|
||||||
a.Add("TXT", rejectif.TxtHasTrailingSpace) // Last verified at 2025-12-03: Alibaba strips trailing spaces
|
a.Add("TXT", rejectif.TxtHasTrailingSpace) // Last verified at 2025-12-03: Alibaba strips trailing spaces
|
||||||
a.Add("TXT", rejectif.TxtHasUnpairedBackslash) // Last verified at 2025-12-03: Alibaba mishandles odd backslashes
|
a.Add("TXT", rejectif.TxtHasUnpairedBackslash) // Last verified at 2025-12-03: Alibaba mishandles odd backslashes
|
||||||
|
a.Add("*", labelConstraint) // Last verified at 2025-12-03: Alibaba only allows ASCII + Chinese, rejects other Unicode
|
||||||
|
a.Add("CNAME", targetConstraint) // Last verified at 2025-12-03: CNAME target must be ASCII or Chinese
|
||||||
return a.Audit(records)
|
return a.Audit(records)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v4/models"
|
"github.com/StackExchange/dnscontrol/v4/models"
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
|
"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
|
||||||
|
"golang.org/x/net/idna"
|
||||||
)
|
)
|
||||||
|
|
||||||
// nativeToRecord converts an Alibaba Cloud DNS record to a RecordConfig.
|
// nativeToRecord converts an Alibaba Cloud DNS record to a RecordConfig.
|
||||||
|
|
@ -14,7 +15,11 @@ func nativeToRecord(r *alidns.Record, domain string) (*models.RecordConfig, erro
|
||||||
TTL: uint32(r.TTL),
|
TTL: uint32(r.TTL),
|
||||||
Original: r,
|
Original: r,
|
||||||
}
|
}
|
||||||
rc.SetLabel(r.RR, domain)
|
label, err := idna.ToASCII(r.RR)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to convert label to ASCII: %w", err)
|
||||||
|
}
|
||||||
|
rc.SetLabel(label, domain)
|
||||||
|
|
||||||
// Normalize CNAME, MX, NS records with trailing dot to be consistent with FQDN format.
|
// Normalize CNAME, MX, NS records with trailing dot to be consistent with FQDN format.
|
||||||
value := r.Value
|
value := r.Value
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue