From 985e979d1d1d9dd85bd806522f7af2f9725c78d7 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 17 Sep 2021 22:05:32 +0200 Subject: [PATCH] Integrate SPN into interception --- firewall/filter.go | 9 ++++--- firewall/interception.go | 57 ++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/firewall/filter.go b/firewall/filter.go index 81f62454..9c0efdeb 100644 --- a/firewall/filter.go +++ b/firewall/filter.go @@ -3,6 +3,7 @@ package firewall import ( "github.com/safing/portbase/config" "github.com/safing/portbase/modules/subsystems" + "github.com/safing/spn/captain" "github.com/safing/portbase/modules" @@ -13,6 +14,7 @@ import ( var ( filterModule *modules.Module filterEnabled config.BoolOption + tunnelEnabled config.BoolOption ) func init() { @@ -28,8 +30,8 @@ func init() { Key: CfgOptionEnableFilterKey, Description: "Start the Privacy Filter module. If turned off, all privacy filter protections are fully disabled on this device.", OptType: config.OptTypeBool, - ExpertiseLevel: config.ExpertiseLevelUser, - ReleaseLevel: config.ReleaseLevelBeta, + ExpertiseLevel: config.ExpertiseLevelDeveloper, + ReleaseLevel: config.ReleaseLevelStable, DefaultValue: true, Annotations: config.Annotations{ config.CategoryAnnotation: "General", @@ -44,6 +46,7 @@ func filterPrep() (err error) { return err } - filterEnabled = config.GetAsBool(CfgOptionEnableFilterKey, true) + filterEnabled = config.Concurrent.GetAsBool(CfgOptionEnableFilterKey, true) + tunnelEnabled = config.Concurrent.GetAsBool(captain.CfgOptionEnableSPNKey, false) return nil } diff --git a/firewall/interception.go b/firewall/interception.go index 007e3785..575179be 100644 --- a/firewall/interception.go +++ b/firewall/interception.go @@ -9,6 +9,8 @@ import ( "sync/atomic" "time" + "github.com/safing/spn/captain" + "github.com/google/gopacket/layers" "github.com/safing/portmaster/netenv" "golang.org/x/sync/singleflight" @@ -22,7 +24,7 @@ import ( "github.com/safing/portmaster/network" "github.com/safing/portmaster/network/netutils" "github.com/safing/portmaster/network/packet" - "github.com/safing/spn/captain" + "github.com/safing/spn/crew" "github.com/safing/spn/sluice" // module dependencies @@ -346,32 +348,41 @@ func initialHandler(conn *network.Connection, pkt packet.Packet) { return } - // check if filtering is enabled - if !filterEnabled() { - conn.Inspecting = false + // TODO: enable inspecting again + conn.Inspecting = false + + // Filter, if enabled. + if filterEnabled() { + log.Tracer(pkt.Ctx()).Trace("filter: starting decision process") + DecideOnConnection(pkt.Ctx(), conn, pkt) + } else { conn.Accept("privacy filter disabled", noReasonOptionKey) - conn.StopFirewallHandler() - issueVerdict(conn, pkt, 0, true) - return } - log.Tracer(pkt.Ctx()).Trace("filter: starting decision process") - DecideOnConnection(pkt.Ctx(), conn, pkt) - conn.Inspecting = false // TODO: enable inspecting again + // Tunnel, if enabled. + if pkt.IsOutbound() && conn.Entity.IPScope.IsGlobal() && + tunnelEnabled() && conn.Verdict == network.VerdictAccept && + conn.Process().Profile() != nil && + conn.Process().Profile().UseSPN() { - // tunneling - // TODO: add implementation for forced tunneling - if pkt.IsOutbound() && - captain.ClientReady() && - conn.Entity.IPScope.IsGlobal() && - conn.Verdict == network.VerdictAccept { - // try to tunnel - err := sluice.AwaitRequest(pkt.Info(), conn.Entity.Domain) - if err != nil { - log.Tracer(pkt.Ctx()).Tracef("filter: not tunneling: %s", err) - } else { - log.Tracer(pkt.Ctx()).Trace("filter: tunneling request") - conn.Verdict = network.VerdictRerouteToTunnel + // Exclude requests of the SPN itself. + if !captain.IsExcepted(conn.Entity.IP) { + // Check if client is ready. + if captain.ClientReady() { + // Queue request in sluice. + err := sluice.AwaitRequest(conn, crew.HandleSluiceRequest) + if err != nil { + log.Tracer(pkt.Ctx()).Warningf("failed to rqeuest tunneling: %s", err) + conn.Failed("failed to request tunneling", "") + } else { + log.Tracer(pkt.Ctx()).Trace("filter: tunneling requested") + conn.Verdict = network.VerdictRerouteToTunnel + } + } else { + // Block connection as SPN is not ready yet. + log.Tracer(pkt.Ctx()).Trace("SPN not ready for tunneling") + conn.Failed("SPN not ready for tunneling", "") + } } }