From 9d801a42d7581c11b8411385775fa713783584c9 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Thu, 6 Jan 2022 22:04:49 -0800 Subject: [PATCH] Add secret Run Exit Node option when "debug" is searched for. And bump tailscale dep, to bring in new ipn.Prefs API and wire up ExitDNS for Android. This change has no visible behavior change to anybody unless they search for "debug" and then hit the "..." menu. Updates tailscale/tailscale#1738 Signed-off-by: Brad Fitzpatrick --- cmd/tailscale/backend.go | 18 ++++++++++++++++++ cmd/tailscale/main.go | 7 +++++++ cmd/tailscale/ui.go | 30 +++++++++++++++++++++++++++++- go.mod | 2 +- go.sum | 4 ++++ 5 files changed, 59 insertions(+), 2 deletions(-) diff --git a/cmd/tailscale/backend.go b/cmd/tailscale/backend.go index fdd6afd..9260cf2 100644 --- a/cmd/tailscale/backend.go +++ b/cmd/tailscale/backend.go @@ -29,6 +29,7 @@ import ( "tailscale.com/types/logger" "tailscale.com/util/dnsname" "tailscale.com/wgengine" + "tailscale.com/wgengine/netstack" "tailscale.com/wgengine/router" ) @@ -120,6 +121,9 @@ func newBackend(dataDir string, jvm *jni.JVM, appCtx jni.Object, store *stateSto return nil, fmt.Errorf("runBackend: NewUserspaceEngine: %v", err) } b.logIDPublic = logID.Public().String() + if err := startNetstack(log.Printf, dialer, engine); err != nil { + return nil, fmt.Errorf("startNetstack: %w", err) + } local, err := ipnlocal.NewLocalBackend(logf, b.logIDPublic, store, dialer, engine) if err != nil { engine.Close() @@ -428,3 +432,17 @@ func (b *backend) getDNSBaseConfig() (dns.OSConfig, error) { return config, nil } + +func startNetstack(logf logger.Logf, dialer *tsdial.Dialer, e wgengine.Engine) error { + tunDev, magicConn, ok := e.(wgengine.InternalsGetter).GetInternals() + if !ok { + return fmt.Errorf("%T is not a wgengine.InternalsGetter", e) + } + ns, err := netstack.Create(logf, tunDev, e, magicConn, dialer) + if err != nil { + return fmt.Errorf("netstack.Create: %w", err) + } + ns.ProcessLocalIPs = false + ns.ProcessSubnets = true + return ns.Start() +} diff --git a/cmd/tailscale/main.go b/cmd/tailscale/main.go index 4ab8520..6c45dea 100644 --- a/cmd/tailscale/main.go +++ b/cmd/tailscale/main.go @@ -188,6 +188,7 @@ type ( WebAuthEvent struct{} GoogleAuthEvent struct{} LogoutEvent struct{} + BeExitNodeEvent bool ) // serverOAuthID is the OAuth ID of the tailscale-android server, used @@ -416,6 +417,9 @@ func (a *App) runBackend() error { case ToggleEvent: state.Prefs.WantRunning = !state.Prefs.WantRunning go b.backend.SetPrefs(state.Prefs) + case BeExitNodeEvent: + state.Prefs.SetAdvertiseExitNode(bool(e)) + go b.backend.SetPrefs(state.Prefs) case WebAuthEvent: if !signingIn { go b.backend.StartLoginInteractive() @@ -860,6 +864,7 @@ func (a *App) runUI() error { } case p := <-a.prefs: ui.enabled.Value = p.WantRunning + ui.runningExit = p.AdvertisesExitNode() w.Invalidate() case state.browseURL = <-a.browseURLs: ui.signinType = noSignin @@ -1070,6 +1075,8 @@ func (a *App) processUIEvents(w *app.Window, events []UIEvent, act jni.Object, s logMarker := fmt.Sprintf("BUG-%v-%v-%v", backendLogID, time.Now().UTC().Format("20060102150405Z"), randHex(8)) log.Printf("user bugreport: %s", logMarker) w.WriteClipboard(logMarker) + case BeExitNodeEvent: + requestBackend(e) case WebAuthEvent: a.store.WriteString(loginMethodPrefKey, loginMethodWeb) requestBackend(e) diff --git a/cmd/tailscale/ui.go b/cmd/tailscale/ui.go index d32a1f8..8d59ecb 100644 --- a/cmd/tailscale/ui.go +++ b/cmd/tailscale/ui.go @@ -10,6 +10,7 @@ import ( "fmt" "image" "image/color" + "strings" "time" "gioui.org/f32" @@ -70,6 +71,9 @@ type UI struct { list layout.List } + showDebugMenu bool + runningExit bool // are we an exit node now? + intro struct { list layout.List start widget.Clickable @@ -84,6 +88,7 @@ type UI struct { copy widget.Clickable reauth widget.Clickable bug widget.Clickable + beExit widget.Clickable exits widget.Clickable logout widget.Clickable } @@ -260,7 +265,11 @@ func (ui *UI) layout(gtx layout.Context, sysIns system.Insets, state *clientStat for _, e := range ui.search.Events() { if _, ok := e.(widget.ChangeEvent); ok { - events = append(events, SearchEvent{Query: ui.search.Text()}) + text := ui.search.Text() + if strings.EqualFold(text, "debug") { + ui.showDebugMenu = true + } + events = append(events, SearchEvent{Query: text}) break } } @@ -319,6 +328,16 @@ func (ui *UI) layout(gtx layout.Context, sysIns system.Insets, state *clientStat ui.showCopied(gtx, "bug report marker to clipboard") } + if ui.menuClicked(&ui.menu.beExit) { + ui.runningExit = !ui.runningExit + events = append(events, BeExitNodeEvent(ui.runningExit)) + if ui.runningExit { + ui.showMessage(gtx, "Running exit node") + } else { + ui.showMessage(gtx, "Stopped running exit node") + } + } + if ui.menuClicked(&ui.menu.exits) || ui.openExitDialog.Clicked() { ui.exitDialog.show = true } @@ -981,6 +1000,15 @@ func (ui *UI) layoutMenu(gtx layout.Context, sysIns system.Insets, expiry time.T menuItem{title: "Reauthenticate", btn: &menu.reauth}, menuItem{title: "Log out", btn: &menu.logout}, ) + if ui.runningExit || ui.showDebugMenu { + var title string + if ui.runningExit { + title = "Stop running exit node [BETA]" + } else { + title = "Run exit node [BETA]" + } + items = append(items, menuItem{title: title, btn: &menu.beExit}) + } return layoutMenu(ui.theme, gtx, items, func(gtx C) D { var expiryStr string const fmtStr = time.Stamp diff --git a/go.mod b/go.mod index ad73391..a037450 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( golang.org/x/sys v0.0.0-20211205182925-97ca703d548d golang.zx2c4.com/wireguard v0.0.0-20211116201604-de7c702ace45 inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6 - tailscale.com v1.1.1-0.20220106164417-64c2657448c9 + tailscale.com v1.1.1-0.20220107180532-1a4e8da0849f ) require ( diff --git a/go.sum b/go.sum index 8c9210c..04cb7c7 100644 --- a/go.sum +++ b/go.sum @@ -705,3 +705,7 @@ tailscale.com v1.1.1-0.20220103195654-dd45bba76b3a h1:f1Ixr2b9pnSeVLRt1caMxd4rJV tailscale.com v1.1.1-0.20220103195654-dd45bba76b3a/go.mod h1:kjVy3ji2OH5lZhPLIIRacoY3CN4Bo3Yyb2mtoM8nfJ4= tailscale.com v1.1.1-0.20220106164417-64c2657448c9 h1:LFkTqkAfdB+FzWS0KmOwv2Y5ba0Kbbc3IQfHi6G09fA= tailscale.com v1.1.1-0.20220106164417-64c2657448c9/go.mod h1:kjVy3ji2OH5lZhPLIIRacoY3CN4Bo3Yyb2mtoM8nfJ4= +tailscale.com v1.1.1-0.20220107005935-1b426cc232c0 h1:Z2+Z5HEPrInsP7BlE/2kMohRRWRvjxzJiLryhsrT+/c= +tailscale.com v1.1.1-0.20220107005935-1b426cc232c0/go.mod h1:kjVy3ji2OH5lZhPLIIRacoY3CN4Bo3Yyb2mtoM8nfJ4= +tailscale.com v1.1.1-0.20220107180532-1a4e8da0849f h1:PIv9L0qXK6HZuAer6hg6mmSByzJ5jv1MR5J7Wlbnfek= +tailscale.com v1.1.1-0.20220107180532-1a4e8da0849f/go.mod h1:kjVy3ji2OH5lZhPLIIRacoY3CN4Bo3Yyb2mtoM8nfJ4=