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
|
||||
testgroup("NullMXApex",
|
||||
not(
|
||||
"ALIDNS", // ALIDNS does not support NullMX.
|
||||
"TRANSIP", // TRANSIP is slow and doesn't support NullMX. Skip to save time.
|
||||
),
|
||||
tc("create", // Install a Null MX.
|
||||
|
|
@ -596,6 +595,7 @@ func makeTests() []*TestGroup {
|
|||
// SOFTLAYER: fails at direct internationalization, punycode works, of course.
|
||||
tc("Internationalized name", a("ööö", "1.2.3.4")),
|
||||
tc("Change IDN", a("ööö", "2.2.2.2")),
|
||||
tc("Chinese label", a("中文", "1.2.3.4")),
|
||||
tc("Internationalized CNAME Target", cname("a", "ööö.com.")),
|
||||
),
|
||||
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 _, rc := range records {
|
||||
// First, run type-specific checks
|
||||
for _, f := range aud.checksFor[rc.Type] {
|
||||
e := f(rc)
|
||||
if e != nil {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,10 +1,46 @@
|
|||
package alidns
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"unicode"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"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
|
||||
// that aren't supported by this provider. If all records are
|
||||
// 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.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("*", 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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
|
||||
"golang.org/x/net/idna"
|
||||
)
|
||||
|
||||
// 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),
|
||||
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.
|
||||
value := r.Value
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue