cmd/tailscale/cli: redact private key in debug netmap output by default

This makes `tailscale debug watch-ipn` safe to use for troubleshooting
user issues, in addition to local debugging during development.

Signed-off-by: David Anderson <danderson@tailscale.com>
pull/6883/head
David Anderson 2 years ago committed by Dave Anderson
parent d72575eaaa
commit 91e64ca74f

@ -134,6 +134,7 @@ var debugCmd = &ffcli.Command{
fs := newFlagSet("watch-ipn")
fs.BoolVar(&watchIPNArgs.netmap, "netmap", true, "include netmap in messages")
fs.BoolVar(&watchIPNArgs.initial, "initial", false, "include initial status")
fs.BoolVar(&watchIPNArgs.showPrivateKey, "show-private-key", false, "include node private key in printed netmap")
return fs
})(),
},
@ -319,8 +320,9 @@ func runPrefs(ctx context.Context, args []string) error {
}
var watchIPNArgs struct {
netmap bool
initial bool
netmap bool
initial bool
showPrivateKey bool
}
func runWatchIPN(ctx context.Context, args []string) error {
@ -328,6 +330,9 @@ func runWatchIPN(ctx context.Context, args []string) error {
if watchIPNArgs.initial {
mask = ipn.NotifyInitialState | ipn.NotifyInitialPrefs | ipn.NotifyInitialNetMap
}
if !watchIPNArgs.showPrivateKey {
mask |= ipn.NotifyNoPrivateKeys
}
watcher, err := localClient.WatchIPNBus(ctx, mask)
if err != nil {
return err

@ -65,6 +65,8 @@ const (
NotifyInitialState // if set, the first Notify message (sent immediately) will contain the current State + BrowseToURL
NotifyInitialPrefs // if set, the first Notify message (sent immediately) will contain the current Prefs
NotifyInitialNetMap // if set, the first Notify message (sent immediately) will contain the current NetMap
NotifyNoPrivateKeys // if set, private keys that would normally be sent in updates are zeroed out
)
// Notify is a communication from a backend (e.g. tailscaled) to a frontend

@ -1742,6 +1742,24 @@ func (b *LocalBackend) readPoller() {
func (b *LocalBackend) WatchNotifications(ctx context.Context, mask ipn.NotifyWatchOpt, fn func(roNotify *ipn.Notify) (keepGoing bool)) {
ch := make(chan *ipn.Notify, 128)
origFn := fn
if mask&ipn.NotifyNoPrivateKeys != 0 {
fn = func(n *ipn.Notify) bool {
if n.NetMap == nil || n.NetMap.PrivateKey.IsZero() {
return origFn(n)
}
// The netmap in n is shared across all watchers, so to mutate it for a
// single watcher we have to clone the notify and the netmap. We can
// make shallow clones, at least.
nm2 := *n.NetMap
n2 := *n
n2.NetMap = &nm2
n2.NetMap.PrivateKey = key.NodePrivate{}
return origFn(&n2)
}
}
var ini *ipn.Notify
b.mu.Lock()

Loading…
Cancel
Save