From 1d315f799a514c7886877239cea9f66a6b5d670f Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 27 Nov 2024 13:42:11 +0000 Subject: [PATCH] Adding a strict check if the application profile is partial Signed-off-by: Amit Schendel --- ...r0011_unexpected_egress_network_traffic.go | 22 ++++++++----------- ..._unexpected_egress_network_traffic_test.go | 13 +++++++++++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic.go b/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic.go index c72387d1..5c50d390 100644 --- a/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic.go +++ b/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic.go @@ -4,8 +4,6 @@ import ( "bytes" "fmt" "net" - "slices" - "strings" apitypes "github.com/armosec/armoapi-go/armotypes" "github.com/goradd/maps" @@ -69,13 +67,19 @@ func (rule *R0011UnexpectedEgressNetworkTraffic) handleNetworkEvent(networkEvent return nil } + // Skip partially watched containers. + if annotations := nn.GetAnnotations(); annotations != nil { + if annotations["kubescape.io/completion"] == string(utils.WatchedContainerCompletionStatusPartial) { + return nil + } + } + nnContainer, err := getContainerFromNetworkNeighborhood(nn, networkEvent.GetContainer()) if err != nil { return nil } domain := objCache.DnsCache().ResolveIpToDomain(networkEvent.DstEndpoint.Addr) - if domain != "" { return nil } @@ -85,11 +89,6 @@ func (rule *R0011UnexpectedEgressNetworkTraffic) handleNetworkEvent(networkEvent if egress.IPAddress == networkEvent.DstEndpoint.Addr { return nil } - - // Check if we seen this dns name before and it's in-cluster address and in the egress list. - if domain != "" && (strings.HasSuffix(domain, "svc.cluster.local.") || slices.Contains(egress.DNSNames, domain)) { - return nil - } } // Alert on the address. @@ -163,11 +162,6 @@ func isPrivateIP(ip string) bool { return true } - // Check if IP is metadata server - if parsedIP.Equal(net.ParseIP("169.254.169.254")) { - return true - } - // Check if IP is in private IP ranges privateIPRanges := []struct { start net.IP @@ -180,6 +174,8 @@ func isPrivateIP(ip string) bool { {net.ParseIP("224.0.0.0"), net.ParseIP("239.255.255.255")}, // Class E (Experimental) {net.ParseIP("240.0.0.0"), net.ParseIP("255.255.255.255")}, + // APIPA (sometimes used for local dns) + {net.ParseIP("169.254.0.0"), net.ParseIP("169.254.255.255")}, } for _, r := range privateIPRanges { diff --git a/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic_test.go b/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic_test.go index 949e8673..9d9b7392 100644 --- a/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic_test.go +++ b/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic_test.go @@ -128,7 +128,20 @@ func TestR0011UnexpectedNetworkTraffic(t *testing.T) { t.Errorf("Expected ruleResult to be nil since we already alerted on this port") } + // Test with non-whitelisted address with nil dns cache with different port. with partial watched container. + e.DstEndpoint.Addr = "5.5.5.5" + e.Port = 81 + originalAnnotations := nn.GetAnnotations() + nn.Annotations = map[string]string{"kubescape.io/completion": string(utils.WatchedContainerCompletionStatusPartial)} + objCache.SetNetworkNeighborhood(nn) + ruleResult = r.ProcessEvent(utils.NetworkEventType, e, &objCache) + if ruleResult != nil { + t.Errorf("Expected ruleResult to be nil since it's a partially watched container") + } + // Test with non-whitelisted address with nil dns cache with different port. + nn.Annotations = originalAnnotations + objCache.SetNetworkNeighborhood(nn) e.DstEndpoint.Addr = "5.5.5.5" e.Port = 80 e.Proto = "UDP"