Merge pull request #839 from safing/fix/block-connections-on-conf-change
Block connections on config change
This commit is contained in:
@@ -182,12 +182,12 @@ func FilterResolvedDNS(
|
||||
return rrCache
|
||||
}
|
||||
|
||||
// Only filter criticial things if request comes from the system resolver.
|
||||
// Only filter critical things if request comes from the system resolver.
|
||||
sysResolver := conn.Process().IsSystemResolver()
|
||||
|
||||
// Filter dns records and return if the query is blocked.
|
||||
rrCache = filterDNSResponse(ctx, conn, layeredProfile, rrCache, sysResolver)
|
||||
if conn.Verdict == network.VerdictBlock {
|
||||
if conn.Verdict.Active == network.VerdictBlock {
|
||||
return rrCache
|
||||
}
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ func RunInspectors(conn *network.Connection, pkt packet.Packet) (network.Verdict
|
||||
continue
|
||||
}
|
||||
|
||||
// check if the current verdict is already past the inspection criteria.
|
||||
if conn.Verdict > inspectVerdicts[key] {
|
||||
// check if the active verdict is already past the inspection criteria.
|
||||
if conn.Verdict.Active > inspectVerdicts[key] {
|
||||
activeInspectors[key] = true
|
||||
continue
|
||||
}
|
||||
@@ -86,11 +86,11 @@ func RunInspectors(conn *network.Connection, pkt packet.Packet) (network.Verdict
|
||||
continueInspection = true
|
||||
case BLOCK_CONN:
|
||||
conn.SetVerdict(network.VerdictBlock, "", "", nil)
|
||||
verdict = conn.Verdict
|
||||
verdict = conn.Verdict.Active
|
||||
activeInspectors[key] = true
|
||||
case DROP_CONN:
|
||||
conn.SetVerdict(network.VerdictDrop, "", "", nil)
|
||||
verdict = conn.Verdict
|
||||
verdict = conn.Verdict.Active
|
||||
activeInspectors[key] = true
|
||||
case STOP_INSPECTING:
|
||||
activeInspectors[key] = true
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/safing/portmaster/network"
|
||||
"github.com/safing/portmaster/network/netutils"
|
||||
"github.com/safing/portmaster/network/packet"
|
||||
"github.com/safing/portmaster/network/reference"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -43,14 +44,64 @@ var (
|
||||
ownPID = os.Getpid()
|
||||
)
|
||||
|
||||
const (
|
||||
configChangeEvent = "config change"
|
||||
profileConfigChangeEvent = "profile config change"
|
||||
onSPNConnectEvent = "spn connect"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// TODO: Move interception module to own package (dir).
|
||||
interceptionModule = modules.Register("interception", interceptionPrep, interceptionStart, interceptionStop, "base", "updates", "network", "notifications")
|
||||
interceptionModule = modules.Register("interception", interceptionPrep, interceptionStart, interceptionStop, "base", "updates", "network", "notifications", "profiles")
|
||||
|
||||
network.SetDefaultFirewallHandler(defaultHandler)
|
||||
}
|
||||
|
||||
func interceptionPrep() error {
|
||||
// Reset connections every time configuration changes
|
||||
// this will be triggered on spn enable/disable
|
||||
err := interceptionModule.RegisterEventHook(
|
||||
"config",
|
||||
configChangeEvent,
|
||||
"reset connection verdicts",
|
||||
func(ctx context.Context, _ interface{}) error {
|
||||
resetAllConnectionVerdicts()
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("interception: failed registering event hook: %s", err)
|
||||
}
|
||||
|
||||
// Reset connections every time profile changes
|
||||
err = interceptionModule.RegisterEventHook(
|
||||
"profiles",
|
||||
profileConfigChangeEvent,
|
||||
"reset connection verdicts",
|
||||
func(ctx context.Context, _ interface{}) error {
|
||||
resetAllConnectionVerdicts()
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("failed registering event hook: %s", err)
|
||||
}
|
||||
|
||||
// Reset connections when spn is connected
|
||||
// connect and disconnecting is triggered on config change event but connecting takеs more time
|
||||
err = interceptionModule.RegisterEventHook(
|
||||
"captain",
|
||||
onSPNConnectEvent,
|
||||
"reset connection verdicts",
|
||||
func(ctx context.Context, _ interface{}) error {
|
||||
resetAllConnectionVerdicts()
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("failed registering event hook: %s", err)
|
||||
}
|
||||
|
||||
if err := registerConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -58,6 +109,60 @@ func interceptionPrep() error {
|
||||
return prepAPIAuth()
|
||||
}
|
||||
|
||||
func resetAllConnectionVerdicts() {
|
||||
// Resetting will force all the connection to be evaluated by the firewall again
|
||||
// this will set new verdicts if configuration was update or spn has been disabled or enabled.
|
||||
log.Info("interception: marking all connections for re-evaluation")
|
||||
|
||||
// Create tracing context.
|
||||
ctx, tracer := log.AddTracer(context.Background())
|
||||
defer tracer.Submit()
|
||||
|
||||
// Re-evaluate all connections.
|
||||
for _, conn := range network.GetAllConnections() {
|
||||
func() {
|
||||
conn.Lock()
|
||||
defer conn.Unlock()
|
||||
|
||||
// Skip internal connections:
|
||||
// - Pre-authenticated connections from Portmaster
|
||||
// - Redirected DNS requests
|
||||
// - SPN Uplink to Home Hub
|
||||
if conn.Internal {
|
||||
log.Tracef("skipping internal connection %s", conn)
|
||||
return
|
||||
}
|
||||
|
||||
log.Tracer(ctx).Debugf("filter: re-evaluating verdict of %s", conn)
|
||||
previousVerdict := conn.Verdict.Firewall
|
||||
|
||||
// Apply privacy filter and check tunneling.
|
||||
filterConnection(ctx, conn, nil)
|
||||
|
||||
// Stop existing SPN tunnel if not needed anymore.
|
||||
if conn.Verdict.Active != network.VerdictRerouteToTunnel && conn.TunnelContext != nil {
|
||||
err := conn.TunnelContext.StopTunnel()
|
||||
if err != nil {
|
||||
log.Debugf("filter: failed to stopped unneeded tunnel: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Save if verdict changed.
|
||||
if conn.Verdict.Firewall != previousVerdict {
|
||||
conn.Save()
|
||||
tracer.Infof("filter: verdict of connection %s changed from %s to %s", conn, previousVerdict.Verb(), conn.VerdictVerb())
|
||||
} else {
|
||||
tracer.Tracef("filter: verdict to connection %s unchanged at %s", conn, conn.VerdictVerb())
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
err := interception.ResetVerdictOfAllConnections()
|
||||
if err != nil {
|
||||
log.Errorf("interception: failed to remove persistent verdicts: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func interceptionStart() error {
|
||||
getConfig()
|
||||
|
||||
@@ -90,8 +195,6 @@ func SetNameserverIPMatcher(fn func(ip net.IP) bool) error {
|
||||
}
|
||||
|
||||
func handlePacket(ctx context.Context, pkt packet.Packet) {
|
||||
// log.Errorf("DEBUG: firewall: handling packet %s", pkt)
|
||||
|
||||
// Record metrics.
|
||||
startTime := time.Now()
|
||||
defer packetHandlingHistogram.UpdateDuration(startTime)
|
||||
@@ -135,6 +238,8 @@ func getConnection(pkt packet.Packet) (*network.Connection, error) {
|
||||
|
||||
// Else create new one from the packet.
|
||||
conn = network.NewConnectionFromFirstPacket(pkt)
|
||||
conn.Lock()
|
||||
defer conn.Unlock()
|
||||
conn.SetFirewallHandler(initialHandler)
|
||||
created = true
|
||||
return conn, nil
|
||||
@@ -161,7 +266,7 @@ func getConnection(pkt packet.Packet) (*network.Connection, error) {
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// fastTrackedPermit quickly permits certain network criticial or internal connections.
|
||||
// fastTrackedPermit quickly permits certain network critical or internal connections.
|
||||
func fastTrackedPermit(pkt packet.Packet) (handled bool) {
|
||||
meta := pkt.Info()
|
||||
|
||||
@@ -331,6 +436,7 @@ func fastTrackedPermit(pkt packet.Packet) (handled bool) {
|
||||
func initialHandler(conn *network.Connection, pkt packet.Packet) {
|
||||
log.Tracer(pkt.Ctx()).Trace("filter: handing over to connection-based handler")
|
||||
|
||||
// Check for special (internal) connection cases.
|
||||
switch {
|
||||
case !conn.Inbound && localPortIsPreAuthenticated(conn.Entity.Protocol, conn.LocalPort):
|
||||
// Approve connection.
|
||||
@@ -352,19 +458,36 @@ func initialHandler(conn *network.Connection, pkt packet.Packet) {
|
||||
conn.Entity.IPScope == netutils.LocalMulticast):
|
||||
|
||||
// Reroute rogue dns queries back to Portmaster.
|
||||
conn.Verdict = network.VerdictRerouteToNameserver
|
||||
conn.SetVerdictDirectly(network.VerdictRerouteToNameserver)
|
||||
conn.Reason.Msg = "redirecting rogue dns query"
|
||||
conn.Internal = true
|
||||
// End directly, as no other processing is necessary.
|
||||
conn.StopFirewallHandler()
|
||||
finalizeVerdict(conn)
|
||||
issueVerdict(conn, pkt, 0, true)
|
||||
return
|
||||
}
|
||||
|
||||
case filterEnabled():
|
||||
log.Tracer(pkt.Ctx()).Trace("filter: starting decision process")
|
||||
DecideOnConnection(pkt.Ctx(), conn, pkt)
|
||||
// Apply privacy filter and check tunneling.
|
||||
filterConnection(pkt.Ctx(), conn, pkt)
|
||||
|
||||
// Decide how to continue handling connection.
|
||||
switch {
|
||||
case conn.Inspecting:
|
||||
log.Tracer(pkt.Ctx()).Trace("filter: start inspecting")
|
||||
conn.SetFirewallHandler(inspectThenVerdict)
|
||||
inspectThenVerdict(conn, pkt)
|
||||
default:
|
||||
conn.StopFirewallHandler()
|
||||
issueVerdict(conn, pkt, 0, true)
|
||||
}
|
||||
}
|
||||
|
||||
func filterConnection(ctx context.Context, conn *network.Connection, pkt packet.Packet) {
|
||||
if filterEnabled() {
|
||||
log.Tracer(ctx).Trace("filter: starting decision process")
|
||||
DecideOnConnection(ctx, conn, pkt)
|
||||
} else {
|
||||
conn.Accept("privacy filter disabled", noReasonOptionKey)
|
||||
}
|
||||
|
||||
@@ -385,16 +508,22 @@ func initialHandler(conn *network.Connection, pkt packet.Packet) {
|
||||
}
|
||||
|
||||
// Check if connection should be tunneled.
|
||||
checkTunneling(pkt.Ctx(), conn, pkt)
|
||||
checkTunneling(ctx, conn)
|
||||
|
||||
switch {
|
||||
case conn.Inspecting:
|
||||
log.Tracer(pkt.Ctx()).Trace("filter: start inspecting")
|
||||
conn.SetFirewallHandler(inspectThenVerdict)
|
||||
inspectThenVerdict(conn, pkt)
|
||||
default:
|
||||
conn.StopFirewallHandler()
|
||||
issueVerdict(conn, pkt, 0, true)
|
||||
// Handle verdict records and transitions.
|
||||
finalizeVerdict(conn)
|
||||
|
||||
// Request tunneling if no tunnel is set and connection should be tunneled.
|
||||
if conn.Verdict.Active == network.VerdictRerouteToTunnel &&
|
||||
conn.TunnelContext == nil {
|
||||
err := requestTunneling(ctx, conn)
|
||||
if err != nil {
|
||||
// Set connection to failed, but keep tunneling data.
|
||||
// The tunneling data makes connection easy to recognize as a failed SPN
|
||||
// connection and the data will help with debugging and displaying in the UI.
|
||||
conn.Failed(fmt.Sprintf("failed to request tunneling: %s", err), "")
|
||||
finalizeVerdict(conn)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,8 +554,8 @@ func issueVerdict(conn *network.Connection, pkt packet.Packet, verdict network.V
|
||||
}
|
||||
|
||||
// do not allow to circumvent decision: e.g. to ACCEPT packets from a DROP-ed connection
|
||||
if verdict < conn.Verdict {
|
||||
verdict = conn.Verdict
|
||||
if verdict < conn.Verdict.Active {
|
||||
verdict = conn.Verdict.Active
|
||||
}
|
||||
|
||||
var err error
|
||||
@@ -472,6 +601,65 @@ func issueVerdict(conn *network.Connection, pkt packet.Packet, verdict network.V
|
||||
}
|
||||
}
|
||||
|
||||
// verdictRating rates the privacy and security aspect of verdicts from worst to best.
|
||||
var verdictRating = []network.Verdict{
|
||||
network.VerdictAccept, // Connection allowed in the open.
|
||||
network.VerdictRerouteToTunnel, // Connection allowed, but protected.
|
||||
network.VerdictRerouteToNameserver, // Connection allowed, but resolved via Portmaster.
|
||||
network.VerdictBlock, // Connection blocked, with feedback.
|
||||
network.VerdictDrop, // Connection blocked, without feedback.
|
||||
network.VerdictFailed,
|
||||
network.VerdictUndeterminable,
|
||||
network.VerdictUndecided,
|
||||
}
|
||||
|
||||
func finalizeVerdict(conn *network.Connection) {
|
||||
// Update worst verdict at the end.
|
||||
defer func() {
|
||||
for _, worstVerdict := range verdictRating {
|
||||
if conn.Verdict.Firewall == worstVerdict {
|
||||
conn.Verdict.Worst = worstVerdict
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Check for non-applicable verdicts.
|
||||
// The earlier and clearer we do this, the better.
|
||||
switch conn.Verdict.Firewall { //nolint:exhaustive
|
||||
case network.VerdictUndecided, network.VerdictUndeterminable, network.VerdictFailed:
|
||||
if conn.Inbound {
|
||||
conn.Verdict.Active = network.VerdictDrop
|
||||
} else {
|
||||
conn.Verdict.Active = network.VerdictBlock
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Apply firewall verdict to active verdict.
|
||||
switch {
|
||||
case conn.Verdict.Active == network.VerdictUndecided:
|
||||
// Apply first verdict without change.
|
||||
conn.Verdict.Active = conn.Verdict.Firewall
|
||||
|
||||
case conn.Verdict.Worst == network.VerdictBlock ||
|
||||
conn.Verdict.Worst == network.VerdictDrop ||
|
||||
conn.Verdict.Worst == network.VerdictFailed ||
|
||||
conn.Verdict.Worst == network.VerdictUndeterminable:
|
||||
// Always allow to change verdict from any real initial/worst non-allowed state.
|
||||
// Note: This check needs to happen before updating the Worst verdict.
|
||||
conn.Verdict.Active = conn.Verdict.Firewall
|
||||
|
||||
case reference.IsPacketProtocol(conn.Entity.Protocol):
|
||||
// For known packet protocols, apply firewall verdict unchanged.
|
||||
conn.Verdict.Active = conn.Verdict.Firewall
|
||||
|
||||
case conn.Verdict.Active != conn.Verdict.Firewall:
|
||||
// For all other protocols (most notably, stream protocols), always block after the first change.
|
||||
// Block in both directions, as there is a live connection, which we want to actively kill.
|
||||
conn.Verdict.Active = network.VerdictBlock
|
||||
}
|
||||
}
|
||||
|
||||
// func tunnelHandler(pkt packet.Packet) {
|
||||
// tunnelInfo := GetTunnelInfo(pkt.Info().Dst)
|
||||
// if tunnelInfo == nil {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package interception
|
||||
|
||||
import "github.com/safing/portmaster/network/packet"
|
||||
import (
|
||||
"github.com/safing/portmaster/firewall/interception/nfq"
|
||||
"github.com/safing/portmaster/network/packet"
|
||||
)
|
||||
|
||||
// start starts the interception.
|
||||
func start(ch chan packet.Packet) error {
|
||||
@@ -11,3 +14,8 @@ func start(ch chan packet.Packet) error {
|
||||
func stop() error {
|
||||
return StopNfqueueInterception()
|
||||
}
|
||||
|
||||
// ResetVerdictOfAllConnections resets all connections so they are forced to go thought the firewall again.
|
||||
func ResetVerdictOfAllConnections() error {
|
||||
return nfq.DeleteAllMarkedConnection()
|
||||
}
|
||||
|
||||
@@ -38,3 +38,8 @@ func start(ch chan packet.Packet) error {
|
||||
func stop() error {
|
||||
return windowskext.Stop()
|
||||
}
|
||||
|
||||
// ResetVerdictOfAllConnections resets all connections so they are forced to go thought the firewall again.
|
||||
func ResetVerdictOfAllConnections() error {
|
||||
return windowskext.ClearCache()
|
||||
}
|
||||
|
||||
66
firewall/interception/nfq/conntrack.go
Normal file
66
firewall/interception/nfq/conntrack.go
Normal file
@@ -0,0 +1,66 @@
|
||||
//go:build linux
|
||||
|
||||
package nfq
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
ct "github.com/florianl/go-conntrack"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/netenv"
|
||||
)
|
||||
|
||||
// DeleteAllMarkedConnection deletes all marked entries from the conntrack table.
|
||||
func DeleteAllMarkedConnection() error {
|
||||
nfct, err := ct.Open(&ct.Config{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() { _ = nfct.Close() }()
|
||||
|
||||
// Delete all ipv4 marked connections
|
||||
deleted := deleteMarkedConnections(nfct, ct.IPv4)
|
||||
|
||||
if netenv.IPv6Enabled() {
|
||||
// Delete all ipv6 marked connections
|
||||
deleted += deleteMarkedConnections(nfct, ct.IPv6)
|
||||
}
|
||||
|
||||
log.Infof("nfq: deleted %d conntrack entries to reset permanent connection verdicts", deleted)
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteMarkedConnections(nfct *ct.Nfct, f ct.Family) (deleted int) {
|
||||
// initialize variables
|
||||
permanentFlags := []uint32{MarkAcceptAlways, MarkBlockAlways, MarkDropAlways, MarkRerouteNS, MarkRerouteSPN}
|
||||
filter := ct.FilterAttr{}
|
||||
filter.MarkMask = []byte{0xFF, 0xFF, 0xFF, 0xFF}
|
||||
filter.Mark = []byte{0x00, 0x00, 0x00, 0x00} // 4 zeros starting value
|
||||
|
||||
numberOfErrors := 0
|
||||
var deleteError error = nil
|
||||
// Get all connections from the specified family (ipv4 or ipv6)
|
||||
for _, mark := range permanentFlags {
|
||||
binary.BigEndian.PutUint32(filter.Mark, mark) // Little endian is in reverse not sure why. BigEndian makes it in correct order.
|
||||
currentConnections, err := nfct.Query(ct.Conntrack, f, filter)
|
||||
if err != nil {
|
||||
log.Warningf("nfq: error on conntrack query: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, connection := range currentConnections {
|
||||
deleteError = nfct.Delete(ct.Conntrack, ct.IPv4, connection)
|
||||
if err != nil {
|
||||
numberOfErrors++
|
||||
} else {
|
||||
deleted++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if numberOfErrors > 0 {
|
||||
log.Warningf("nfq: failed to delete %d conntrack entries last error is: %s", numberOfErrors, deleteError)
|
||||
}
|
||||
return deleted
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package windowskext
|
||||
@@ -48,6 +49,7 @@ type WinKext struct {
|
||||
recvVerdictRequest *windows.Proc
|
||||
setVerdict *windows.Proc
|
||||
getPayload *windows.Proc
|
||||
clearCache *windows.Proc
|
||||
}
|
||||
|
||||
// Init initializes the DLL and the Kext (Kernel Driver).
|
||||
@@ -90,6 +92,11 @@ func Init(dllPath, driverPath string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not find proc PortmasterGetPayload in dll: %s", err)
|
||||
}
|
||||
new.clearCache, err = new.dll.FindProc("PortmasterClearCache")
|
||||
if err != nil {
|
||||
// the loaded dll is an old version
|
||||
log.Errorf("could not find proc PortmasterClearCache (v1.0.12+) in dll: %s", err)
|
||||
}
|
||||
|
||||
// initialize dll/kext
|
||||
rc, _, lastErr := new.init.Call()
|
||||
@@ -246,6 +253,27 @@ func GetPayload(packetID uint32, packetSize uint32) ([]byte, error) {
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func ClearCache() error {
|
||||
kextLock.RLock()
|
||||
defer kextLock.RUnlock()
|
||||
if !ready.IsSet() {
|
||||
log.Error("kext: failed to clear the cache: kext not ready")
|
||||
return ErrKextNotReady
|
||||
}
|
||||
|
||||
if kext.clearCache == nil {
|
||||
log.Error("kext: cannot clear cache: clearCache function missing")
|
||||
}
|
||||
|
||||
rc, _, lastErr := kext.clearCache.Call()
|
||||
|
||||
if rc != windows.NO_ERROR {
|
||||
return formatErr(lastErr, rc)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func formatErr(err error, rc uintptr) error {
|
||||
sysErr, ok := err.(syscall.Errno)
|
||||
if ok {
|
||||
|
||||
@@ -75,8 +75,7 @@ func DecideOnConnection(ctx context.Context, conn *network.Connection, pkt packe
|
||||
conn.SaveWhenFinished()
|
||||
|
||||
// Reset verdict for connection.
|
||||
log.Tracer(ctx).Infof("filter: re-evaluating verdict on %s", conn)
|
||||
conn.Verdict = network.VerdictUndecided
|
||||
log.Tracer(ctx).Infof("filter: profile updated, re-evaluating verdict of %s", conn)
|
||||
|
||||
// Reset entity if it exists.
|
||||
if conn.Entity != nil {
|
||||
@@ -138,10 +137,9 @@ func runDeciders(ctx context.Context, selectedDeciders []deciderFn, conn *networ
|
||||
|
||||
// checkPortmasterConnection allows all connection that originate from
|
||||
// portmaster itself.
|
||||
func checkPortmasterConnection(ctx context.Context, conn *network.Connection, _ *profile.LayeredProfile, pkt packet.Packet) bool {
|
||||
func checkPortmasterConnection(ctx context.Context, conn *network.Connection, _ *profile.LayeredProfile, _ packet.Packet) bool {
|
||||
// Grant own outgoing connections.
|
||||
if conn.Process().Pid == ownPID &&
|
||||
(pkt == nil || pkt.IsOutbound()) {
|
||||
if conn.Process().Pid == ownPID && !conn.Inbound {
|
||||
log.Tracer(ctx).Infof("filter: granting own connection %s", conn)
|
||||
conn.Accept("connection by Portmaster", noReasonOptionKey)
|
||||
conn.Internal = true
|
||||
@@ -429,7 +427,7 @@ func checkBypassPrevention(ctx context.Context, conn *network.Connection, p *pro
|
||||
return false
|
||||
}
|
||||
|
||||
func checkFilterLists(ctx context.Context, conn *network.Connection, p *profile.LayeredProfile, pkt packet.Packet) bool {
|
||||
func checkFilterLists(ctx context.Context, conn *network.Connection, p *profile.LayeredProfile, _ packet.Packet) bool {
|
||||
// apply privacy filter lists
|
||||
result, reason := p.MatchFilterLists(ctx, conn.Entity)
|
||||
switch result {
|
||||
|
||||
@@ -2,6 +2,7 @@ package firewall
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/netenv"
|
||||
@@ -16,7 +17,7 @@ import (
|
||||
"github.com/safing/spn/sluice"
|
||||
)
|
||||
|
||||
func checkTunneling(ctx context.Context, conn *network.Connection, pkt packet.Packet) {
|
||||
func checkTunneling(ctx context.Context, conn *network.Connection) {
|
||||
// Check if the connection should be tunneled at all.
|
||||
switch {
|
||||
case !tunnelEnabled():
|
||||
@@ -28,9 +29,12 @@ func checkTunneling(ctx context.Context, conn *network.Connection, pkt packet.Pa
|
||||
case conn.Inbound:
|
||||
// Can't tunnel incoming connections.
|
||||
return
|
||||
case conn.Verdict != network.VerdictAccept:
|
||||
case conn.Verdict.Firewall != network.VerdictAccept:
|
||||
// Connection will be blocked.
|
||||
return
|
||||
case conn.IPProtocol != packet.TCP && conn.IPProtocol != packet.UDP:
|
||||
// Unsupported protocol.
|
||||
return
|
||||
case conn.Process().Pid == ownPID:
|
||||
// Bypass tunneling for certain own connections.
|
||||
switch {
|
||||
@@ -77,7 +81,7 @@ func checkTunneling(ctx context.Context, conn *network.Connection, pkt packet.Pa
|
||||
}
|
||||
}
|
||||
|
||||
// Check if tunneling is enabeld for this app at all.
|
||||
// Check if tunneling is enabled for this app at all.
|
||||
if !layeredProfile.UseSPN() {
|
||||
return
|
||||
}
|
||||
@@ -101,11 +105,22 @@ func checkTunneling(ctx context.Context, conn *network.Connection, pkt packet.Pa
|
||||
// Check if ready.
|
||||
if !captain.ClientReady() {
|
||||
// Block connection as SPN is not ready yet.
|
||||
log.Tracer(pkt.Ctx()).Trace("SPN not ready for tunneling")
|
||||
log.Tracer(ctx).Trace("SPN not ready for tunneling")
|
||||
conn.Failed("SPN not ready for tunneling", "")
|
||||
return
|
||||
}
|
||||
|
||||
conn.SetVerdictDirectly(network.VerdictRerouteToTunnel)
|
||||
conn.Tunneled = true
|
||||
}
|
||||
|
||||
func requestTunneling(ctx context.Context, conn *network.Connection) error {
|
||||
// Get profile.
|
||||
layeredProfile := conn.Process().Profile()
|
||||
if layeredProfile == nil {
|
||||
return errors.New("no profile set")
|
||||
}
|
||||
|
||||
// Set options.
|
||||
conn.TunnelOpts = &navigator.Options{
|
||||
HubPolicies: layeredProfile.StackedExitHubPolicies(),
|
||||
@@ -150,13 +165,11 @@ func checkTunneling(ctx context.Context, conn *network.Connection, pkt packet.Pa
|
||||
}
|
||||
|
||||
// Queue request in sluice.
|
||||
err = sluice.AwaitRequest(conn, crew.HandleSluiceRequest)
|
||||
err := sluice.AwaitRequest(conn, crew.HandleSluiceRequest)
|
||||
if err != nil {
|
||||
log.Tracer(pkt.Ctx()).Warningf("failed to request tunneling: %s", err)
|
||||
conn.Failed("failed to request tunneling", "")
|
||||
} else {
|
||||
log.Tracer(pkt.Ctx()).Trace("filter: tunneling requested")
|
||||
conn.Verdict = network.VerdictRerouteToTunnel
|
||||
conn.Tunneled = true
|
||||
return err
|
||||
}
|
||||
|
||||
log.Tracer(ctx).Trace("filter: tunneling requested")
|
||||
return nil
|
||||
}
|
||||
|
||||
15
go.mod
15
go.mod
@@ -5,6 +5,7 @@ go 1.19
|
||||
require (
|
||||
github.com/agext/levenshtein v1.2.3
|
||||
github.com/coreos/go-iptables v0.6.0
|
||||
github.com/florianl/go-conntrack v0.3.0
|
||||
github.com/florianl/go-nfqueue v1.3.1
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/godbus/dbus/v5 v5.1.0
|
||||
@@ -16,7 +17,7 @@ require (
|
||||
github.com/oschwald/maxminddb-golang v1.10.0
|
||||
github.com/safing/jess v0.3.0
|
||||
github.com/safing/portbase v0.16.0
|
||||
github.com/safing/spn v0.5.1
|
||||
github.com/safing/spn v0.5.2
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/spf13/cobra v1.5.0
|
||||
github.com/spkg/zipfs v0.7.1
|
||||
@@ -24,9 +25,9 @@ require (
|
||||
github.com/tannerryan/ring v1.1.2
|
||||
github.com/tevino/abool v1.2.0
|
||||
github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc
|
||||
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
|
||||
golang.org/x/net v0.0.0-20221004154528-8021a29435af
|
||||
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0
|
||||
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875
|
||||
zombiezen.com/go/sqlite v0.10.1
|
||||
)
|
||||
|
||||
@@ -66,7 +67,7 @@ require (
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/tidwall/gjson v1.14.3 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tidwall/sjson v1.2.5 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/tklauser/numcpus v0.5.0 // indirect
|
||||
@@ -78,12 +79,12 @@ require (
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
github.com/zalando/go-keyring v0.2.1 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be // indirect
|
||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
modernc.org/libc v1.20.0 // indirect
|
||||
modernc.org/libc v1.20.3 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.4.0 // indirect
|
||||
modernc.org/sqlite v1.19.1 // indirect
|
||||
|
||||
86
go.sum
86
go.sum
@@ -31,6 +31,7 @@ github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk=
|
||||
@@ -53,8 +54,11 @@ github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/florianl/go-conntrack v0.3.0 h1:DUY84Mce+/lE9dJi2EWvGYacQtX2X96J9aVWV99l8UE=
|
||||
github.com/florianl/go-conntrack v0.3.0/go.mod h1:Q+Um4J/nWUXSbnyzQRMOP4eweSeEQ2G8sfCO5gMz6Pw=
|
||||
github.com/florianl/go-nfqueue v1.3.1 h1:khQ9fYCrjbu5CF8dZF55G2RTIEIQRI0Aj5k3msJR6Gw=
|
||||
github.com/florianl/go-nfqueue v1.3.1/go.mod h1:aHWbgkhryJxF5XxYvJ3oRZpdD4JP74Zu/hP1zuhja+M=
|
||||
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
|
||||
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
|
||||
@@ -75,7 +79,12 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
@@ -99,15 +108,25 @@ github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jackc/puddle/v2 v2.0.0-beta.1 h1:Y4Ao+kFWANtDhWUkdw1JcbH+x84/aq6WUfhVQ1wdib8=
|
||||
github.com/jackc/puddle/v2 v2.0.0-beta.1/go.mod h1:itE7ZJY8xnoo0JqJEpSMprN0f+NQkMCuEV/N9j8h0oc=
|
||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
|
||||
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201216134343-bde56ed16391/go.mod h1:cR77jAZG3Y3bsb8hF6fHJbFoyFukLFOkQ98S0pQz3xw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201220180245-69540ac93943/go.mod h1:z4c53zj6Eex712ROyh8WI0ihysb5j2ROyV42iNogmAs=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20210122163228-8d122574c736/go.mod h1:ZXpIyOK59ZnN7J0BV99cZUPmsqDRZ3eq5X+st7u/oSA=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b/go.mod h1:8w9Rh8m+aHZIG69YPGGem1i5VzoyRC8nw2kA8B+ik5U=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20210525051524-4cc836578190/go.mod h1:NmKSdU4VGSiv1bMsdqNALI4RSvvjtz65tTMCnD05qLo=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
@@ -119,9 +138,22 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo=
|
||||
github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc=
|
||||
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
|
||||
github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
|
||||
github.com/mdlayher/netlink v1.2.0/go.mod h1:kwVW1io0AZy9A1E2YYgaD4Cj+C+GPkU6klXCMzIJ9p8=
|
||||
github.com/mdlayher/netlink v1.2.1/go.mod h1:bacnNlfhqHqqLo4WsYeXSqfyXkInQ9JneWI68v1KwSU=
|
||||
github.com/mdlayher/netlink v1.2.2-0.20210123213345-5cc92139ae3e/go.mod h1:bacnNlfhqHqqLo4WsYeXSqfyXkInQ9JneWI68v1KwSU=
|
||||
github.com/mdlayher/netlink v1.3.0/go.mod h1:xK/BssKuwcRXHrtN04UBkwQ6dY9VviGGuriDdoPSWys=
|
||||
github.com/mdlayher/netlink v1.4.0/go.mod h1:dRJi5IABcZpBD2A3D0Mv/AiX8I9uDEu5oGkAVrekmf8=
|
||||
github.com/mdlayher/netlink v1.4.1/go.mod h1:e4/KuJ+s8UhfUpO9z00/fDZZmhSrs+oxyqAS9cNgn6Q=
|
||||
github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA=
|
||||
github.com/mdlayher/netlink v1.6.2 h1:D2zGSkvYsJ6NreeED3JiVTu1lj2sIYATqSaZlhPzUgQ=
|
||||
github.com/mdlayher/netlink v1.6.2/go.mod h1:O1HXX2sIWSMJ3Qn1BYZk1yZM+7iMki/uYGGiwGyq/iU=
|
||||
github.com/mdlayher/socket v0.0.0-20210307095302-262dc9984e00/go.mod h1:GAFlyu4/XV68LkQKYzKhIo/WW7j3Zi0YRAz/BOoanUc=
|
||||
github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs=
|
||||
github.com/mdlayher/socket v0.2.3 h1:XZA2X2TjdOwNoNPVPclRCURoX/hokBY8nkTmRZFEheM=
|
||||
github.com/mdlayher/socket v0.2.3/go.mod h1:bz12/FozYNH/VbvC3q7TRIK/Y6dH1kCKsXaUeXi/FmY=
|
||||
@@ -159,6 +191,8 @@ github.com/safing/portbase v0.16.0 h1:oGu5xVuMyzkG6Fht+kKbyHvA8CEJEexuCvsYQuyh6v
|
||||
github.com/safing/portbase v0.16.0/go.mod h1:mzNCWqPbO7vIYbbK5PElGbudwd2vx4YPNawymL8Aro8=
|
||||
github.com/safing/spn v0.5.1 h1:SPTG9S7BfUBpnrg8pmTFsaSlRowSljlZ0hT4NQFHnjE=
|
||||
github.com/safing/spn v0.5.1/go.mod h1:IuQNzXhR8sSi7sq4KXIH1rK9N3Z94A3nRgItjfDB6Dg=
|
||||
github.com/safing/spn v0.5.2 h1:Gl82Fhy8+tKAarLGakkug+xzuBUcjeA39Q495pfnDWk=
|
||||
github.com/safing/spn v0.5.2/go.mod h1:r2Ig1VN0jTXC0kjSrK0mk8q3StkFTlQL+k2oJi+3TMY=
|
||||
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=
|
||||
@@ -202,8 +236,9 @@ github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
|
||||
github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs=
|
||||
@@ -240,46 +275,76 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A=
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0=
|
||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220923203811-8be639271d50/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc h1:FxpXZdoBqT8RjqTy6i1E8nXHhW21wK7ptQ/EPIGxzPQ=
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4=
|
||||
golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc=
|
||||
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 h1:cu5kTvlzcw1Q5S9f5ip1/cpiB4nXvw1XYzFPGgzLUOY=
|
||||
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210123111255-9b0068b26619/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -292,8 +357,9 @@ golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 h1:AzgQNqF+FKwyQ5LbVrVqOcuuFB67N47F9+htZYH0wFM=
|
||||
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -339,8 +405,8 @@ modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwco
|
||||
modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A=
|
||||
modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU=
|
||||
modernc.org/libc v1.16.7/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU=
|
||||
modernc.org/libc v1.20.0 h1:MEbCfCKpuDC/LRb3HOCM9fZOqnPx8le3kzTJVmUGDbU=
|
||||
modernc.org/libc v1.20.0/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
|
||||
modernc.org/libc v1.20.3 h1:BodaDPuUse7taQchAClMmbE/yZp3T2ZBiwCDFyBLEXw=
|
||||
modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
|
||||
@@ -189,7 +189,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
|
||||
conn.Resolver = rrCache.Resolver
|
||||
}
|
||||
|
||||
switch conn.Verdict {
|
||||
switch conn.Verdict.Active {
|
||||
// We immediately save blocked, dropped or failed verdicts so
|
||||
// they pop up in the UI.
|
||||
case network.VerdictBlock, network.VerdictDrop, network.VerdictFailed, network.VerdictRerouteToNameserver, network.VerdictRerouteToTunnel:
|
||||
@@ -217,7 +217,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
|
||||
case network.VerdictUndeterminable:
|
||||
fallthrough
|
||||
default:
|
||||
tracer.Warningf("nameserver: unexpected verdict %s for connection %s, not saving", conn.Verdict, conn)
|
||||
tracer.Warningf("nameserver: unexpected verdict %s for connection %s, not saving", conn.VerdictVerb(), conn)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -235,11 +235,11 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
|
||||
}
|
||||
|
||||
// Check if there is a Verdict to act upon.
|
||||
switch conn.Verdict { //nolint:exhaustive // Only checking for specific values.
|
||||
switch conn.Verdict.Active { //nolint:exhaustive // Only checking for specific values.
|
||||
case network.VerdictBlock, network.VerdictDrop, network.VerdictFailed:
|
||||
tracer.Infof(
|
||||
"nameserver: returning %s response for %s to %s",
|
||||
conn.Verdict.Verb(),
|
||||
conn.VerdictVerb(),
|
||||
q.ID(),
|
||||
conn.Process(),
|
||||
)
|
||||
@@ -315,11 +315,11 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
|
||||
}
|
||||
|
||||
// Check if there is a Verdict to act upon.
|
||||
switch conn.Verdict { //nolint:exhaustive // Only checking for specific values.
|
||||
switch conn.Verdict.Active { //nolint:exhaustive // Only checking for specific values.
|
||||
case network.VerdictBlock, network.VerdictDrop, network.VerdictFailed:
|
||||
tracer.Infof(
|
||||
"nameserver: returning %s response for %s to %s",
|
||||
conn.Verdict.Verb(),
|
||||
conn.VerdictVerb(),
|
||||
q.ID(),
|
||||
conn.Process(),
|
||||
)
|
||||
@@ -338,7 +338,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
|
||||
}
|
||||
tracer.Infof(
|
||||
"nameserver: returning %s response (%s%s) for %s to %s",
|
||||
conn.Verdict.Verb(),
|
||||
conn.VerdictVerb(),
|
||||
dns.RcodeToString[rrCache.RCode],
|
||||
noAnswerIndicator,
|
||||
q.ID(),
|
||||
|
||||
@@ -155,7 +155,7 @@ func convertConnection(conn *network.Connection) (*Conn, error) {
|
||||
IPProtocol: conn.IPProtocol,
|
||||
LocalIP: conn.LocalIP.String(),
|
||||
LocalPort: conn.LocalPort,
|
||||
Verdict: conn.Verdict,
|
||||
Verdict: conn.Verdict.Firewall, // TODO: Expose both Worst and Firewall verdicts.
|
||||
Started: time.Unix(conn.Started, 0),
|
||||
Tunneled: conn.Tunneled,
|
||||
Encrypted: conn.Encrypted,
|
||||
@@ -177,7 +177,7 @@ func convertConnection(conn *network.Connection) (*Conn, error) {
|
||||
c.Type = ""
|
||||
}
|
||||
|
||||
switch conn.Verdict {
|
||||
switch conn.Verdict.Firewall {
|
||||
case network.VerdictAccept, network.VerdictRerouteToNameserver, network.VerdictRerouteToTunnel:
|
||||
accepted := true
|
||||
c.Allowed = &accepted
|
||||
|
||||
@@ -120,9 +120,10 @@ func AddNetworkDebugData(di *debug.Info, profile, where string) {
|
||||
|
||||
// Collect matching connections.
|
||||
var ( //nolint:prealloc // We don't know the size.
|
||||
debugConns []*Connection
|
||||
accepted int
|
||||
total int
|
||||
debugConns []*Connection
|
||||
accepted int
|
||||
total int
|
||||
transitioning int
|
||||
)
|
||||
for maybeConn := range it.Next {
|
||||
// Switch to correct type.
|
||||
@@ -152,12 +153,15 @@ func AddNetworkDebugData(di *debug.Info, profile, where string) {
|
||||
|
||||
// Count.
|
||||
total++
|
||||
switch conn.Verdict { //nolint:exhaustive
|
||||
switch conn.Verdict.Firewall { //nolint:exhaustive
|
||||
case VerdictAccept,
|
||||
VerdictRerouteToNameserver,
|
||||
VerdictRerouteToTunnel:
|
||||
accepted++
|
||||
}
|
||||
if conn.Verdict.Active != conn.Verdict.Firewall {
|
||||
transitioning++
|
||||
}
|
||||
|
||||
// Add to list.
|
||||
debugConns = append(debugConns, conn)
|
||||
@@ -166,9 +170,10 @@ func AddNetworkDebugData(di *debug.Info, profile, where string) {
|
||||
// Add it all.
|
||||
di.AddSection(
|
||||
fmt.Sprintf(
|
||||
"Network: %d/%d Connections",
|
||||
"Network: %d/%d [~%d] Connections",
|
||||
accepted,
|
||||
total,
|
||||
transitioning,
|
||||
),
|
||||
debug.UseCodeSection|debug.AddContentLineBreaks,
|
||||
buildNetworkDebugInfoData(debugConns),
|
||||
@@ -232,7 +237,7 @@ func (conn *Connection) debugInfoLine() string {
|
||||
|
||||
return fmt.Sprintf(
|
||||
"% 14s %s%- 25s %s-%s P#%d [%s] %s - by %s @ %s",
|
||||
conn.Verdict.Verb(),
|
||||
conn.VerdictVerb(),
|
||||
connectionData,
|
||||
conn.fmtDomainComponent(),
|
||||
time.Unix(conn.Started, 0).Format("15:04:05"),
|
||||
|
||||
@@ -40,7 +40,15 @@ var connectionTestData = []*Connection{
|
||||
Country: "",
|
||||
ASN: 0,
|
||||
},
|
||||
Verdict: 4,
|
||||
Verdict: struct {
|
||||
Worst Verdict
|
||||
Active Verdict
|
||||
Firewall Verdict
|
||||
}{
|
||||
Worst: 2,
|
||||
Active: 2,
|
||||
Firewall: 2,
|
||||
},
|
||||
Reason: Reason{
|
||||
Msg: "incoming connection blocked by default",
|
||||
OptionKey: "filter/serviceEndpoints",
|
||||
@@ -80,7 +88,15 @@ var connectionTestData = []*Connection{
|
||||
Country: "DE",
|
||||
ASN: 16509,
|
||||
},
|
||||
Verdict: 2,
|
||||
Verdict: struct {
|
||||
Worst Verdict
|
||||
Active Verdict
|
||||
Firewall Verdict
|
||||
}{
|
||||
Worst: 2,
|
||||
Active: 2,
|
||||
Firewall: 2,
|
||||
},
|
||||
Reason: Reason{
|
||||
Msg: "default permit",
|
||||
OptionKey: "filter/defaultAction",
|
||||
@@ -123,7 +139,15 @@ var connectionTestData = []*Connection{
|
||||
Country: "US",
|
||||
ASN: 15169,
|
||||
},
|
||||
Verdict: 2,
|
||||
Verdict: struct {
|
||||
Worst Verdict
|
||||
Active Verdict
|
||||
Firewall Verdict
|
||||
}{
|
||||
Worst: 2,
|
||||
Active: 2,
|
||||
Firewall: 2,
|
||||
},
|
||||
Reason: Reason{
|
||||
Msg: "default permit",
|
||||
OptionKey: "filter/defaultAction",
|
||||
|
||||
@@ -107,16 +107,26 @@ type Connection struct { //nolint:maligned // TODO: fix alignment
|
||||
// Resolver holds information about the resolver used to resolve
|
||||
// Entity.Domain.
|
||||
Resolver *resolver.ResolverInfo
|
||||
// Verdict is the final decision that has been made for a connection.
|
||||
// Verdict holds the decisions that are made for a connection
|
||||
// The verdict may change so any access to it must be guarded by the
|
||||
// connection lock.
|
||||
Verdict Verdict
|
||||
Verdict struct {
|
||||
// Worst verdict holds the worst verdict that was assigned to this
|
||||
// connection from a privacy/security perspective.
|
||||
Worst Verdict
|
||||
// Active verdict holds the verdict that Portmaster will respond with.
|
||||
// This is different from the Firewall verdict in order to guarantee proper
|
||||
// transition between verdicts that need the connection to be re-established.
|
||||
Active Verdict
|
||||
// Firewall holsd the last (most recent) decision by the firewall.
|
||||
Firewall Verdict
|
||||
}
|
||||
// Reason holds information justifying the verdict, as well as additional
|
||||
// information about the reason.
|
||||
// Access to Reason must be guarded by the connection lock.
|
||||
Reason Reason
|
||||
// Started holds the number of seconds in UNIX epoch time at which
|
||||
// the connection has been initated and first seen by the portmaster.
|
||||
// the connection has been initiated and first seen by the portmaster.
|
||||
// Started is only ever set when creating a new connection object
|
||||
// and is considered immutable afterwards.
|
||||
Started int64
|
||||
@@ -142,7 +152,7 @@ type Connection struct { //nolint:maligned // TODO: fix alignment
|
||||
// TunnelOpts holds options for tunneling the connection.
|
||||
TunnelOpts *navigator.Options
|
||||
// ProcessContext holds additional information about the process
|
||||
// that iniated the connection. It is set once when the connection
|
||||
// that initiated the connection. It is set once when the connection
|
||||
// object is created and is considered immutable afterwards.
|
||||
ProcessContext ProcessContext
|
||||
// DNSContext holds additional information about the DNS request that was
|
||||
@@ -152,6 +162,7 @@ type Connection struct { //nolint:maligned // TODO: fix alignment
|
||||
// connection is using.
|
||||
TunnelContext interface {
|
||||
GetExitNodeID() string
|
||||
StopTunnel() error
|
||||
}
|
||||
|
||||
// Internal is set to true if the connection is attributed as an
|
||||
@@ -159,7 +170,7 @@ type Connection struct { //nolint:maligned // TODO: fix alignment
|
||||
// points and access to it must be guarded by the connection lock.
|
||||
Internal bool
|
||||
// process holds a reference to the actor process. That is, the
|
||||
// process instance that initated the connection.
|
||||
// process instance that initiated the connection.
|
||||
process *process.Process
|
||||
// pkgQueue is used to serialize packet handling for a single
|
||||
// connection and is served by the connections packetHandler.
|
||||
@@ -167,7 +178,7 @@ type Connection struct { //nolint:maligned // TODO: fix alignment
|
||||
// firewallHandler is the firewall handler that is called for
|
||||
// each packet sent to pktQueue.
|
||||
firewallHandler FirewallHandler
|
||||
// saveWhenFinished can be set to drue during the life-time of
|
||||
// saveWhenFinished can be set to true during the life-time of
|
||||
// a connection and signals the firewallHandler that a Save()
|
||||
// should be issued after processing the connection.
|
||||
saveWhenFinished bool
|
||||
@@ -439,6 +450,11 @@ func GetConnection(id string) (*Connection, bool) {
|
||||
return conns.get(id)
|
||||
}
|
||||
|
||||
// GetAllConnections Gets all connection.
|
||||
func GetAllConnections() []*Connection {
|
||||
return conns.list()
|
||||
}
|
||||
|
||||
// SetLocalIP sets the local IP address together with its network scope. The
|
||||
// connection is not locked for this.
|
||||
func (conn *Connection) SetLocalIP(ip net.IP) {
|
||||
@@ -508,23 +524,39 @@ func (conn *Connection) Failed(reason, reasonOptionKey string) {
|
||||
conn.FailedWithContext(reason, reasonOptionKey, nil)
|
||||
}
|
||||
|
||||
// SetVerdict sets a new verdict for the connection, making sure it does not interfere with previous verdicts.
|
||||
// SetVerdict sets a new verdict for the connection.
|
||||
func (conn *Connection) SetVerdict(newVerdict Verdict, reason, reasonOptionKey string, reasonCtx interface{}) (ok bool) {
|
||||
if newVerdict >= conn.Verdict {
|
||||
conn.Verdict = newVerdict
|
||||
conn.Reason.Msg = reason
|
||||
conn.Reason.Context = reasonCtx
|
||||
conn.SetVerdictDirectly(newVerdict)
|
||||
|
||||
conn.Reason.OptionKey = ""
|
||||
conn.Reason.Profile = ""
|
||||
if reasonOptionKey != "" && conn.Process() != nil {
|
||||
conn.Reason.OptionKey = reasonOptionKey
|
||||
conn.Reason.Profile = conn.Process().Profile().GetProfileSource(conn.Reason.OptionKey)
|
||||
}
|
||||
conn.Reason.Msg = reason
|
||||
conn.Reason.Context = reasonCtx
|
||||
|
||||
return true
|
||||
conn.Reason.OptionKey = ""
|
||||
conn.Reason.Profile = ""
|
||||
if reasonOptionKey != "" && conn.Process() != nil {
|
||||
conn.Reason.OptionKey = reasonOptionKey
|
||||
conn.Reason.Profile = conn.Process().Profile().GetProfileSource(conn.Reason.OptionKey)
|
||||
}
|
||||
return false
|
||||
|
||||
return true // TODO: remove
|
||||
}
|
||||
|
||||
// SetVerdictDirectly sets the firewall verdict.
|
||||
func (conn *Connection) SetVerdictDirectly(newVerdict Verdict) {
|
||||
conn.Verdict.Firewall = newVerdict
|
||||
}
|
||||
|
||||
// VerdictVerb returns the verdict as a verb, while taking any special states
|
||||
// into account.
|
||||
func (conn *Connection) VerdictVerb() string {
|
||||
if conn.Verdict.Firewall == conn.Verdict.Active {
|
||||
return conn.Verdict.Firewall.Verb()
|
||||
}
|
||||
return fmt.Sprintf(
|
||||
"%s (transitioning to %s)",
|
||||
conn.Verdict.Active.Verb(),
|
||||
conn.Verdict.Firewall.Verb(),
|
||||
)
|
||||
}
|
||||
|
||||
// Process returns the connection's process.
|
||||
@@ -651,7 +683,7 @@ func packetHandlerHandleConn(conn *Connection, pkt packet.Packet) {
|
||||
}
|
||||
|
||||
// Log verdict.
|
||||
log.Tracer(pkt.Ctx()).Infof("filter: connection %s %s: %s", conn, conn.Verdict.Verb(), conn.Reason.Msg)
|
||||
log.Tracer(pkt.Ctx()).Infof("filter: connection %s %s: %s", conn, conn.VerdictVerb(), conn.Reason.Msg)
|
||||
// Submit trace logs.
|
||||
log.Tracer(pkt.Ctx()).Submit()
|
||||
|
||||
|
||||
@@ -48,6 +48,17 @@ func (cs *connectionStore) clone() map[string]*Connection {
|
||||
return m
|
||||
}
|
||||
|
||||
func (cs *connectionStore) list() []*Connection {
|
||||
cs.rw.RLock()
|
||||
defer cs.rw.RUnlock()
|
||||
|
||||
l := make([]*Connection, 0, len(cs.items))
|
||||
for _, conn := range cs.items {
|
||||
l = append(l, conn)
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (cs *connectionStore) len() int { //nolint:unused // TODO: Clean up if still unused.
|
||||
cs.rw.RLock()
|
||||
defer cs.rw.RUnlock()
|
||||
|
||||
@@ -115,7 +115,7 @@ func writeOpenDNSRequestsToDB() {
|
||||
// ReplyWithDNS creates a new reply to the given request with the data from the RRCache, and additional informational records.
|
||||
func (conn *Connection) ReplyWithDNS(ctx context.Context, request *dns.Msg) *dns.Msg {
|
||||
// Select request responder.
|
||||
switch conn.Verdict {
|
||||
switch conn.Verdict.Active {
|
||||
case VerdictBlock:
|
||||
return nsutil.BlockIP().ReplyWithDNS(ctx, request)
|
||||
case VerdictDrop:
|
||||
@@ -136,7 +136,7 @@ func (conn *Connection) ReplyWithDNS(ctx context.Context, request *dns.Msg) *dns
|
||||
func (conn *Connection) GetExtraRRs(ctx context.Context, request *dns.Msg) []dns.RR {
|
||||
// Select level to add the verdict record with.
|
||||
var level log.Severity
|
||||
switch conn.Verdict {
|
||||
switch conn.Verdict.Active {
|
||||
case VerdictFailed:
|
||||
level = log.ErrorLevel
|
||||
case VerdictUndecided, VerdictUndeterminable,
|
||||
@@ -148,7 +148,7 @@ func (conn *Connection) GetExtraRRs(ctx context.Context, request *dns.Msg) []dns
|
||||
}
|
||||
|
||||
// Create resource record with verdict and reason.
|
||||
rr, err := nsutil.MakeMessageRecord(level, fmt.Sprintf("%s: %s", conn.Verdict.Verb(), conn.Reason.Msg))
|
||||
rr, err := nsutil.MakeMessageRecord(level, fmt.Sprintf("%s: %s", conn.VerdictVerb(), conn.Reason.Msg))
|
||||
if err != nil {
|
||||
log.Tracer(ctx).Warningf("filter: failed to add informational record to reply: %s", err)
|
||||
return nil
|
||||
|
||||
@@ -119,7 +119,7 @@ func (conn *Connection) addToMetrics() {
|
||||
}
|
||||
|
||||
// Check the verdict.
|
||||
switch conn.Verdict { //nolint:exhaustive // Not critical.
|
||||
switch conn.Verdict.Firewall { //nolint:exhaustive // Not critical.
|
||||
case VerdictBlock, VerdictDrop:
|
||||
blockedOutConnCounter.Inc()
|
||||
conn.addedToMetrics = true
|
||||
|
||||
@@ -224,7 +224,7 @@ func (pkt *Base) FmtRemoteAddress() string {
|
||||
return fmt.Sprintf("%s:%s:%s", pkt.info.Protocol.String(), pkt.FmtRemoteIP(), pkt.FmtRemotePort())
|
||||
}
|
||||
|
||||
// Packet is an interface to a network packet to provide object behaviour the same across all systems.
|
||||
// Packet is an interface to a network packet to provide object behavior the same across all systems.
|
||||
type Packet interface {
|
||||
// Verdicts.
|
||||
Accept() error
|
||||
|
||||
@@ -46,3 +46,30 @@ func GetProtocolNumber(protocol string) (number uint8, ok bool) {
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// IsPacketProtocol returns whether the given protocol number is a known packet based protocol.
|
||||
// Note: Not fully complete. Calling IsPacketProtocol() does not equal calling !IsStreamProtocol().
|
||||
func IsPacketProtocol(protocol uint8) bool {
|
||||
switch protocol {
|
||||
case 1, // ICMP
|
||||
17, // UDP
|
||||
27, // RDP
|
||||
58, // ICMP6
|
||||
33, // DCCP
|
||||
136: // UDP-LITE
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// IsStreamProtocol returns whether the given protocol number is a known stream based protocol.
|
||||
// Note: Not fully complete. Calling IsPacketProtocol() does not equal calling !IsStreamProtocol().
|
||||
func IsStreamProtocol(protocol uint8) bool {
|
||||
switch protocol {
|
||||
case 6: // TCP
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,9 +54,9 @@ func (v Verdict) Verb() string {
|
||||
case VerdictDrop:
|
||||
return "dropped"
|
||||
case VerdictRerouteToNameserver:
|
||||
return "to nameserver"
|
||||
return "redirected to nameserver"
|
||||
case VerdictRerouteToTunnel:
|
||||
return "to tunnel"
|
||||
return "tunneled"
|
||||
case VerdictFailed:
|
||||
return "failed"
|
||||
default:
|
||||
|
||||
@@ -91,6 +91,7 @@ func startProfileUpdateChecker() error {
|
||||
if err == nil {
|
||||
newProfile.layeredProfile.Update()
|
||||
}
|
||||
module.TriggerEvent(profileConfigChange, nil)
|
||||
}
|
||||
|
||||
// Always increase the revision counter of the layer profile.
|
||||
@@ -104,6 +105,7 @@ func startProfileUpdateChecker() error {
|
||||
receivedProfile, err := EnsureProfile(r)
|
||||
if err != nil || !receivedProfile.savedInternally {
|
||||
activeProfile.outdated.Set()
|
||||
module.TriggerEvent(profileConfigChange, nil)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
|
||||
@@ -16,8 +16,13 @@ var (
|
||||
updatesPath string
|
||||
)
|
||||
|
||||
const (
|
||||
profileConfigChange = "profile config change"
|
||||
)
|
||||
|
||||
func init() {
|
||||
module = modules.Register("profiles", prep, start, nil, "base", "updates")
|
||||
module.RegisterEvent(profileConfigChange, true)
|
||||
}
|
||||
|
||||
func prep() error {
|
||||
|
||||
@@ -322,15 +322,15 @@ func (profile *Profile) GetServiceEndpoints() endpoints.Endpoints {
|
||||
|
||||
// AddEndpoint adds an endpoint to the endpoint list, saves the profile and reloads the configuration.
|
||||
func (profile *Profile) AddEndpoint(newEntry string) {
|
||||
profile.addEndpointyEntry(CfgOptionEndpointsKey, newEntry)
|
||||
profile.addEndpointEntry(CfgOptionEndpointsKey, newEntry)
|
||||
}
|
||||
|
||||
// AddServiceEndpoint adds a service endpoint to the endpoint list, saves the profile and reloads the configuration.
|
||||
func (profile *Profile) AddServiceEndpoint(newEntry string) {
|
||||
profile.addEndpointyEntry(CfgOptionServiceEndpointsKey, newEntry)
|
||||
profile.addEndpointEntry(CfgOptionServiceEndpointsKey, newEntry)
|
||||
}
|
||||
|
||||
func (profile *Profile) addEndpointyEntry(cfgKey, newEntry string) {
|
||||
func (profile *Profile) addEndpointEntry(cfgKey, newEntry string) {
|
||||
changed := false
|
||||
|
||||
// When finished, save the profile.
|
||||
@@ -365,7 +365,7 @@ func (profile *Profile) addEndpointyEntry(cfgKey, newEntry string) {
|
||||
|
||||
if entry == newEntry {
|
||||
// An identical entry is already in the list, abort.
|
||||
log.Debugf("profile: ingoring new endpoint rule for %s, as identical is already present: %s", profile, newEntry)
|
||||
log.Debugf("profile: ignoring new endpoint rule for %s, as identical is already present: %s", profile, newEntry)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user