mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-25 20:57:31 +00:00
net/dns: don't set MatchDomains on Apple platforms when no upstream nameservers available (#12334)
This PR addresses a DNS issue on macOS as discussed this morning. Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
This commit is contained in:
@@ -172,6 +172,7 @@ func TestManager(t *testing.T) {
|
||||
bs OSConfig
|
||||
os OSConfig
|
||||
rs resolver.Config
|
||||
goos string // empty means "linux"
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
@@ -424,7 +425,7 @@ func TestManager(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "routes-multi-split",
|
||||
name: "routes-multi-split-linux",
|
||||
in: Config{
|
||||
Routes: upstreams(
|
||||
"corp.com", "2.2.2.2",
|
||||
@@ -442,6 +443,57 @@ func TestManager(t *testing.T) {
|
||||
"corp.com.", "2.2.2.2",
|
||||
"bigco.net.", "3.3.3.3"),
|
||||
},
|
||||
goos: "linux",
|
||||
},
|
||||
{
|
||||
// The `routes-multi-split-linux` test case above on Darwin should NOT result in a split
|
||||
// DNS configuration.
|
||||
// Check that MatchDomains is empty. Due to Apple limitations, we cannot set MatchDomains
|
||||
// without those domains also being SearchDomains.
|
||||
name: "routes-multi-does-not-split-on-darwin",
|
||||
in: Config{
|
||||
Routes: upstreams(
|
||||
"corp.com", "2.2.2.2",
|
||||
"bigco.net", "3.3.3.3"),
|
||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||
},
|
||||
split: false,
|
||||
os: OSConfig{
|
||||
Nameservers: mustIPs("100.100.100.100"),
|
||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||
},
|
||||
rs: resolver.Config{
|
||||
Routes: upstreams(
|
||||
".", "",
|
||||
"corp.com.", "2.2.2.2",
|
||||
"bigco.net.", "3.3.3.3"),
|
||||
},
|
||||
goos: "darwin",
|
||||
},
|
||||
{
|
||||
// The `routes-multi-split-linux` test case above on iOS should NOT result in a split
|
||||
// DNS configuration.
|
||||
// Check that MatchDomains is empty. Due to Apple limitations, we cannot set MatchDomains
|
||||
// without those domains also being SearchDomains.
|
||||
name: "routes-multi-does-not-split-on-ios",
|
||||
in: Config{
|
||||
Routes: upstreams(
|
||||
"corp.com", "2.2.2.2",
|
||||
"bigco.net", "3.3.3.3"),
|
||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||
},
|
||||
split: false,
|
||||
os: OSConfig{
|
||||
Nameservers: mustIPs("100.100.100.100"),
|
||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||
},
|
||||
rs: resolver.Config{
|
||||
Routes: upstreams(
|
||||
".", "",
|
||||
"corp.com.", "2.2.2.2",
|
||||
"bigco.net.", "3.3.3.3"),
|
||||
},
|
||||
goos: "ios",
|
||||
},
|
||||
{
|
||||
name: "magic",
|
||||
@@ -489,6 +541,59 @@ func TestManager(t *testing.T) {
|
||||
"bradfitz.ts.com.", "2.3.4.5"),
|
||||
LocalDomains: fqdns("ts.com."),
|
||||
},
|
||||
goos: "linux",
|
||||
},
|
||||
{
|
||||
// The `magic-split` test case above on Darwin should NOT result in a split DNS configuration.
|
||||
// Check that MatchDomains is empty. Due to Apple limitations, we cannot set MatchDomains
|
||||
// without those domains also being SearchDomains.
|
||||
name: "magic-split-does-not-split-on-darwin",
|
||||
in: Config{
|
||||
Hosts: hosts(
|
||||
"dave.ts.com.", "1.2.3.4",
|
||||
"bradfitz.ts.com.", "2.3.4.5"),
|
||||
Routes: upstreams("ts.com", ""),
|
||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||
},
|
||||
split: false,
|
||||
os: OSConfig{
|
||||
Nameservers: mustIPs("100.100.100.100"),
|
||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||
},
|
||||
rs: resolver.Config{
|
||||
Routes: upstreams(".", ""),
|
||||
Hosts: hosts(
|
||||
"dave.ts.com.", "1.2.3.4",
|
||||
"bradfitz.ts.com.", "2.3.4.5"),
|
||||
LocalDomains: fqdns("ts.com."),
|
||||
},
|
||||
goos: "darwin",
|
||||
},
|
||||
{
|
||||
// The `magic-split` test case above on iOS should NOT result in a split DNS configuration.
|
||||
// Check that MatchDomains is empty. Due to Apple limitations, we cannot set MatchDomains
|
||||
// without those domains also being SearchDomains.
|
||||
name: "magic-split-does-not-split-on-ios",
|
||||
in: Config{
|
||||
Hosts: hosts(
|
||||
"dave.ts.com.", "1.2.3.4",
|
||||
"bradfitz.ts.com.", "2.3.4.5"),
|
||||
Routes: upstreams("ts.com", ""),
|
||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||
},
|
||||
split: false,
|
||||
os: OSConfig{
|
||||
Nameservers: mustIPs("100.100.100.100"),
|
||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||
},
|
||||
rs: resolver.Config{
|
||||
Routes: upstreams(".", ""),
|
||||
Hosts: hosts(
|
||||
"dave.ts.com.", "1.2.3.4",
|
||||
"bradfitz.ts.com.", "2.3.4.5"),
|
||||
LocalDomains: fqdns("ts.com."),
|
||||
},
|
||||
goos: "ios",
|
||||
},
|
||||
{
|
||||
name: "routes-magic",
|
||||
@@ -518,7 +623,7 @@ func TestManager(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "routes-magic-split",
|
||||
name: "routes-magic-split-linux",
|
||||
in: Config{
|
||||
Routes: upstreams(
|
||||
"corp.com", "2.2.2.2",
|
||||
@@ -541,6 +646,71 @@ func TestManager(t *testing.T) {
|
||||
"bradfitz.ts.com.", "2.3.4.5"),
|
||||
LocalDomains: fqdns("ts.com."),
|
||||
},
|
||||
goos: "linux",
|
||||
},
|
||||
{
|
||||
// The `routes-magic-split-linux` test case above on Darwin should NOT result in a
|
||||
// split DNS configuration.
|
||||
// Check that MatchDomains is empty. Due to Apple limitations, we cannot set MatchDomains
|
||||
// without those domains also being SearchDomains.
|
||||
name: "routes-magic-does-not-split-on-darwin",
|
||||
in: Config{
|
||||
Routes: upstreams(
|
||||
"corp.com", "2.2.2.2",
|
||||
"ts.com", ""),
|
||||
Hosts: hosts(
|
||||
"dave.ts.com.", "1.2.3.4",
|
||||
"bradfitz.ts.com.", "2.3.4.5"),
|
||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||
},
|
||||
split: true,
|
||||
os: OSConfig{
|
||||
Nameservers: mustIPs("100.100.100.100"),
|
||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||
},
|
||||
rs: resolver.Config{
|
||||
Routes: upstreams(
|
||||
".", "",
|
||||
"corp.com.", "2.2.2.2",
|
||||
),
|
||||
Hosts: hosts(
|
||||
"dave.ts.com.", "1.2.3.4",
|
||||
"bradfitz.ts.com.", "2.3.4.5"),
|
||||
LocalDomains: fqdns("ts.com."),
|
||||
},
|
||||
goos: "darwin",
|
||||
},
|
||||
{
|
||||
// The `routes-magic-split-linux` test case above on Darwin should NOT result in a
|
||||
// split DNS configuration.
|
||||
// Check that MatchDomains is empty. Due to Apple limitations, we cannot set MatchDomains
|
||||
// without those domains also being SearchDomains.
|
||||
name: "routes-magic-does-not-split-on-ios",
|
||||
in: Config{
|
||||
Routes: upstreams(
|
||||
"corp.com", "2.2.2.2",
|
||||
"ts.com", ""),
|
||||
Hosts: hosts(
|
||||
"dave.ts.com.", "1.2.3.4",
|
||||
"bradfitz.ts.com.", "2.3.4.5"),
|
||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||
},
|
||||
split: true,
|
||||
os: OSConfig{
|
||||
Nameservers: mustIPs("100.100.100.100"),
|
||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||
},
|
||||
rs: resolver.Config{
|
||||
Routes: upstreams(
|
||||
".", "",
|
||||
"corp.com.", "2.2.2.2",
|
||||
),
|
||||
Hosts: hosts(
|
||||
"dave.ts.com.", "1.2.3.4",
|
||||
"bradfitz.ts.com.", "2.3.4.5"),
|
||||
LocalDomains: fqdns("ts.com."),
|
||||
},
|
||||
goos: "ios",
|
||||
},
|
||||
{
|
||||
name: "exit-node-forward",
|
||||
@@ -598,6 +768,76 @@ func TestManager(t *testing.T) {
|
||||
Routes: upstreams(".", "https://dns.nextdns.io/c3a884"),
|
||||
},
|
||||
},
|
||||
{
|
||||
// on iOS exclusively, tests the split DNS behavior for battery life optimization added in
|
||||
// https://github.com/tailscale/tailscale/pull/10576
|
||||
name: "ios-use-split-dns-when-no-custom-resolvers",
|
||||
in: Config{
|
||||
Routes: upstreams("ts.net", "199.247.155.52", "optimistic-display.ts.net", ""),
|
||||
SearchDomains: fqdns("optimistic-display.ts.net"),
|
||||
},
|
||||
split: true,
|
||||
os: OSConfig{
|
||||
Nameservers: mustIPs("100.100.100.100"),
|
||||
SearchDomains: fqdns("optimistic-display.ts.net"),
|
||||
MatchDomains: fqdns("ts.net"),
|
||||
},
|
||||
rs: resolver.Config{
|
||||
Routes: upstreams(
|
||||
".", "",
|
||||
"ts.net", "199.247.155.52",
|
||||
),
|
||||
LocalDomains: fqdns("optimistic-display.ts.net."),
|
||||
},
|
||||
goos: "ios",
|
||||
},
|
||||
{
|
||||
// if using app connectors, the battery life optimization above should not be applied
|
||||
name: "ios-dont-use-split-dns-when-app-connector-resolver-needed",
|
||||
in: Config{
|
||||
Routes: upstreams(
|
||||
"ts.net", "199.247.155.52",
|
||||
"optimistic-display.ts.net", "",
|
||||
"github.com", "https://dnsresolver.bigcorp.com/2f143"),
|
||||
SearchDomains: fqdns("optimistic-display.ts.net"),
|
||||
},
|
||||
split: true,
|
||||
os: OSConfig{
|
||||
Nameservers: mustIPs("100.100.100.100"),
|
||||
SearchDomains: fqdns("optimistic-display.ts.net"),
|
||||
},
|
||||
rs: resolver.Config{
|
||||
Routes: upstreams(
|
||||
".", "",
|
||||
"github.com", "https://dnsresolver.bigcorp.com/2f143",
|
||||
"ts.net", "199.247.155.52",
|
||||
),
|
||||
LocalDomains: fqdns("optimistic-display.ts.net."),
|
||||
},
|
||||
goos: "ios",
|
||||
},
|
||||
{
|
||||
// on darwin, verify that with the same config as in ios-use-split-dns-when-no-custom-resolvers,
|
||||
// MatchDomains are NOT set.
|
||||
name: "darwin-dont-use-split-dns-when-no-custom-resolvers",
|
||||
in: Config{
|
||||
Routes: upstreams("ts.net", "199.247.155.52", "optimistic-display.ts.net", ""),
|
||||
SearchDomains: fqdns("optimistic-display.ts.net"),
|
||||
},
|
||||
split: true,
|
||||
os: OSConfig{
|
||||
Nameservers: mustIPs("100.100.100.100"),
|
||||
SearchDomains: fqdns("optimistic-display.ts.net"),
|
||||
},
|
||||
rs: resolver.Config{
|
||||
Routes: upstreams(
|
||||
".", "",
|
||||
"ts.net", "199.247.155.52",
|
||||
),
|
||||
LocalDomains: fqdns("optimistic-display.ts.net."),
|
||||
},
|
||||
goos: "darwin",
|
||||
},
|
||||
}
|
||||
|
||||
trIP := cmp.Transformer("ipStr", func(ip netip.Addr) string { return ip.String() })
|
||||
@@ -614,7 +854,11 @@ func TestManager(t *testing.T) {
|
||||
SplitDNS: test.split,
|
||||
BaseConfig: test.bs,
|
||||
}
|
||||
m := NewManager(t.Logf, &f, nil, tsdial.NewDialer(netmon.NewStatic()), nil, nil)
|
||||
goos := test.goos
|
||||
if goos == "" {
|
||||
goos = "linux"
|
||||
}
|
||||
m := NewManager(t.Logf, &f, nil, tsdial.NewDialer(netmon.NewStatic()), nil, nil, goos)
|
||||
m.resolver.TestOnlySetHook(f.SetResolver)
|
||||
|
||||
if err := m.Set(test.in); err != nil {
|
||||
|
Reference in New Issue
Block a user