From eda62f468d1c5ea869f4e488882d0c0ed7d9e864 Mon Sep 17 00:00:00 2001 From: Vladimir Stoilov Date: Wed, 27 Nov 2024 15:59:03 +0200 Subject: [PATCH] [service] Minor fixes to the dns monitor --- .github/workflows/windows-dll.yml | 12 ++++++++++ service/firewall/dns.go | 4 +++- .../dnsmonitor/eventlistener_linux.go | 10 ++++++--- .../dnsmonitor/eventlistener_windows.go | 4 ++++ .../interception/dnsmonitor/module.go | 6 ++--- service/firewall/packet_handler.go | 21 +++++++++--------- service/resolver/resolver.go | 22 +++++++++++-------- 7 files changed, 53 insertions(+), 26 deletions(-) diff --git a/.github/workflows/windows-dll.yml b/.github/workflows/windows-dll.yml index 58084d162..9b2fd7231 100644 --- a/.github/workflows/windows-dll.yml +++ b/.github/workflows/windows-dll.yml @@ -27,3 +27,15 @@ jobs: uses: microsoft/setup-msbuild@v2 - name: Build DLL run: msbuild windows_core_dll\windows_core_dll.sln -t:rebuild -property:Configuration=Release + - name: Verify DLL + shell: powershell + run: | + if (!(Test-Path "windows_core_dll/x64/Release/portmaster-core.dll")) { + Write-Error "DLL build failed: portmaster-core.dll not found" + exit 1 + } + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: portmaster-core-dll + path: windows_core_dll/x64/Release/portmaster-core.dll \ No newline at end of file diff --git a/service/firewall/dns.go b/service/firewall/dns.go index c03d31519..e34347089 100644 --- a/service/firewall/dns.go +++ b/service/firewall/dns.go @@ -297,7 +297,9 @@ func UpdateIPsAndCNAMEs(q *resolver.Query, rrCache *resolver.RRCache, conn *netw // Process CNAMEs record.AddCNAMEs(cnames) // Link connection with cnames. - conn.Entity.CNAME = record.CNAMEs + if conn.Type == network.DNSRequest { + conn.Entity.CNAME = record.CNAMEs + } SaveIPsInCache(ips, profileID, record) } diff --git a/service/firewall/interception/dnsmonitor/eventlistener_linux.go b/service/firewall/interception/dnsmonitor/eventlistener_linux.go index 561469bc4..d987a0823 100644 --- a/service/firewall/interception/dnsmonitor/eventlistener_linux.go +++ b/service/firewall/interception/dnsmonitor/eventlistener_linux.go @@ -12,6 +12,7 @@ import ( "github.com/miekg/dns" "github.com/safing/portmaster/base/log" "github.com/safing/portmaster/service/mgr" + "github.com/safing/portmaster/service/resolver" "github.com/varlink/go/varlink" ) @@ -20,9 +21,12 @@ type Listener struct { } func newListener(module *DNSMonitor) (*Listener, error) { + // Set source of the resolver. + ResolverInfo.Source = resolver.ServerSourceSystemd + // Check if the system has systemd-resolver. _, err := os.Stat("/run/systemd/resolve/io.systemd.Resolve.Monitor") - if os.IsNotExist(err) { + if err != nil { return nil, fmt.Errorf("system does not support systemd resolver monitor") } @@ -31,11 +35,11 @@ func newListener(module *DNSMonitor) (*Listener, error) { restartAttempts := 0 module.mgr.Go("systemd-resolver-event-listener", func(w *mgr.WorkerCtx) error { - // Stop start if the connection failed after too many tries. + // Abort initialization if the connection failed after too many tries. if restartAttempts > 10 { return nil } - defer func() { restartAttempts += 1 }() + restartAttempts += 1 // Initialize varlink connection varlinkConn, err := varlink.NewConnection(module.mgr.Ctx(), "unix:/run/systemd/resolve/io.systemd.Resolve.Monitor") diff --git a/service/firewall/interception/dnsmonitor/eventlistener_windows.go b/service/firewall/interception/dnsmonitor/eventlistener_windows.go index 1a2c0d73d..b6a39fd8d 100644 --- a/service/firewall/interception/dnsmonitor/eventlistener_windows.go +++ b/service/firewall/interception/dnsmonitor/eventlistener_windows.go @@ -11,6 +11,7 @@ import ( "github.com/miekg/dns" "github.com/safing/portmaster/service/mgr" + "github.com/safing/portmaster/service/resolver" ) type Listener struct { @@ -18,6 +19,9 @@ type Listener struct { } func newListener(module *DNSMonitor) (*Listener, error) { + // Set source of the resolver. + ResolverInfo.Source = resolver.ServerSourceETW + listener := &Listener{} var err error // Initialize new dns event session. diff --git a/service/firewall/interception/dnsmonitor/module.go b/service/firewall/interception/dnsmonitor/module.go index 4d412361d..eed8be119 100644 --- a/service/firewall/interception/dnsmonitor/module.go +++ b/service/firewall/interception/dnsmonitor/module.go @@ -16,9 +16,8 @@ import ( ) var ResolverInfo = resolver.ResolverInfo{ - Name: "SystemdResolver", - Type: resolver.ServerSourceEnv, - Source: "System", + Name: "SystemResolver", + Type: resolver.ServerTypeMonitor, } type DNSMonitor struct { @@ -85,6 +84,7 @@ func New(instance instance) (*DNSMonitor, error) { mgr: m, instance: instance, } + return module, nil } diff --git a/service/firewall/packet_handler.go b/service/firewall/packet_handler.go index 772287e45..c0e59cb74 100644 --- a/service/firewall/packet_handler.go +++ b/service/firewall/packet_handler.go @@ -613,13 +613,14 @@ func inspectDNSPacket(conn *network.Connection, pkt packet.Packet) { return } - // Packet was parsed, accept the connection and continue. - err = pkt.Accept() - if err != nil { - log.Errorf("filter: failed to accept dns packet: %s", err) - } - - conn.Type = network.DNSRequest + // Packet was parsed. + // Allow it but only after the answer was added to the cache. + defer func() { + err = pkt.Accept() + if err != nil { + log.Errorf("filter: failed to accept dns packet: %s", err) + } + }() // Check if packet has a question. if len(dnsPacket.Question) == 0 { @@ -645,9 +646,9 @@ func inspectDNSPacket(conn *network.Connection, pkt packet.Packet) { } resolverInfo := &resolver.ResolverInfo{ - Name: "Direct DNS request", // TODO(vladimir): Better name? - Type: resolver.ServerTypeDNS, - Source: resolver.ServerSourcePacket, + Name: "DNSRequestObserver", + Type: resolver.ServerTypeFirewall, + Source: resolver.ServerSourceFirewall, IP: conn.Entity.IP, Domain: conn.Entity.Domain, IPScope: conn.Entity.IPScope, diff --git a/service/resolver/resolver.go b/service/resolver/resolver.go index 90e4110cf..35d71329b 100644 --- a/service/resolver/resolver.go +++ b/service/resolver/resolver.go @@ -17,18 +17,22 @@ import ( // DNS Resolver Attributes. const ( - ServerTypeDNS = "dns" - ServerTypeTCP = "tcp" - ServerTypeDoT = "dot" - ServerTypeDoH = "doh" - ServerTypeMDNS = "mdns" - ServerTypeEnv = "env" + ServerTypeDNS = "dns" + ServerTypeTCP = "tcp" + ServerTypeDoT = "dot" + ServerTypeDoH = "doh" + ServerTypeMDNS = "mdns" + ServerTypeEnv = "env" + ServerTypeMonitor = "monitor" + ServerTypeFirewall = "firewall" ServerSourceConfigured = "config" ServerSourceOperatingSystem = "system" ServerSourceMDNS = "mdns" ServerSourceEnv = "env" - ServerSourcePacket = "packet" + ServerSourceETW = "etw" + ServerSourceSystemd = "systemd" + ServerSourceFirewall = "firewall" ) // DNS resolver scheme aliases. @@ -83,11 +87,11 @@ type ResolverInfo struct { //nolint:golint,maligned // TODO Name string // Type describes the type of the resolver. - // Possible values include dns, tcp, dot, doh, mdns, env, packet. + // Possible values include dns, tcp, dot, doh, mdns, env, monitor, firewall. Type string // Source describes where the resolver configuration came from. - // Possible values include config, system, mdns, env. + // Possible values include config, system, mdns, env, etw, systemd, firewall. Source string // IP is the IP address of the resolver