Skip to content

Commit

Permalink
control/controlhttp: add health warning for macOS filtering blocking …
Browse files Browse the repository at this point in the history
…Tailscale (#12546)

Updates #9658
Updates #12545

Change-Id: I6612b9b65eb193a1a651e219b5198c7c20ed94e1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Co-authored-by: Andrea Gottardo <andrea@tailscale.com>
  • Loading branch information
bradfitz and agottardo committed Jun 19, 2024
1 parent 1023b2a commit 0004827
Showing 1 changed file with 43 additions and 1 deletion.
44 changes: 43 additions & 1 deletion control/controlhttp/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ import (
"net/http/httptrace"
"net/netip"
"net/url"
"runtime"
"sort"
"sync/atomic"
"time"

"tailscale.com/control/controlbase"
"tailscale.com/envknob"
"tailscale.com/health"
"tailscale.com/net/dnscache"
"tailscale.com/net/dnsfallback"
"tailscale.com/net/netutil"
Expand Down Expand Up @@ -396,12 +398,28 @@ func (a *Dialer) resolver() *dnscache.Resolver {
}
}

func isLoopback(a net.Addr) bool {
if ta, ok := a.(*net.TCPAddr); ok {
return ta.IP.IsLoopback()
}
return false
}

var macOSScreenTime = health.Register(&health.Warnable{
Code: "macos-screen-time",
Title: "Tailscale blocked by Screen Time",
Text: func(args health.Args) string {
return "macOS Screen Time seems to be blocking Tailscale. Try disabling Screen Time in System Settings > Screen Time > Content & Privacy > Access to Web Content."
},
ImpactsConnectivity: true,
})

// tryURLUpgrade connects to u, and tries to upgrade it to a net.Conn. If addr
// is valid, then no DNS is used and the connection will be made to the
// provided address.
//
// Only the provided ctx is used, not a.ctx.
func (a *Dialer) tryURLUpgrade(ctx context.Context, u *url.URL, addr netip.Addr, init []byte) (net.Conn, error) {
func (a *Dialer) tryURLUpgrade(ctx context.Context, u *url.URL, addr netip.Addr, init []byte) (_ net.Conn, retErr error) {
var dns *dnscache.Resolver

// If we were provided an address to dial, then create a resolver that just
Expand All @@ -423,6 +441,30 @@ func (a *Dialer) tryURLUpgrade(ctx context.Context, u *url.URL, addr netip.Addr,
dialer = stdDialer.DialContext
}

// On macOS, see if Screen Time is blocking things.
if runtime.GOOS == "darwin" {
var proxydIntercepted atomic.Bool // intercepted by macOS webfilterproxyd
origDialer := dialer
dialer = func(ctx context.Context, network, address string) (net.Conn, error) {
c, err := origDialer(ctx, network, address)
if err != nil {
return nil, err
}
if isLoopback(c.LocalAddr()) && isLoopback(c.RemoteAddr()) {
proxydIntercepted.Store(true)
}
return c, nil
}
defer func() {
if retErr != nil && proxydIntercepted.Load() {
a.HealthTracker.SetUnhealthy(macOSScreenTime, nil)
retErr = fmt.Errorf("macOS Screen Time is blocking network access: %w", retErr)
} else {
a.HealthTracker.SetHealthy(macOSScreenTime)
}
}()
}

tr := http.DefaultTransport.(*http.Transport).Clone()
defer tr.CloseIdleConnections()
tr.Proxy = a.getProxyFunc()
Expand Down

0 comments on commit 0004827

Please sign in to comment.