Merge pull request #44 from safing/feature/pre-alpha-finalizing

Pre alpha finalizing
This commit is contained in:
Patrick Pacher
2020-04-30 16:42:09 +02:00
committed by GitHub
33 changed files with 427 additions and 166 deletions

View File

@@ -1,16 +1,23 @@
package firewall
import (
"github.com/safing/portbase/api"
"github.com/safing/portbase/config"
"github.com/safing/portmaster/core"
)
// Configuration Keys
var (
CfgOptionEnableFilterKey = "filter/enable"
CfgOptionPromptTimeoutKey = "filter/promptTimeout"
CfgOptionPromptTimeoutOrder = 2
promptTimeout config.IntOption
CfgOptionAskWithSystemNotificationsKey = "filter/askWithSystemNotifications"
CfgOptionAskWithSystemNotificationsOrder = 2
askWithSystemNotifications config.BoolOption
useSystemNotifications config.BoolOption
CfgOptionAskTimeoutKey = "filter/askTimeout"
CfgOptionAskTimeoutOrder = 3
askTimeout config.IntOption
CfgOptionPermanentVerdictsKey = "filter/permanentVerdicts"
CfgOptionPermanentVerdictsOrder = 128
@@ -37,22 +44,38 @@ func registerConfig() error {
permanentVerdicts = config.Concurrent.GetAsBool(CfgOptionPermanentVerdictsKey, true)
err = config.Register(&config.Option{
Name: "Timeout for prompt notifications",
Key: CfgOptionPromptTimeoutKey,
Description: "Amount of time how long Portmaster will wait for a response when prompting about a connection via a notification. In seconds.",
Order: CfgOptionPromptTimeoutOrder,
Name: "Ask with System Notifications",
Key: CfgOptionAskWithSystemNotificationsKey,
Description: `Ask about connections using your operating system's notification system. For this to be enabled, the setting "Use System Notifications" must enabled too. This only affects questions from the Privacy Filter, and does not affect alerts from the Portmaster.`,
Order: CfgOptionAskWithSystemNotificationsOrder,
OptType: config.OptTypeBool,
ExpertiseLevel: config.ExpertiseLevelUser,
ReleaseLevel: config.ReleaseLevelStable,
DefaultValue: true,
})
if err != nil {
return err
}
askWithSystemNotifications = config.Concurrent.GetAsBool(CfgOptionAskWithSystemNotificationsKey, true)
useSystemNotifications = config.Concurrent.GetAsBool(core.CfgUseSystemNotificationsKey, true)
err = config.Register(&config.Option{
Name: "Timeout for Ask Notifications",
Key: CfgOptionAskTimeoutKey,
Description: "Amount of time (in seconds) how long the Portmaster will wait for a response when prompting about a connection via a notification. Please note that system notifications might not respect this or have it's own limits.",
Order: CfgOptionAskTimeoutOrder,
OptType: config.OptTypeInt,
ExpertiseLevel: config.ExpertiseLevelUser,
ReleaseLevel: config.ReleaseLevelBeta,
ReleaseLevel: config.ReleaseLevelStable,
DefaultValue: 60,
})
if err != nil {
return err
}
promptTimeout = config.Concurrent.GetAsInt(CfgOptionPromptTimeoutKey, 60)
askTimeout = config.Concurrent.GetAsInt(CfgOptionAskTimeoutKey, 60)
devMode = config.Concurrent.GetAsBool("core/devMode", false)
apiListenAddress = config.GetAsString("api/listenAddress", "")
devMode = config.Concurrent.GetAsBool(core.CfgDevModeKey, false)
apiListenAddress = config.GetAsString(api.CfgDefaultListenAddressKey, "")
return nil
}

47
firewall/filter.go Normal file
View File

@@ -0,0 +1,47 @@
package firewall
import (
"github.com/safing/portbase/config"
"github.com/safing/portbase/modules/subsystems"
"github.com/safing/portbase/modules"
// module dependencies
_ "github.com/safing/portmaster/core"
_ "github.com/safing/portmaster/profile"
)
var (
filterModule *modules.Module
filterEnabled config.BoolOption
)
func init() {
filterModule = modules.Register("filter", filterPrep, nil, nil, "core", "intel")
subsystems.Register(
"filter",
"Privacy Filter",
"DNS and Network Filter",
filterModule,
"config:filter/",
&config.Option{
Name: "Enable Privacy Filter",
Key: CfgOptionEnableFilterKey,
Description: "Enable the Privacy Filter Subsystem to filter DNS queries and network requests.",
OptType: config.OptTypeBool,
ExpertiseLevel: config.ExpertiseLevelUser,
ReleaseLevel: config.ReleaseLevelBeta,
DefaultValue: true,
},
)
}
func filterPrep() (err error) {
err = registerConfig()
if err != nil {
return err
}
filterEnabled = config.GetAsBool(CfgOptionEnableFilterKey, true)
return nil
}

View File

@@ -7,9 +7,6 @@ import (
"sync/atomic"
"time"
"github.com/safing/portbase/config"
"github.com/safing/portbase/modules/subsystems"
"github.com/safing/portbase/log"
"github.com/safing/portbase/modules"
"github.com/safing/portmaster/firewall/inspection"
@@ -23,7 +20,7 @@ import (
)
var (
module *modules.Module
interceptionModule *modules.Module
// localNet net.IPNet
// localhost net.IP
@@ -45,33 +42,12 @@ var (
)
func init() {
module = modules.Register("filter", prep, start, stop, "core", "network", "nameserver", "intel")
subsystems.Register(
"filter",
"Privacy Filter",
"DNS and Network Filter",
module,
"config:filter/",
&config.Option{
Name: "Enable Privacy Filter",
Key: CfgOptionEnableFilterKey,
Description: "Enable the Privacy Filter Subsystem to filter DNS queries and network requests.",
OptType: config.OptTypeBool,
ExpertiseLevel: config.ExpertiseLevelUser,
ReleaseLevel: config.ReleaseLevelBeta,
DefaultValue: true,
},
)
interceptionModule = modules.Register("interception", interceptionPrep, interceptionStart, interceptionStop, "base")
network.SetDefaultFirewallHandler(defaultHandler)
}
func prep() (err error) {
err = registerConfig()
if err != nil {
return err
}
func interceptionPrep() (err error) {
err = prepAPIAuth()
if err != nil {
return err
@@ -101,20 +77,20 @@ func prep() (err error) {
return nil
}
func start() error {
func interceptionStart() error {
startAPIAuth()
module.StartWorker("stat logger", func(ctx context.Context) error {
interceptionModule.StartWorker("stat logger", func(ctx context.Context) error {
statLogger()
return nil
})
module.StartWorker("packet handler", func(ctx context.Context) error {
interceptionModule.StartWorker("packet handler", func(ctx context.Context) error {
run()
return nil
})
module.StartWorker("ports state cleaner", func(ctx context.Context) error {
interceptionModule.StartWorker("ports state cleaner", func(ctx context.Context) error {
portsInUseCleaner()
return nil
})
@@ -122,7 +98,7 @@ func start() error {
return interception.Start()
}
func stop() error {
func interceptionStop() error {
return interception.Stop()
}
@@ -248,6 +224,15 @@ func initialHandler(conn *network.Connection, pkt packet.Packet) {
return
}
// check if filtering is enabled
if !filterEnabled() {
conn.Inspecting = false
conn.SetVerdict(network.VerdictAccept, "privacy filter disabled", nil)
conn.StopFirewallHandler()
issueVerdict(conn, pkt, 0, true)
return
}
log.Tracer(pkt.Ctx()).Trace("filter: starting decision process")
DecideOnConnection(conn, pkt)
conn.Inspecting = false // TODO: enable inspecting again
@@ -350,7 +335,7 @@ func issueVerdict(conn *network.Connection, pkt packet.Packet, verdict network.V
func run() {
for {
select {
case <-module.Stopping():
case <-interceptionModule.Stopping():
return
case pkt := <-interception.Packets:
handlePacket(pkt)
@@ -361,7 +346,7 @@ func run() {
func statLogger() {
for {
select {
case <-module.Stopping():
case <-interceptionModule.Stopping():
return
case <-time.After(10 * time.Second):
log.Tracef(

View File

@@ -45,14 +45,14 @@ func init() {
"mangle C171 -m mark --mark 0 -j NFQUEUE --queue-num 17140 --queue-bypass",
"filter C17 -m mark --mark 0 -j DROP",
"filter C17 -m mark --mark 1700 -j ACCEPT",
"filter C17 -m mark --mark 1700 -j RETURN",
"filter C17 -m mark --mark 1701 -j REJECT --reject-with icmp-host-prohibited",
"filter C17 -m mark --mark 1702 -j DROP",
"filter C17 -j CONNMARK --save-mark",
"filter C17 -m mark --mark 1710 -j ACCEPT",
"filter C17 -m mark --mark 1710 -j RETURN",
"filter C17 -m mark --mark 1711 -j REJECT --reject-with icmp-host-prohibited",
"filter C17 -m mark --mark 1712 -j DROP",
"filter C17 -m mark --mark 1717 -j ACCEPT",
"filter C17 -m mark --mark 1717 -j RETURN",
}
v4once = []string{
@@ -80,14 +80,14 @@ func init() {
"mangle C171 -m mark --mark 0 -j NFQUEUE --queue-num 17160 --queue-bypass",
"filter C17 -m mark --mark 0 -j DROP",
"filter C17 -m mark --mark 1700 -j ACCEPT",
"filter C17 -m mark --mark 1700 -j RETURN",
"filter C17 -m mark --mark 1701 -j REJECT --reject-with icmp6-adm-prohibited",
"filter C17 -m mark --mark 1702 -j DROP",
"filter C17 -j CONNMARK --save-mark",
"filter C17 -m mark --mark 1710 -j ACCEPT",
"filter C17 -m mark --mark 1710 -j RETURN",
"filter C17 -m mark --mark 1711 -j REJECT --reject-with icmp6-adm-prohibited",
"filter C17 -m mark --mark 1712 -j DROP",
"filter C17 -m mark --mark 1717 -j ACCEPT",
"filter C17 -m mark --mark 1717 -j RETURN",
}
v6once = []string{

View File

@@ -163,8 +163,8 @@ func checkConnectionType(conn *network.Connection, _ packet.Packet) bool {
}
return true
}
case network.PeerLAN, network.PeerInternet, network.PeerInvalid:
// Important: PeerHost is and should be missing!
case network.PeerInternet:
// BlockP2P only applies to connections to the Internet
if p.BlockP2P() {
conn.Block("direct connections (P2P) blocked")
return true

View File

@@ -72,7 +72,7 @@ func GetPermittedPort() uint16 {
func portsInUseCleaner() {
for {
select {
case <-module.Stopping():
case <-interceptionModule.Stopping():
return
case <-time.After(cleanerTickDuration):
cleanPortsInUse()

View File

@@ -26,16 +26,16 @@ const (
)
func prompt(conn *network.Connection, pkt packet.Packet) { //nolint:gocognit // TODO
nTTL := time.Duration(promptTimeout()) * time.Second
nTTL := time.Duration(askTimeout()) * time.Second
// first check if there is an existing notification for this.
// build notification ID
var nID string
switch {
case conn.Inbound, conn.Entity.Domain == "": // connection to/from IP
nID = fmt.Sprintf("firewall-prompt-%d-%s-%s", conn.Process().Pid, conn.Scope, pkt.Info().RemoteIP())
nID = fmt.Sprintf("filter:prompt-%d-%s-%s", conn.Process().Pid, conn.Scope, pkt.Info().RemoteIP())
default: // connection to domain
nID = fmt.Sprintf("firewall-prompt-%d-%s", conn.Process().Pid, conn.Scope)
nID = fmt.Sprintf("filter:prompt-%d-%s", conn.Process().Pid, conn.Scope)
}
n := notifications.Get(nID)
saveResponse := true