mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-12 11:49:55 +00:00
client/dns/mgmt: strip wildcard prefix in pool-root membership check
isUnderPoolRoot lowercased and trimmed the trailing dot, but did not
strip a leading "*." wildcard the way server.toZone does via
nbdns.NormalizeZone. If a mgmt-advertised Relay URL ever comes through
as "*.relay.netbird.io", the handler-chain registration side strips
the wildcard (toZone) but the membership check here would keep it,
so HasSuffix(".*.relay.netbird.io") would never match legitimate
instance subdomains and on-demand resolves would not fire.
Today the extractor lowercases + IDNA-normalizes URLs and rejects the
wildcard form, so the divergence is latent. Close it anyway by running
both sides of the membership check through a shared
canonicalizePoolDomain helper that mirrors toZone's transformation
(modulo trailing-dot orientation, which is self-consistent within
this function). toZone itself lives in the parent dns package and
cannot be imported here without a cycle.
This commit is contained in:
@@ -202,15 +202,24 @@ func (m *Resolver) MatchSubdomains() bool {
|
||||
// e.g. "streamline-de-fra1-0.relay.netbird.io." is under "relay.netbird.io".
|
||||
// The pool-root itself is not considered a subdomain (it matches the exact
|
||||
// cache entry populated by AddDomain instead).
|
||||
//
|
||||
// Canonicalization mirrors server.toZone — lowercase, strip trailing dot,
|
||||
// and strip a leading "*." wildcard (via canonicalizePoolDomain) — so the
|
||||
// membership check is consistent with the handler-chain registration that
|
||||
// runs the same set through toZone. toZone itself lives in the parent dns
|
||||
// package and cannot be imported from here without a cycle.
|
||||
func (m *Resolver) isUnderPoolRoot(fqdn string) bool {
|
||||
m.mutex.RLock()
|
||||
defer m.mutex.RUnlock()
|
||||
if m.serverDomains == nil {
|
||||
return false
|
||||
}
|
||||
fqdn = strings.ToLower(strings.TrimSuffix(fqdn, "."))
|
||||
fqdn = canonicalizePoolDomain(fqdn)
|
||||
if fqdn == "" {
|
||||
return false
|
||||
}
|
||||
for _, root := range m.serverDomains.Relay {
|
||||
r := strings.ToLower(strings.TrimSuffix(root.PunycodeString(), "."))
|
||||
r := canonicalizePoolDomain(root.PunycodeString())
|
||||
if r == "" || fqdn == r {
|
||||
continue
|
||||
}
|
||||
@@ -221,6 +230,17 @@ func (m *Resolver) isUnderPoolRoot(fqdn string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// canonicalizePoolDomain normalizes a domain for pool-root membership
|
||||
// comparison: lowercase, trailing dot stripped, leading "*." wildcard
|
||||
// stripped. Matches the transformation server.toZone applies on the
|
||||
// handler-registration side (modulo trailing-dot orientation, which is
|
||||
// self-consistent within this file).
|
||||
func canonicalizePoolDomain(s string) string {
|
||||
s = strings.ToLower(strings.TrimSuffix(s, "."))
|
||||
s = strings.TrimPrefix(s, "*.")
|
||||
return s
|
||||
}
|
||||
|
||||
// resolveOnDemand resolves an uncached pool-root subdomain (e.g. a relay
|
||||
// instance FQDN) through the bypass resolver path, caches the result, and
|
||||
// writes it back to w. Falls through to the next handler on error so the
|
||||
|
||||
Reference in New Issue
Block a user