Skip to content

[management] Streamline domain validation#5211

Merged
lixmal merged 1 commit intomainfrom
fix-domain-validation
Jan 29, 2026
Merged

[management] Streamline domain validation#5211
lixmal merged 1 commit intomainfrom
fix-domain-validation

Conversation

@lixmal
Copy link
Copy Markdown
Collaborator

@lixmal lixmal commented Jan 29, 2026

Describe your changes

Per-Component Validation Changes

Component Wildcards Before After New Allowances
DNS Zone domain ✗ (was ✓) util.IsValidDomain IsValidDomainNoWildcard numeric TLDs, single-label, underscores
DNS Record name ✓ (unchanged) util.IsValidDomain IsValidDomain numeric TLDs, single-label, underscores
CNAME target ✗ (was ✓) util.IsValidDomain IsValidDomainNoWildcard numeric TLDs, single-label, underscores
Nameserver match domain ✗ (explicit) custom regex + dns.IsDomainName ValidateDomains + wildcard check unicode→punycode, trailing dot, numeric TLDs
Network resource domain ✓ (unchanged) inline regex ValidateDomains numeric TLDs, single-label, underscores
CLI --dns-domain dns.IsDomainName IsValidDomainNoWildcard numeric TLDs, single-label, underscores
Account DNSDomain strict regex IsValidDomainNoWildcard numeric TLDs, single-label, underscores
Account singleAccModeDomain strict regex IsValidDomainNoWildcard numeric TLDs, single-label, underscores
IDP user domain strict regex unchanged (public domains)

Summary

  • Unified domain validation into shared/management/domain package
  • Zones & CNAME targets: wildcards now rejected
  • Record names & network resources: wildcards still allowed
  • Nameservers: explicit wildcard rejection + unicode/punycode support
  • All internal DNS domains: now allow numeric TLDs, single-label domains, underscores
  • IDP domains: kept strict validation (real public TLDs only)

Stack

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

https://github.com/netbirdio/docs/pull/__

Summary by CodeRabbit

  • Tests

    • Expanded domain-matching and validation tests (single-letter TLDs, single-character labels, wildcards, Unicode/punycode, edge-length and count limits).
  • Bug Fixes

    • Tightened domain validation: stricter public rules (no single-label domains, min TLD length), wildcard rejection where applicable, and trailing-dot handling.
  • New Features

    • Unified, punycode-aware domain validation helpers and a non-punycode validation variant for ASCII/punycode-only checks.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 29, 2026

📝 Walkthrough

Walkthrough

Centralizes and replaces scattered domain validation code with a shared validation package, updates call sites across management and zones to use the new validators, and expands domain validation tests (including punycode, single-letter TLDs, wildcard rules, and length boundaries).

Changes

Cohort / File(s) Summary
Shared domain validators
shared/management/domain/validate.go, shared/management/domain/validate_test.go
Adds IsValidDomain, IsValidDomainNoWildcard, ValidateDomainsList; updates ValidateDomains to handle punycode and stricter rules; extensive new tests covering many edge cases (Unicode, single-letter TLDs, length limits, wildcards).
Management server validation updates
management/server/nameserver.go, management/server/account.go, management/server/networks/resources/types/resource.go, management/server/networks/resources/types/resource_test.go
Replaces regex/miekg/dns checks with shared validators (nbdomain); trims trailing dot FQDNs, rejects wildcard domains where appropriate, adjusts public-domain rules and test inputs.
Zones & records
management/internals/modules/zones/zone.go, management/internals/modules/zones/records/record.go
Replaces util.IsValidDomain with shared domain validators; tighter CNAME target validation using IsValidDomainNoWildcard and updated error messages.
Management CLI
management/cmd/management.go
Replaces dns.IsDomainName check with nbdomain.IsValidDomainNoWildcard and removes direct miekg/dns dependency.
Removed util validator
management/server/util/util.go
Removes legacy IsValidDomain and its regexp dependency.
Tests: DNS handler & nameserver
client/internal/dns/handler_chain_test.go, management/server/nameserver_test.go, management/server/networks/resources/manager_test.go
Adds/extends tests for single-letter TLDs, subdomain/wildcard cases, nameserver domain validation (wildcards, Unicode/punycode), and updates resource test inputs to align with new validators.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • pappz
  • crn4

Poem

🐰 I hopped through labels, dots, and rune,
I chased the wildcards under moon,
I wrapped domains in puny code,
I guarded lengths along the road,
Hooray — now validators make our meadow bloom! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 52.94% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the primary change: streamlining domain validation logic across components.
Description check ✅ Passed The description provides a detailed per-component analysis with a summary table and checklist completion, though it lacks an issue ticket number/link as required by the template.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
shared/management/domain/validate.go (1)

63-78: Add a total-length guard to list validation.

ValidateDomains enforces max length via FromString, but ValidateDomainsList can accept >253‑char domains. If callsites use this for user input, overlong domains can slip through. Consider adding a length check here (and mirroring it in IsValidDomain / IsValidDomainNoWildcard).

🩹 Suggested guard in ValidateDomainsList
 	for _, d := range domains {
 		d := strings.ToLower(d)
+		if len(d) > 253 {
+			return fmt.Errorf("domain exceeds maximum length: %s", d)
+		}
 		if !domainRegex.MatchString(d) {
 			return fmt.Errorf("invalid domain format: %s", d)
 		}
 	}
🤖 Fix all issues with AI agents
In `@management/cmd/management.go`:
- Around line 81-83: The validation rejects FQDNs with trailing dots; before
calling IsValidDomainNoWildcard on dnsDomain in management.go, normalize
dnsDomain by removing a single trailing '.' (and ensure resulting string is
non-empty) so domains like "example.com." become "example.com" prior to
validation; update any error messages to reference the normalized value or,
alternatively, document that trailing-dot FQDNs are not accepted if you prefer
to keep current behavior.
🧹 Nitpick comments (2)
shared/management/domain/validate_test.go (1)

193-203: Remove the duplicate test case.

Lines 193-203 repeat the previous “Wildcard with dot domain” case. Dropping one keeps the suite leaner.

🧹 Remove the duplicate block
-		{
-			name:     "Wildcard with dot domain",
-			domains:  []string{".*.example.com"},
-			expected: nil,
-			wantErr:  true,
-		},
management/server/nameserver.go (1)

310-312: Consider rejecting wildcards anywhere in the domain, not just as a prefix.

The current check only rejects domains starting with *., but a domain like a.*.example.com (wildcard in the middle) would pass this check and be sent to ValidateDomains. While ValidateDomains might reject it due to the regex, it would be cleaner to have explicit wildcard handling here.

💡 Optional: Reject wildcards anywhere in the domain
 func validateDomain(d string) error {
-	if strings.HasPrefix(d, "*.") {
+	if strings.Contains(d, "*") {
 		return errors.New("wildcards not allowed")
 	}

Comment thread management/cmd/management.go
@lixmal lixmal force-pushed the fix-domain-validation branch from 58b0e63 to fd63dbd Compare January 29, 2026 11:47
@sonarqubecloud
Copy link
Copy Markdown

Comment thread management/server/networks/resources/manager_test.go
Comment thread management/server/nameserver_test.go
@lixmal lixmal merged commit 81c11df into main Jan 29, 2026
49 of 50 checks passed
@lixmal lixmal deleted the fix-domain-validation branch January 29, 2026 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants