Detect responses to multi/broadcast queries

This commit is contained in:
Daniel
2022-05-24 11:18:23 +02:00
parent e178b732bc
commit 49e79fe3fd
6 changed files with 151 additions and 10 deletions

View File

@@ -3,7 +3,9 @@ package firewall
import (
"context"
"fmt"
"net"
"path/filepath"
"strconv"
"strings"
"github.com/agext/levenshtein"
@@ -41,6 +43,7 @@ type deciderFn func(context.Context, *network.Connection, *profile.LayeredProfil
var defaultDeciders = []deciderFn{
checkPortmasterConnection,
checkSelfCommunication,
checkIfBroadcastReply,
checkConnectionType,
checkConnectionScope,
checkEndpointLists,
@@ -182,6 +185,46 @@ func checkSelfCommunication(ctx context.Context, conn *network.Connection, _ *pr
return false
}
func checkIfBroadcastReply(ctx context.Context, conn *network.Connection, _ *profile.LayeredProfile, _ packet.Packet) bool {
// Only check inbound connections.
if !conn.Inbound {
return false
}
// Only check if the process has been identified.
if !conn.Process().IsIdentified() {
return false
}
// Check if the remote IP is part of a local network.
localNet, err := netenv.GetLocalNetwork(conn.Entity.IP)
if err != nil {
log.Tracer(ctx).Warningf("filter: failed to get local network: %s", err)
return false
}
if localNet == nil {
return false
}
// Search for a matching requesting connection.
requestingConn := network.GetMulticastRequestConn(conn, localNet)
if requestingConn == nil {
return false
}
conn.Accept(
fmt.Sprintf(
"response to multi/broadcast query to %s/%s",
packet.IPProtocol(requestingConn.Entity.Protocol),
net.JoinHostPort(
requestingConn.Entity.IP.String(),
strconv.Itoa(int(requestingConn.Entity.Port)),
),
),
"",
)
return true
}
func checkEndpointLists(ctx context.Context, conn *network.Connection, p *profile.LayeredProfile, _ packet.Packet) bool {
// DNS request from the system resolver require a special decision process,
// because the original requesting process is not known. Here, we only check

View File

@@ -42,10 +42,10 @@ func checkTunneling(ctx context.Context, conn *network.Connection, pkt packet.Pa
}
// Check more extensively for Local/LAN connections.
myNet, err := netenv.IsMyNet(conn.Entity.IP)
localNet, err := netenv.GetLocalNetwork(conn.Entity.IP)
if err != nil {
log.Warningf("firewall: failed to check if %s is in my net: %s", conn.Entity.IP, err)
} else if myNet {
} else if localNet != nil {
// With IPv6, just checking the IP scope is not enough, as the host very
// likely has a public IPv6 address.
// Don't tunnel LAN connections.