ipn/localapi: add localapi debug endpoints for packet filter/matches
For debugging #6423. This is easier than TS_DEBUG_MAP, as this means I can pipe things into jq, etc. Updates #6423 Change-Id: Ib3e7496b2eb3f47d4bed42e9b8045a441424b23c Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
b2b8e62476
commit
eafbf8886d
|
@ -16,6 +16,7 @@ import (
|
|||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/netmap"
|
||||
"tailscale.com/types/opt"
|
||||
"tailscale.com/types/views"
|
||||
"tailscale.com/wgengine/filter"
|
||||
)
|
||||
|
||||
|
@ -40,6 +41,7 @@ type mapSession struct {
|
|||
lastDNSConfig *tailcfg.DNSConfig
|
||||
lastDERPMap *tailcfg.DERPMap
|
||||
lastUserProfile map[tailcfg.UserID]tailcfg.UserProfile
|
||||
lastPacketFilterRules views.Slice[tailcfg.FilterRule]
|
||||
lastParsedPacketFilter []filter.Match
|
||||
lastSSHPolicy *tailcfg.SSHPolicy
|
||||
collectServices bool
|
||||
|
@ -96,6 +98,7 @@ func (ms *mapSession) netmapForResponse(resp *tailcfg.MapResponse) *netmap.Netwo
|
|||
|
||||
if pf := resp.PacketFilter; pf != nil {
|
||||
var err error
|
||||
ms.lastPacketFilterRules = views.SliceOf(pf)
|
||||
ms.lastParsedPacketFilter, err = filter.MatchesFromFilterRules(pf)
|
||||
if err != nil {
|
||||
ms.logf("parsePacketFilter: %v", err)
|
||||
|
@ -147,21 +150,22 @@ func (ms *mapSession) netmapForResponse(resp *tailcfg.MapResponse) *netmap.Netwo
|
|||
}
|
||||
|
||||
nm := &netmap.NetworkMap{
|
||||
NodeKey: ms.privateNodeKey.Public(),
|
||||
PrivateKey: ms.privateNodeKey,
|
||||
MachineKey: ms.machinePubKey,
|
||||
Peers: resp.Peers,
|
||||
UserProfiles: make(map[tailcfg.UserID]tailcfg.UserProfile),
|
||||
Domain: ms.lastDomain,
|
||||
DomainAuditLogID: ms.lastDomainAuditLogID,
|
||||
DNS: *ms.lastDNSConfig,
|
||||
PacketFilter: ms.lastParsedPacketFilter,
|
||||
SSHPolicy: ms.lastSSHPolicy,
|
||||
CollectServices: ms.collectServices,
|
||||
DERPMap: ms.lastDERPMap,
|
||||
Debug: debug,
|
||||
ControlHealth: ms.lastHealth,
|
||||
TKAEnabled: ms.lastTKAInfo != nil && !ms.lastTKAInfo.Disabled,
|
||||
NodeKey: ms.privateNodeKey.Public(),
|
||||
PrivateKey: ms.privateNodeKey,
|
||||
MachineKey: ms.machinePubKey,
|
||||
Peers: resp.Peers,
|
||||
UserProfiles: make(map[tailcfg.UserID]tailcfg.UserProfile),
|
||||
Domain: ms.lastDomain,
|
||||
DomainAuditLogID: ms.lastDomainAuditLogID,
|
||||
DNS: *ms.lastDNSConfig,
|
||||
PacketFilter: ms.lastParsedPacketFilter,
|
||||
PacketFilterRules: ms.lastPacketFilterRules,
|
||||
SSHPolicy: ms.lastSSHPolicy,
|
||||
CollectServices: ms.collectServices,
|
||||
DERPMap: ms.lastDERPMap,
|
||||
Debug: debug,
|
||||
ControlHealth: ms.lastHealth,
|
||||
TKAEnabled: ms.lastTKAInfo != nil && !ms.lastTKAInfo.Disabled,
|
||||
}
|
||||
ms.netMapBuilding = nm
|
||||
|
||||
|
|
|
@ -61,39 +61,41 @@ var handler = map[string]localAPIHandler{
|
|||
|
||||
// The other /localapi/v0/NAME handlers are exact matches and contain only NAME
|
||||
// without a trailing slash:
|
||||
"bugreport": (*Handler).serveBugReport,
|
||||
"check-ip-forwarding": (*Handler).serveCheckIPForwarding,
|
||||
"check-prefs": (*Handler).serveCheckPrefs,
|
||||
"component-debug-logging": (*Handler).serveComponentDebugLogging,
|
||||
"debug": (*Handler).serveDebug,
|
||||
"debug-derp-region": (*Handler).serveDebugDERPRegion,
|
||||
"derpmap": (*Handler).serveDERPMap,
|
||||
"dev-set-state-store": (*Handler).serveDevSetStateStore,
|
||||
"dial": (*Handler).serveDial,
|
||||
"file-targets": (*Handler).serveFileTargets,
|
||||
"goroutines": (*Handler).serveGoroutines,
|
||||
"id-token": (*Handler).serveIDToken,
|
||||
"login-interactive": (*Handler).serveLoginInteractive,
|
||||
"logout": (*Handler).serveLogout,
|
||||
"metrics": (*Handler).serveMetrics,
|
||||
"ping": (*Handler).servePing,
|
||||
"prefs": (*Handler).servePrefs,
|
||||
"pprof": (*Handler).servePprof,
|
||||
"serve-config": (*Handler).serveServeConfig,
|
||||
"set-dns": (*Handler).serveSetDNS,
|
||||
"set-expiry-sooner": (*Handler).serveSetExpirySooner,
|
||||
"start": (*Handler).serveStart,
|
||||
"status": (*Handler).serveStatus,
|
||||
"tka/init": (*Handler).serveTKAInit,
|
||||
"tka/log": (*Handler).serveTKALog,
|
||||
"tka/modify": (*Handler).serveTKAModify,
|
||||
"tka/sign": (*Handler).serveTKASign,
|
||||
"tka/status": (*Handler).serveTKAStatus,
|
||||
"tka/disable": (*Handler).serveTKADisable,
|
||||
"tka/force-local-disable": (*Handler).serveTKALocalDisable,
|
||||
"upload-client-metrics": (*Handler).serveUploadClientMetrics,
|
||||
"watch-ipn-bus": (*Handler).serveWatchIPNBus,
|
||||
"whois": (*Handler).serveWhoIs,
|
||||
"bugreport": (*Handler).serveBugReport,
|
||||
"check-ip-forwarding": (*Handler).serveCheckIPForwarding,
|
||||
"check-prefs": (*Handler).serveCheckPrefs,
|
||||
"component-debug-logging": (*Handler).serveComponentDebugLogging,
|
||||
"debug": (*Handler).serveDebug,
|
||||
"debug-derp-region": (*Handler).serveDebugDERPRegion,
|
||||
"debug-packet-filter-matches": (*Handler).serveDebugPacketFilterMatches,
|
||||
"debug-packet-filter-rules": (*Handler).serveDebugPacketFilterRules,
|
||||
"derpmap": (*Handler).serveDERPMap,
|
||||
"dev-set-state-store": (*Handler).serveDevSetStateStore,
|
||||
"dial": (*Handler).serveDial,
|
||||
"file-targets": (*Handler).serveFileTargets,
|
||||
"goroutines": (*Handler).serveGoroutines,
|
||||
"id-token": (*Handler).serveIDToken,
|
||||
"login-interactive": (*Handler).serveLoginInteractive,
|
||||
"logout": (*Handler).serveLogout,
|
||||
"metrics": (*Handler).serveMetrics,
|
||||
"ping": (*Handler).servePing,
|
||||
"prefs": (*Handler).servePrefs,
|
||||
"pprof": (*Handler).servePprof,
|
||||
"serve-config": (*Handler).serveServeConfig,
|
||||
"set-dns": (*Handler).serveSetDNS,
|
||||
"set-expiry-sooner": (*Handler).serveSetExpirySooner,
|
||||
"start": (*Handler).serveStart,
|
||||
"status": (*Handler).serveStatus,
|
||||
"tka/init": (*Handler).serveTKAInit,
|
||||
"tka/log": (*Handler).serveTKALog,
|
||||
"tka/modify": (*Handler).serveTKAModify,
|
||||
"tka/sign": (*Handler).serveTKASign,
|
||||
"tka/status": (*Handler).serveTKAStatus,
|
||||
"tka/disable": (*Handler).serveTKADisable,
|
||||
"tka/force-local-disable": (*Handler).serveTKALocalDisable,
|
||||
"upload-client-metrics": (*Handler).serveUploadClientMetrics,
|
||||
"watch-ipn-bus": (*Handler).serveWatchIPNBus,
|
||||
"whois": (*Handler).serveWhoIs,
|
||||
}
|
||||
|
||||
func randHex(n int) string {
|
||||
|
@ -506,6 +508,40 @@ func (h *Handler) serveDevSetStateStore(w http.ResponseWriter, r *http.Request)
|
|||
io.WriteString(w, "done\n")
|
||||
}
|
||||
|
||||
func (h *Handler) serveDebugPacketFilterRules(w http.ResponseWriter, r *http.Request) {
|
||||
if !h.PermitWrite {
|
||||
http.Error(w, "debug access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
nm := h.b.NetMap()
|
||||
if nm == nil {
|
||||
http.Error(w, "no netmap", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
enc := json.NewEncoder(w)
|
||||
enc.SetIndent("", "\t")
|
||||
enc.Encode(nm.PacketFilterRules)
|
||||
}
|
||||
|
||||
func (h *Handler) serveDebugPacketFilterMatches(w http.ResponseWriter, r *http.Request) {
|
||||
if !h.PermitWrite {
|
||||
http.Error(w, "debug access denied", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
nm := h.b.NetMap()
|
||||
if nm == nil {
|
||||
http.Error(w, "no netmap", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
enc := json.NewEncoder(w)
|
||||
enc.SetIndent("", "\t")
|
||||
enc.Encode(nm.PacketFilter)
|
||||
}
|
||||
|
||||
func (h *Handler) serveComponentDebugLogging(w http.ResponseWriter, r *http.Request) {
|
||||
if !h.PermitWrite {
|
||||
http.Error(w, "debug access denied", http.StatusForbidden)
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/tka"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/views"
|
||||
"tailscale.com/wgengine/filter"
|
||||
)
|
||||
|
||||
|
@ -38,9 +39,10 @@ type NetworkMap struct {
|
|||
Peers []*tailcfg.Node // sorted by Node.ID
|
||||
DNS tailcfg.DNSConfig
|
||||
// TODO(maisem) : replace with View.
|
||||
Hostinfo tailcfg.Hostinfo
|
||||
PacketFilter []filter.Match
|
||||
SSHPolicy *tailcfg.SSHPolicy // or nil, if not enabled/allowed
|
||||
Hostinfo tailcfg.Hostinfo
|
||||
PacketFilter []filter.Match
|
||||
PacketFilterRules views.Slice[tailcfg.FilterRule]
|
||||
SSHPolicy *tailcfg.SSHPolicy // or nil, if not enabled/allowed
|
||||
|
||||
// CollectServices reports whether this node's Tailnet has
|
||||
// requested that info about services be included in HostInfo.
|
||||
|
|
Loading…
Reference in New Issue