From cdec623033bc6b1df5165e68d76017c3256da189 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 6 Aug 2020 21:22:14 +0200 Subject: [PATCH] Add SPN integration --- .ci-inject-internal-deps.sh | 4 +++ Gopkg.lock | 47 ++++++++++++++++++++++++++ Gopkg.toml | 2 +- cmds/portmaster-core/main.go | 10 +++++- firewall/interception.go | 19 +++++++++++ firewall/interception/nfqueue_linux.go | 8 ++--- intel/geoip/location.go | 1 + updates/main.go | 42 ++++++++++++----------- updates/upgrader.go | 11 ++++-- 9 files changed, 116 insertions(+), 28 deletions(-) diff --git a/.ci-inject-internal-deps.sh b/.ci-inject-internal-deps.sh index c4d8eb1fd..08304016f 100755 --- a/.ci-inject-internal-deps.sh +++ b/.ci-inject-internal-deps.sh @@ -15,4 +15,8 @@ echo " [[constraint]] name = \"github.com/safing/portbase\" branch = \"${PORTBASE_BRANCH}\" + +[[constraint]] + name = \"github.com/safing/spn\" + branch = \"${PORTBASE_BRANCH}\" " >> $DEP_FILE diff --git a/Gopkg.lock b/Gopkg.lock index 8d3bc9626..f517c08cc 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -49,6 +49,14 @@ revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" version = "v1.1.1" +[[projects]] + digest = "1:979299da1a605fc6fddc4d8fcc09ebfc6cfa6a10b05df825a3ec59773d59d0d5" + name = "github.com/florianl/go-nfqueue" + packages = ["."] + pruneopts = "" + revision = "327225dbfdfcc1fc52bb676256bee46e5c8a7a3d" + version = "v2.0.0" + [[projects]] digest = "1:b6581f9180e0f2d5549280d71819ab951db9d511478c87daca95669589d505c0" name = "github.com/go-ole/go-ole" @@ -88,6 +96,22 @@ revision = "f0e32980c006571efd537032e5f9cd8c1a92819e" version = "v0.1.0" +[[projects]] + digest = "1:8e3bd93036b4a925fe2250d3e4f38f21cadb8ef623561cd80c3c50c114b13201" + name = "github.com/hashicorp/errwrap" + packages = ["."] + pruneopts = "" + revision = "8a6fb523712970c966eefc6b39ed2c5e74880354" + version = "v1.0.0" + +[[projects]] + digest = "1:c6e569ffa34fcd24febd3562bff0520a104d15d1a600199cb3141debf2e58c89" + name = "github.com/hashicorp/go-multierror" + packages = ["."] + pruneopts = "" + revision = "2004d9dba6b07a5b8d133209244f376680f9d472" + version = "v1.1.0" + [[projects]] digest = "1:2f0c811248aeb64978037b357178b1593372439146bda860cb16f2c80785ea93" name = "github.com/hashicorp/go-version" @@ -112,6 +136,17 @@ pruneopts = "" revision = "2bc1f35cddc0cc527b4bc3dce8578fc2a6c11384" +[[projects]] + digest = "1:4f0792bf942a61626dfdc06d228aa79783e51f214faacba73992a73f9485c0a8" + name = "github.com/mdlayher/netlink" + packages = [ + ".", + "nlenc", + ] + pruneopts = "" + revision = "ad88bf8eff5c1fd8d6a29299addeeb23d05f1ec1" + version = "v1.1.0" + [[projects]] branch = "master" digest = "1:742865d3c8c267f108f852411bd8385c53c209e96813a3b0e859855cce4a0ed7" @@ -128,6 +163,14 @@ revision = "6a033e62c03b7dab4c37f7c9eb2ebb3b10e8f13a" version = "v1.6.0" +[[projects]] + digest = "1:c45802472e0c06928cd997661f2af610accd85217023b1d5f6331bebce0671d3" + name = "github.com/pkg/errors" + packages = ["."] + pruneopts = "" + revision = "614d223910a179a466c1767a985424175c39b465" + version = "v0.9.1" + [[projects]] digest = "1:256484dbbcd271f9ecebc6795b2df8cad4c458dd0f5fd82a8c2fa0c29f233411" name = "github.com/pmezard/go-difflib" @@ -316,12 +359,15 @@ "github.com/agext/levenshtein", "github.com/cookieo9/resources-go", "github.com/coreos/go-iptables/iptables", + "github.com/florianl/go-nfqueue", "github.com/godbus/dbus", "github.com/google/gopacket", "github.com/google/gopacket/layers", "github.com/google/gopacket/tcpassembly", "github.com/google/renameio", + "github.com/hashicorp/go-multierror", "github.com/hashicorp/go-version", + "github.com/mdlayher/netlink", "github.com/miekg/dns", "github.com/oschwald/maxminddb-golang", "github.com/shirou/gopsutil/process", @@ -333,6 +379,7 @@ "golang.org/x/net/ipv4", "golang.org/x/net/publicsuffix", "golang.org/x/sync/errgroup", + "golang.org/x/sys/unix", "golang.org/x/sys/windows", "golang.org/x/sys/windows/svc", "golang.org/x/sys/windows/svc/debug", diff --git a/Gopkg.toml b/Gopkg.toml index f449d026f..dffe63f1b 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -24,7 +24,7 @@ # go-tests = true # unused-packages = true -ignored = ["github.com/safing/portbase/*"] +ignored = ["github.com/safing/portbase/*", "github.com/safing/spn/*"] [[constraint]] name = "github.com/miekg/dns" diff --git a/cmds/portmaster-core/main.go b/cmds/portmaster-core/main.go index 2e250c21a..6243d0d20 100644 --- a/cmds/portmaster-core/main.go +++ b/cmds/portmaster-core/main.go @@ -5,6 +5,7 @@ import ( "github.com/safing/portbase/info" "github.com/safing/portbase/run" + "github.com/safing/spn/conf" // include packages here _ "github.com/safing/portbase/modules/subsystems" @@ -12,9 +13,16 @@ import ( _ "github.com/safing/portmaster/firewall" _ "github.com/safing/portmaster/nameserver" _ "github.com/safing/portmaster/ui" + _ "github.com/safing/spn/captain" ) func main() { - info.Set("Portmaster", "0.4.18", "AGPLv3", true) + // set information + info.Set("Portmaster", "0.5.0", "AGPLv3", true) + + // enable SPN client mode + conf.EnableClient(true) + + // start os.Exit(run.Run()) } diff --git a/firewall/interception.go b/firewall/interception.go index 91f3ba264..15df25d56 100644 --- a/firewall/interception.go +++ b/firewall/interception.go @@ -12,7 +12,10 @@ import ( "github.com/safing/portmaster/firewall/inspection" "github.com/safing/portmaster/firewall/interception" "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/sluice" // module dependencies _ "github.com/safing/portmaster/core/base" @@ -222,6 +225,22 @@ func initialHandler(conn *network.Connection, pkt packet.Packet) { DecideOnConnection(pkt.Ctx(), conn, pkt) conn.Inspecting = false // TODO: enable inspecting again + // tunneling + // TODO: add implementation for forced tunneling + if pkt.IsOutbound() && + captain.ClientReady() && + netutils.IPIsGlobal(conn.Entity.IP) && + 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 + } + } + switch { case conn.Inspecting: log.Tracer(pkt.Ctx()).Trace("filter: start inspecting") diff --git a/firewall/interception/nfqueue_linux.go b/firewall/interception/nfqueue_linux.go index 1b6595c65..efbdf529e 100644 --- a/firewall/interception/nfqueue_linux.go +++ b/firewall/interception/nfqueue_linux.go @@ -81,8 +81,8 @@ func init() { "filter OUTPUT -j C17", "filter INPUT -j C17", "nat OUTPUT -m mark --mark 1799 -p udp -j DNAT --to 127.0.0.1:53", - "nat OUTPUT -m mark --mark 1717 -p tcp -j DNAT --to 127.0.0.17:1117", - "nat OUTPUT -m mark --mark 1717 -p udp -j DNAT --to 127.0.0.17:1117", + "nat OUTPUT -m mark --mark 1717 -p tcp -j DNAT --to 127.0.0.17:717", + "nat OUTPUT -m mark --mark 1717 -p udp -j DNAT --to 127.0.0.17:717", // "nat OUTPUT -m mark --mark 1717 ! -p tcp ! -p udp -j DNAT --to 127.0.0.17", } @@ -116,8 +116,8 @@ func init() { "filter OUTPUT -j C17", "filter INPUT -j C17", "nat OUTPUT -m mark --mark 1799 -p udp -j DNAT --to [::1]:53", - "nat OUTPUT -m mark --mark 1717 -p tcp -j DNAT --to [fd17::17]:1117", - "nat OUTPUT -m mark --mark 1717 -p udp -j DNAT --to [fd17::17]:1117", + "nat OUTPUT -m mark --mark 1717 -p tcp -j DNAT --to [fd17::17]:717", + "nat OUTPUT -m mark --mark 1717 -p udp -j DNAT --to [fd17::17]:717", // "nat OUTPUT -m mark --mark 1717 ! -p tcp ! -p udp -j DNAT --to [fd17::17]", } diff --git a/intel/geoip/location.go b/intel/geoip/location.go index 92fd5b70c..f62d754a4 100644 --- a/intel/geoip/location.go +++ b/intel/geoip/location.go @@ -105,6 +105,7 @@ func PrimitiveNetworkProximity(from net.IP, to net.IP, ipVersion uint8) int { switch ipVersion { case 4: + // TODO: use ip.To4() and :4 a := binary.BigEndian.Uint32(from[12:]) b := binary.BigEndian.Uint32(to[12:]) if a > b { diff --git a/updates/main.go b/updates/main.go index 1aed7bfaa..d68461bf2 100644 --- a/updates/main.go +++ b/updates/main.go @@ -54,6 +54,10 @@ var ( updateASAP bool disableTaskSchedule bool + // MandatoryUpdates is a list of full identifiers that + // should always be kept up to date. + MandatoryUpdates []string + // UserAgent is an HTTP User-Agent that is used to add // more context to requests made by the registry when // fetching resources from the update server. @@ -72,6 +76,24 @@ func init() { module.RegisterEvent(ResourceUpdateEvent) flag.StringVar(&userAgentFromFlag, "update-agent", "", "Sets the user agent for requests to the update server") + + // initialize mandatory updates + if onWindows { + MandatoryUpdates = []string{ + platform("core/portmaster-core.exe"), + platform("start/portmaster-start.exe"), + platform("app/portmaster-app.exe"), + platform("notifier/portmaster-notifier.exe"), + platform("notifier/portmaster-snoretoast.exe"), + } + } else { + MandatoryUpdates = []string{ + platform("core/portmaster-core"), + platform("start/portmaster-start"), + platform("app/portmaster-app"), + platform("notifier/portmaster-notifier"), + } + } } func prep() error { @@ -107,24 +129,6 @@ func start() error { return err } - var mandatoryUpdates []string - if onWindows { - mandatoryUpdates = []string{ - platform("core/portmaster-core.exe"), - platform("start/portmaster-start.exe"), - platform("app/portmaster-app.exe"), - platform("notifier/portmaster-notifier.exe"), - platform("notifier/portmaster-snoretoast.exe"), - } - } else { - mandatoryUpdates = []string{ - platform("core/portmaster-core"), - platform("start/portmaster-start"), - platform("app/portmaster-app"), - platform("notifier/portmaster-notifier"), - } - } - // create registry registry = &updater.ResourceRegistry{ Name: ModuleName, @@ -132,7 +136,7 @@ func start() error { "https://updates.safing.io", }, UserAgent: UserAgent, - MandatoryUpdates: mandatoryUpdates, + MandatoryUpdates: MandatoryUpdates, Beta: releaseChannel() == releaseChannelBeta, DevMode: devMode(), Online: true, diff --git a/updates/upgrader.go b/updates/upgrader.go index 88ca22a7c..e8862528d 100644 --- a/updates/upgrader.go +++ b/updates/upgrader.go @@ -29,6 +29,9 @@ const ( ) var ( + // UpgradeCore specifies if portmaster-core should be upgraded. + UpgradeCore = true + upgraderActive = abool.NewBool(false) pmCtrlUpdate *updater.File pmCoreUpdate *updater.File @@ -58,9 +61,11 @@ func upgrader(_ context.Context, _ interface{}) error { log.Warningf("updates: failed to upgrade portmaster-start: %s", err) } - err = upgradeCoreNotify() - if err != nil { - log.Warningf("updates: failed to notify about core upgrade: %s", err) + if UpgradeCore { + err = upgradeCoreNotify() + if err != nil { + log.Warningf("updates: failed to notify about core upgrade: %s", err) + } } return nil