diff --git a/core/api.go b/core/api.go index bf20f3ba..49cb1428 100644 --- a/core/api.go +++ b/core/api.go @@ -1,13 +1,17 @@ package core import ( + "net/http" + "github.com/safing/portbase/api" "github.com/safing/portbase/log" "github.com/safing/portbase/modules" + "github.com/safing/portbase/utils/debug" + "github.com/safing/portmaster/status" "github.com/safing/portmaster/updates" ) -func registerActions() error { +func registerAPIEndpoints() error { if err := api.RegisterEndpoint(api.Endpoint{ Path: "core/shutdown", Read: api.PermitSelf, @@ -24,6 +28,22 @@ func registerActions() error { return err } + if err := api.RegisterEndpoint(api.Endpoint{ + Path: "debug/core", + Read: api.PermitAnyone, + DataFunc: debugInfo, + Name: "Get Debug Information", + Description: "Returns network debugging information, similar to debug/info, but with system status data.", + Parameters: []api.Parameter{{ + Method: http.MethodGet, + Field: "style", + Value: "github", + Description: "Specify the formatting style. The default is simple markdown formatting.", + }}, + }); err != nil { + return err + } + return nil } @@ -41,3 +61,21 @@ func restart(_ *api.Request) (msg string, err error) { updates.RestartNow() return "restart initiated", nil } + +// debugInfo returns the debugging information for support requests. +func debugInfo(ar *api.Request) (data []byte, err error) { + // Create debug information helper. + di := new(debug.Info) + di.Style = ar.Request.URL.Query().Get("style") + + // Add debug information. + di.AddVersionInfo() + di.AddPlatformInfo(ar.Context()) + status.AddToDebugInfo(di) + di.AddLastReportedModuleError() + di.AddLastUnexpectedLogs() + di.AddGoroutineStack() + + // Return data. + return di.Bytes(), nil +} diff --git a/core/core.go b/core/core.go index 5fb7665b..8674c2a7 100644 --- a/core/core.go +++ b/core/core.go @@ -55,7 +55,7 @@ func start() error { return err } - if err := registerActions(); err != nil { + if err := registerAPIEndpoints(); err != nil { return err } diff --git a/status/module.go b/status/module.go index 05e3c7cc..61a071da 100644 --- a/status/module.go +++ b/status/module.go @@ -2,8 +2,10 @@ package status import ( "context" + "fmt" "github.com/safing/portbase/modules" + "github.com/safing/portbase/utils/debug" "github.com/safing/portmaster/netenv" ) @@ -39,3 +41,16 @@ func start() error { return nil } + +// AddToDebugInfo adds the system status to the given debug.Info. +func AddToDebugInfo(di *debug.Info) { + di.AddSection( + fmt.Sprintf("Status: %s", SecurityLevelString(ActiveSecurityLevel())), + debug.UseCodeSection|debug.AddContentLineBreaks, + fmt.Sprintf("ActiveSecurityLevel: %s", SecurityLevelString(ActiveSecurityLevel())), + fmt.Sprintf("SelectedSecurityLevel: %s", SecurityLevelString(SelectedSecurityLevel())), + fmt.Sprintf("ThreatMitigationLevel: %s", SecurityLevelString(getHighestMitigationLevel())), + fmt.Sprintf("CaptivePortal: %s", netenv.GetCaptivePortal().URL), + fmt.Sprintf("OnlineStatus: %s", netenv.GetOnlineStatus()), + ) +} diff --git a/status/security_level.go b/status/security_level.go index 03a0f4e0..f4770f5d 100644 --- a/status/security_level.go +++ b/status/security_level.go @@ -99,19 +99,19 @@ func SecurityLevelString(level uint8) string { case SecurityLevelOff: return "Off" case SecurityLevelNormal: - return "Normal" + return "Trusted" case SecurityLevelHigh: - return "High" + return "Untrusted" case SecurityLevelExtreme: - return "Extreme" + return "Danger" case SecurityLevelsNormalAndHigh: - return "Normal and High" + return "Trusted and Untrusted" case SecurityLevelsNormalAndExtreme: - return "Normal and Extreme" + return "Trusted and Danger" case SecurityLevelsHighAndExtreme: - return "High and Extreme" + return "Untrusted and Danger" case SecurityLevelsAll: - return "Normal, High and Extreme" + return "Trusted, Untrusted and Danger" default: return "INVALID" }