From fe5558094c56f6ab61c9bd47beddba310ab39dbc Mon Sep 17 00:00:00 2001 From: Jenny Zhang Date: Fri, 10 Feb 2023 16:12:10 -0500 Subject: [PATCH] cmd/tailscale/cli: add logout and debug info to web Fixes #7238 Signed-off-by: Jenny Zhang --- cmd/tailscale/cli/web.css | 22 +++++++++++++++++ cmd/tailscale/cli/web.go | 41 ++++++++++++++++++++++++------- cmd/tailscale/cli/web.html | 50 +++++++++++++++++++++++--------------- 3 files changed, 84 insertions(+), 29 deletions(-) diff --git a/cmd/tailscale/cli/web.css b/cmd/tailscale/cli/web.css index fbe4ee11e..5b9d9e0b6 100644 --- a/cmd/tailscale/cli/web.css +++ b/cmd/tailscale/cli/web.css @@ -1286,6 +1286,28 @@ html { color: rgba(25, 34, 74, var(--text-opacity)); } +.link-underline { + text-decoration: underline; +} + +.link-underline:hover, +.link-underline:active { + text-decoration: none; +} + +.link-muted { + /* same as text-gray-500 */ + --tw-text-opacity: 1; + color: rgba(112, 110, 109, var(--tw-text-opacity)); +} + +.link-muted:hover, +.link-muted:active { + /* same as text-gray-500 */ + --tw-text-opacity: 1; + color: rgba(68, 67, 66, var(--tw-text-opacity)); +} + .button { font-weight: 500; padding-top: 0.45rem; diff --git a/cmd/tailscale/cli/web.go b/cmd/tailscale/cli/web.go index 68e63ddf9..37085ffc1 100644 --- a/cmd/tailscale/cli/web.go +++ b/cmd/tailscale/cli/web.go @@ -60,6 +60,15 @@ type tmplData struct { LicensesURL string TUNMode bool IsSynology bool + DSMVersion int // 6 or 7, if IsSynology=true + IPNVersion string +} + +type postedData struct { + AdvertiseRoutes string + AdvertiseExitNode bool + Reauthenticate bool + ForceLogout bool } var webCmd = &ffcli.Command{ @@ -133,7 +142,7 @@ func runWeb(ctx context.Context, args []string) error { Handler: http.HandlerFunc(webHandler), } - log.Printf("web server runNIng on: https://%s", server.Addr) + log.Printf("web server running on: https://%s", server.Addr) return server.ListenAndServeTLS("", "") } else { log.Printf("web server running on: %s", urlOfListenAddr(webArgs.listen)) @@ -353,11 +362,7 @@ func webHandler(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { defer r.Body.Close() - var postData struct { - AdvertiseRoutes string - AdvertiseExitNode bool - Reauthenticate bool - } + var postData postedData type mi map[string]any if err := json.NewDecoder(r.Body).Decode(&postData); err != nil { w.WriteHeader(400) @@ -386,8 +391,15 @@ func webHandler(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "application/json") - log.Printf("tailscaleUp(reauth=%v) ...", postData.Reauthenticate) - url, err := tailscaleUp(r.Context(), st, postData.Reauthenticate) + var reauth, logout bool + if postData.Reauthenticate { + reauth = true + } + if postData.ForceLogout { + logout = true + } + log.Printf("tailscaleUp(reauth=%v, logout=%v) ...", reauth, logout) + url, err := tailscaleUp(r.Context(), st, postData) log.Printf("tailscaleUp = (URL %v, %v)", url != "", err) if err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -404,6 +416,7 @@ func webHandler(w http.ResponseWriter, r *http.Request) { profile := st.User[st.Self.UserID] deviceName := strings.Split(st.Self.DNSName, ".")[0] + versionShort := strings.Split(st.Version, "-")[0] data := tmplData{ SynologyUser: user, Profile: profile, @@ -412,6 +425,8 @@ func webHandler(w http.ResponseWriter, r *http.Request) { LicensesURL: licensesURL(), TUNMode: st.TUN, IsSynology: distro.Get() == distro.Synology || envknob.Bool("TS_FAKE_SYNOLOGY"), + DSMVersion: distro.DSMVersion(), + IPNVersion: versionShort, } exitNodeRouteV4 := netip.MustParsePrefix("0.0.0.0/0") exitNodeRouteV6 := netip.MustParsePrefix("::/0") @@ -437,10 +452,18 @@ func webHandler(w http.ResponseWriter, r *http.Request) { w.Write(buf.Bytes()) } -func tailscaleUp(ctx context.Context, st *ipnstate.Status, forceReauth bool) (authURL string, retErr error) { +func tailscaleUp(ctx context.Context, st *ipnstate.Status, postData postedData) (authURL string, retErr error) { + if postData.ForceLogout { + if err := localClient.Logout(ctx); err != nil { + return "", fmt.Errorf("Logout error: %w", err) + } + return "", nil + } + origAuthURL := st.AuthURL isRunning := st.BackendState == ipn.Running.String() + forceReauth := postData.Reauthenticate if !forceReauth { if origAuthURL != "" { return origAuthURL, nil diff --git a/cmd/tailscale/cli/web.html b/cmd/tailscale/cli/web.html index 438877b29..8b0ac2d81 100644 --- a/cmd/tailscale/cli/web.html +++ b/cmd/tailscale/cli/web.html @@ -27,9 +27,13 @@
{{ with .Profile.LoginName }} -
+ {{ end }}
@@ -44,7 +48,7 @@ {{ if .IP }}
+ class="border border-gray-200 bg-gray-0 rounded-md p-2 pl-3 pr-3 width-full flex items-center justify-between">
-

{{.DeviceName}}

+
+

{{.DeviceName}}

+
{{.IP}}
+

+ Debug info: Tailscale {{ .IPNVersion }}, tun={{.TUNMode}}{{ if .IsSynology }}, DSM{{ .DSMVersion}} + {{if not .TUNMode}} + (outgoing access not configured) + {{end}} + {{end}} +

{{ end }} {{ if or (eq .Status "NeedsLogin") (eq .Status "NoState") }} {{ if .IP }} @@ -95,18 +110,6 @@ {{end}}
- - {{ if .IsSynology }} -
- Outgoing access {{ if .TUNMode }}enabled{{ else }}not configured{{ end }}. - Learn more → -
- {{ end }} {{ end }}