Skip to content

Commit

Permalink
Merge pull request #1295 from safing/feature/routing-improvements-and…
Browse files Browse the repository at this point in the history
…-other-stuff

Routing improvements
  • Loading branch information
dhaavi authored Aug 24, 2023
2 parents a2d877d + 3657470 commit a2c24f1
Show file tree
Hide file tree
Showing 20 changed files with 2,015 additions and 633 deletions.
20 changes: 18 additions & 2 deletions firewall/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
// Configuration Keys.
var (
CfgOptionEnableFilterKey = "filter/enable"
filterEnabled config.BoolOption

CfgOptionAskWithSystemNotificationsKey = "filter/askWithSystemNotifications"
cfgOptionAskWithSystemNotificationsOrder = 2
Expand All @@ -33,6 +34,23 @@ var (

func registerConfig() error {
err := config.Register(&config.Option{
Name: "Enable Privacy Filter",
Key: CfgOptionEnableFilterKey,
Description: "Enable the Privacy Filter. If turned off, all privacy filter protections are fully disabled on this device. Not meant to be disabled in production - only turn off for testing.",
OptType: config.OptTypeBool,
ExpertiseLevel: config.ExpertiseLevelDeveloper,
ReleaseLevel: config.ReleaseLevelExperimental,
DefaultValue: true,
Annotations: config.Annotations{
config.CategoryAnnotation: "General",
},
})
if err != nil {
return err
}
filterEnabled = config.Concurrent.GetAsBool(CfgOptionEnableFilterKey, true)

err = config.Register(&config.Option{
Name: "Permanent Verdicts",
Key: CfgOptionPermanentVerdictsKey,
Description: "The Portmaster's system integration intercepts every single packet. Usually the first packet is enough for the Portmaster to set the verdict for a connection - ie. to allow or deny it. Making these verdicts permanent means that the Portmaster will tell the system integration that is does not want to see any more packets of that single connection. This brings a major performance increase.",
Expand Down Expand Up @@ -118,7 +136,6 @@ var (
devMode config.BoolOption
apiListenAddress config.StringOption

filterEnabled config.BoolOption
tunnelEnabled config.BoolOption
useCommunityNodes config.BoolOption

Expand All @@ -129,7 +146,6 @@ func getConfig() {
devMode = config.Concurrent.GetAsBool(core.CfgDevModeKey, false)
apiListenAddress = config.GetAsString(api.CfgDefaultListenAddressKey, "")

filterEnabled = config.Concurrent.GetAsBool(CfgOptionEnableFilterKey, true)
tunnelEnabled = config.Concurrent.GetAsBool(captain.CfgOptionEnableSPNKey, false)
useCommunityNodes = config.Concurrent.GetAsBool(captain.CfgOptionUseCommunityNodesKey, true)

Expand Down
14 changes: 1 addition & 13 deletions firewall/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package firewall
import (
"context"

"github.com/safing/portbase/config"
"github.com/safing/portbase/log"
"github.com/safing/portbase/modules"
"github.com/safing/portbase/modules/subsystems"
Expand All @@ -22,18 +21,7 @@ func init() {
"DNS and Network Filter",
module,
"config:filter/",
&config.Option{
Name: "Privacy Filter Module",
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.ExpertiseLevelDeveloper,
ReleaseLevel: config.ReleaseLevelStable,
DefaultValue: true,
Annotations: config.Annotations{
config.CategoryAnnotation: "General",
},
},
nil,
)
}

Expand Down
74 changes: 49 additions & 25 deletions firewall/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
"errors"

"github.com/safing/portbase/log"
"github.com/safing/portmaster/intel"
"github.com/safing/portmaster/netenv"
"github.com/safing/portmaster/network"
"github.com/safing/portmaster/network/packet"
"github.com/safing/portmaster/process"
"github.com/safing/portmaster/profile"
"github.com/safing/portmaster/profile/endpoints"
"github.com/safing/portmaster/resolver"
Expand Down Expand Up @@ -124,66 +126,88 @@ func requestTunneling(ctx context.Context, conn *network.Connection) error {
return errors.New("no profile set")
}

// Get tunnel options.
conn.TunnelOpts = DeriveTunnelOptions(layeredProfile, conn.Process(), conn.Entity, conn.Encrypted)

// Queue request in sluice.
err := sluice.AwaitRequest(conn, crew.HandleSluiceRequest)
if err != nil {
return err
}

log.Tracer(ctx).Trace("filter: tunneling requested")
return nil
}

func init() {
navigator.DeriveTunnelOptions = func(lp *profile.LayeredProfile, destination *intel.Entity, connEncrypted bool) *navigator.Options {
return DeriveTunnelOptions(lp, nil, destination, connEncrypted)
}
}

// DeriveTunnelOptions derives and returns the tunnel options from the connection and profile.
func DeriveTunnelOptions(lp *profile.LayeredProfile, proc *process.Process, destination *intel.Entity, connEncrypted bool) *navigator.Options {
// Set options.
conn.TunnelOpts = &navigator.Options{
HubPolicies: layeredProfile.StackedExitHubPolicies(),
CheckHubExitPolicyWith: conn.Entity,
RequireTrustedDestinationHubs: !conn.Encrypted,
RoutingProfile: layeredProfile.SPNRoutingAlgorithm(),
tunnelOpts := &navigator.Options{
Transit: &navigator.TransitHubOptions{
HubPolicies: lp.StackedTransitHubPolicies(),
},
Destination: &navigator.DestinationHubOptions{
HubPolicies: lp.StackedExitHubPolicies(),
CheckHubPolicyWith: destination,
},
RoutingProfile: lp.SPNRoutingAlgorithm(),
}
if !connEncrypted {
tunnelOpts.Destination.Regard = tunnelOpts.Destination.Regard.Add(navigator.StateTrusted)
}

// Add required verified owners if community nodes should not be used.
if !useCommunityNodes() {
conn.TunnelOpts.RequireVerifiedOwners = captain.NonCommunityVerifiedOwners
tunnelOpts.Transit.RequireVerifiedOwners = captain.NonCommunityVerifiedOwners
tunnelOpts.Destination.RequireVerifiedOwners = captain.NonCommunityVerifiedOwners
}

// Get routing profile for checking for upgrades.
routingProfile := navigator.GetRoutingProfile(conn.TunnelOpts.RoutingProfile)
routingProfile := navigator.GetRoutingProfile(tunnelOpts.RoutingProfile)

// If we have any exit hub policies, we must be able to hop in order to follow the policy.
// Switch to single-hop routing to allow for routing with hub selection.
if routingProfile.MaxHops <= 1 && conn.TunnelOpts.HubPoliciesAreSet() {
conn.TunnelOpts.RoutingProfile = navigator.RoutingProfileSingleHopID
if routingProfile.MaxHops <= 1 && navigator.HubPoliciesAreSet(tunnelOpts.Destination.HubPolicies) {
tunnelOpts.RoutingProfile = navigator.RoutingProfileSingleHopID
}

// If the current home node is not trusted, then upgrade at least to two hops.
if routingProfile.MinHops < 2 {
homeNode, _ := navigator.Main.GetHome()
if homeNode != nil && !homeNode.State.Has(navigator.StateTrusted) {
conn.TunnelOpts.RoutingProfile = navigator.RoutingProfileDoubleHopID
tunnelOpts.RoutingProfile = navigator.RoutingProfileDoubleHopID
}
}

// Special handling for the internal DNS resolver.
if conn.Process().Pid == ownPID && resolver.IsResolverAddress(conn.Entity.IP, conn.Entity.Port) {
if proc != nil && proc.Pid == ownPID && resolver.IsResolverAddress(destination.IP, destination.Port) {
dnsExitHubPolicy, err := captain.GetDNSExitHubPolicy()
if err != nil {
log.Errorf("firewall: failed to get dns exit hub policy: %s", err)
}

if err == nil && dnsExitHubPolicy.IsSet() {
// Apply the dns exit hub policy, if set.
conn.TunnelOpts.HubPolicies = []endpoints.Endpoints{dnsExitHubPolicy}
tunnelOpts.Destination.HubPolicies = []endpoints.Endpoints{dnsExitHubPolicy}
// Use the routing algorithm from the profile, as the home profile won't work with the policy.
conn.TunnelOpts.RoutingProfile = layeredProfile.SPNRoutingAlgorithm()
tunnelOpts.RoutingProfile = lp.SPNRoutingAlgorithm()
// Raise the routing algorithm at least to single-hop.
if conn.TunnelOpts.RoutingProfile == navigator.RoutingProfileHomeID {
conn.TunnelOpts.RoutingProfile = navigator.RoutingProfileSingleHopID
if tunnelOpts.RoutingProfile == navigator.RoutingProfileHomeID {
tunnelOpts.RoutingProfile = navigator.RoutingProfileSingleHopID
}
} else {
// Disable any policies for the internal DNS resolver.
conn.TunnelOpts.HubPolicies = nil
tunnelOpts.Destination.HubPolicies = nil
// Always use the home routing profile for the internal DNS resolver.
conn.TunnelOpts.RoutingProfile = navigator.RoutingProfileHomeID
tunnelOpts.RoutingProfile = navigator.RoutingProfileHomeID
}
}

// Queue request in sluice.
err := sluice.AwaitRequest(conn, crew.HandleSluiceRequest)
if err != nil {
return err
}

log.Tracer(ctx).Trace("filter: tunneling requested")
return nil
return tunnelOpts
}
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ require (
github.com/miekg/dns v1.1.55
github.com/oschwald/maxminddb-golang v1.12.0
github.com/safing/jess v0.3.1
github.com/safing/portbase v0.17.1
github.com/safing/portbase v0.17.2
github.com/safing/portmaster-android/go v0.0.0-20230605085256-6abf4c495626
github.com/safing/spn v0.6.15
github.com/safing/spn v0.6.16
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/spf13/cobra v1.7.0
github.com/spkg/zipfs v0.7.1
Expand Down Expand Up @@ -52,7 +52,7 @@ require (
github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
Expand Down Expand Up @@ -208,12 +208,12 @@ github.com/safing/jess v0.3.1 h1:cMZVhi2whW/YdD98MPLeLIWJndQ7o2QVt2HefQ/ByFA=
github.com/safing/jess v0.3.1/go.mod h1:aj73Eot1zm2ETkJuw9hJlIO8bRom52uBbsCHemvlZmA=
github.com/safing/portbase v0.15.2/go.mod h1:5bHi99fz7Hh/wOsZUOI631WF9ePSHk57c4fdlOMS91Y=
github.com/safing/portbase v0.16.2/go.mod h1:mzNCWqPbO7vIYbbK5PElGbudwd2vx4YPNawymL8Aro8=
github.com/safing/portbase v0.17.1 h1:q2aNHjJw4aoqTqKOxZpxRhYCciHw1exZ7lfGuB78i1E=
github.com/safing/portbase v0.17.1/go.mod h1:1cVgDZIsPiqM5b+K88Kshir5PGIvsftYkx7y1x925+8=
github.com/safing/portbase v0.17.2 h1:HzJkURMmXkv30wMHB7xJ+Z5U5aTMe+EzvlHavKoKkos=
github.com/safing/portbase v0.17.2/go.mod h1:1cVgDZIsPiqM5b+K88Kshir5PGIvsftYkx7y1x925+8=
github.com/safing/portmaster-android/go v0.0.0-20230605085256-6abf4c495626 h1:olc/REnUdpJN/Gmz8B030OxLpMYxyPDTrDILNEw0eKs=
github.com/safing/portmaster-android/go v0.0.0-20230605085256-6abf4c495626/go.mod h1:abwyAQrZGemWbSh/aCD9nnkp0SvFFf/mGWkAbOwPnFE=
github.com/safing/spn v0.6.15 h1:NbjXjZNy6dgYjd36wa/teip9dHtjjzKKYWwsWaok9y4=
github.com/safing/spn v0.6.15/go.mod h1:Mh9bmkqFhO/dHNi9RWXzoXjQij893I4Lj8Wn4tQ0KZA=
github.com/safing/spn v0.6.16 h1:z80H3X6wjsmizjWgichqYRyw3hSVB7rJpsDUDL2EWo0=
github.com/safing/spn v0.6.16/go.mod h1:2CuZfJJazIYyMDrhiwX2eFal0urQyLiX8rXLvJiCTcw=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/seehuhn/fortuna v1.0.1 h1:lu9+CHsmR0bZnx5Ay646XvCSRJ8PJTi5UYJwDBX68H0=
Expand Down
Loading

0 comments on commit a2c24f1

Please sign in to comment.