Fix handling of connectivity / captive portal domains
Also, improve handling of queries during being captive.
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
package firewall
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/safing/portbase/database"
|
||||
@@ -77,18 +79,13 @@ func filterDNSSection(entries []dns.RR, p *profile.LayeredProfile, scope int8) (
|
||||
}
|
||||
|
||||
func filterDNSResponse(conn *network.Connection, rrCache *resolver.RRCache) *resolver.RRCache {
|
||||
p := conn.Process().Profile()
|
||||
|
||||
// do not modify own queries
|
||||
if conn.Process().Pid == os.Getpid() {
|
||||
return rrCache
|
||||
}
|
||||
|
||||
// get profile
|
||||
p := conn.Process().Profile()
|
||||
if p == nil {
|
||||
conn.Block("no profile")
|
||||
return nil
|
||||
}
|
||||
|
||||
// check if DNS response filtering is completely turned off
|
||||
if !p.RemoveOutOfScopeDNS() && !p.RemoveBlockedDNS() {
|
||||
return rrCache
|
||||
@@ -112,6 +109,31 @@ func filterDNSResponse(conn *network.Connection, rrCache *resolver.RRCache) *res
|
||||
rrCache.Filtered = true
|
||||
if validIPs == 0 {
|
||||
conn.Block("no addresses returned for this domain are permitted")
|
||||
|
||||
// If all entries are filtered, this could mean that these are broken/bogus resource records.
|
||||
if rrCache.Expired() {
|
||||
// If the entry is expired, force delete it.
|
||||
err := resolver.DeleteNameRecord(rrCache.Domain, rrCache.Question.String())
|
||||
if err != nil && err != database.ErrNotFound {
|
||||
log.Warningf(
|
||||
"filter: failed to delete fully filtered name cache for %s: %s",
|
||||
rrCache.ID(),
|
||||
err,
|
||||
)
|
||||
}
|
||||
} else if rrCache.TTL > time.Now().Add(10*time.Second).Unix() {
|
||||
// Set a low TTL of 10 seconds if TTL is higher than that.
|
||||
rrCache.TTL = time.Now().Add(10 * time.Second).Unix()
|
||||
err := rrCache.Save()
|
||||
if err != nil {
|
||||
log.Debugf(
|
||||
"filter: failed to set shorter TTL on fully filtered name cache for %s: %s",
|
||||
rrCache.ID(),
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -122,7 +144,25 @@ func filterDNSResponse(conn *network.Connection, rrCache *resolver.RRCache) *res
|
||||
}
|
||||
|
||||
// DecideOnResolvedDNS filters a dns response according to the application profile and settings.
|
||||
func DecideOnResolvedDNS(conn *network.Connection, q *resolver.Query, rrCache *resolver.RRCache) *resolver.RRCache {
|
||||
func DecideOnResolvedDNS(
|
||||
ctx context.Context,
|
||||
conn *network.Connection,
|
||||
q *resolver.Query,
|
||||
rrCache *resolver.RRCache,
|
||||
) *resolver.RRCache {
|
||||
|
||||
// check profile
|
||||
if checkProfileExists(ctx, conn, nil) {
|
||||
// returns true if check triggered
|
||||
return nil
|
||||
}
|
||||
|
||||
// special grant for connectivity domains
|
||||
if checkConnectivityDomain(ctx, conn, nil) {
|
||||
// returns true if check triggered
|
||||
return rrCache
|
||||
}
|
||||
|
||||
updatedRR := filterDNSResponse(conn, rrCache)
|
||||
if updatedRR == nil {
|
||||
return nil
|
||||
|
||||
@@ -52,7 +52,7 @@ func DecideOnConnection(ctx context.Context, conn *network.Connection, pkt packe
|
||||
checkSelfCommunication,
|
||||
checkProfileExists,
|
||||
checkConnectionType,
|
||||
checkCaptivePortal,
|
||||
checkConnectivityDomain,
|
||||
checkConnectionScope,
|
||||
checkEndpointLists,
|
||||
checkBypassPrevention,
|
||||
@@ -181,10 +181,17 @@ func checkConnectionType(ctx context.Context, conn *network.Connection, _ packet
|
||||
return false
|
||||
}
|
||||
|
||||
func checkCaptivePortal(_ context.Context, conn *network.Connection, _ packet.Packet) bool {
|
||||
if netenv.GetOnlineStatus() == netenv.StatusPortal &&
|
||||
conn.Entity.Domain == netenv.GetCaptivePortal().Domain {
|
||||
conn.Accept("captive portal access permitted")
|
||||
func checkConnectivityDomain(_ context.Context, conn *network.Connection, _ packet.Packet) bool {
|
||||
p := conn.Process().Profile()
|
||||
|
||||
if !p.BlockScopeInternet() {
|
||||
// Special grant only applies if application is allowed to connect to the Internet.
|
||||
return false
|
||||
}
|
||||
|
||||
if netenv.GetOnlineStatus() <= netenv.StatusPortal &&
|
||||
netenv.IsConnectivityDomain(conn.Entity.Domain) {
|
||||
conn.Accept("special grant for connectivity domain during network bootstrap")
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user