Skip to content

Commit

Permalink
Merge pull request #353 from kubescape/feature/network-anomaly
Browse files Browse the repository at this point in the history
Feature/network anomaly
  • Loading branch information
amitschendel authored Aug 28, 2024
2 parents 6026a04 + 19bc015 commit fe5e5b8
Show file tree
Hide file tree
Showing 11 changed files with 402 additions and 19 deletions.
36 changes: 23 additions & 13 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
nodeprofilemanagerv1 "github.com/kubescape/node-agent/pkg/nodeprofilemanager/v1"
"github.com/kubescape/node-agent/pkg/objectcache"
"github.com/kubescape/node-agent/pkg/objectcache/applicationprofilecache"
"github.com/kubescape/node-agent/pkg/objectcache/dnscache"
"github.com/kubescape/node-agent/pkg/objectcache/k8scache"
"github.com/kubescape/node-agent/pkg/objectcache/networkneighborhoodcache"
objectcachev1 "github.com/kubescape/node-agent/pkg/objectcache/v1"
Expand Down Expand Up @@ -188,6 +189,25 @@ func main() {
relevancyManager = relevancymanager.CreateRelevancyManagerMock()
}

// Create the network and DNS managers
var networkManagerClient networkmanager.NetworkManagerClient
var dnsManagerClient dnsmanager.DNSManagerClient
var dnsResolver dnsmanager.DNSResolver
if cfg.EnableNetworkTracing {
dnsManager := dnsmanager.CreateDNSManager()
dnsManagerClient = dnsManager
// NOTE: dnsResolver is set for threat detection.
dnsResolver = dnsManager
networkManagerClient = networkmanagerv2.CreateNetworkManager(ctx, cfg, clusterData.ClusterName, k8sClient, storageClient, dnsManager, preRunningContainersIDs, k8sObjectCache)
} else {
if cfg.EnableRuntimeDetection {
logger.L().Ctx(ctx).Fatal("Network tracing is disabled, but runtime detection is enabled. Network tracing is required for runtime detection.")
}
dnsManagerClient = dnsmanager.CreateDNSManagerMock()
dnsResolver = dnsmanager.CreateDNSManagerMock()
networkManagerClient = networkmanager.CreateNetworkManagerMock()
}

var ruleManager rulemanager.RuleManagerClient
var objCache objectcache.ObjectCache
var ruleBindingNotify chan rulebinding.RuleBindingNotify
Expand All @@ -206,8 +226,10 @@ func main() {
nnc := networkneighborhoodcache.NewNetworkNeighborhoodCache(nodeName, k8sClient)
dWatcher.AddAdaptor(nnc)

dc := dnscache.NewDnsCache(dnsResolver)

// create object cache
objCache = objectcachev1.NewObjectCache(k8sObjectCache, apc, nnc)
objCache = objectcachev1.NewObjectCache(k8sObjectCache, apc, nnc, dc)

// create exporter
exporter := exporters.InitExporters(cfg.Exporters, clusterData.ClusterName, nodeName)
Expand Down Expand Up @@ -246,18 +268,6 @@ func main() {
malwareManager = malwaremanager.CreateMalwareManagerMock()
}

// Create the network and DNS managers
var networkManagerClient networkmanager.NetworkManagerClient
var dnsManagerClient dnsmanager.DNSManagerClient
if cfg.EnableNetworkTracing {
dnsManager := dnsmanager.CreateDNSManager()
dnsManagerClient = dnsManager
networkManagerClient = networkmanagerv2.CreateNetworkManager(ctx, cfg, clusterData.ClusterName, k8sClient, storageClient, dnsManager, preRunningContainersIDs, k8sObjectCache)
} else {
dnsManagerClient = dnsmanager.CreateDNSManagerMock()
networkManagerClient = networkmanager.CreateNetworkManagerMock()
}

// Create the container handler
mainHandler, err := containerwatcher.CreateIGContainerWatcher(cfg, applicationProfileManager, k8sClient, relevancyManager, networkManagerClient, dnsManagerClient, prometheusExporter, ruleManager, malwareManager, preRunningContainersIDs, &ruleBindingNotify, containerRuntime)
if err != nil {
Expand Down
8 changes: 6 additions & 2 deletions pkg/containerwatcher/v1/container_watcher_private.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ func (ch *IGContainerWatcher) containerCallback(notif containercollection.PubSub
func (ch *IGContainerWatcher) startContainerCollection(ctx context.Context) error {
ch.ctx = ctx

// This is needed when not running as gadget.
// https://github.com/inspektor-gadget/inspektor-gadget/blob/9a797dc046f8bc1f45e85f15db7e99dd4e5cb6e5/cmd/ig/containers/containers.go#L45-L46
if err := host.Init(host.Config{AutoMountFilesystems: true}); err != nil {
return fmt.Errorf("initializing host package: %w", err)
}

// Start the container collection
containerEventFuncs := []containercollection.FuncNotify{
ch.containerCallback,
Expand Down Expand Up @@ -212,8 +218,6 @@ func (ch *IGContainerWatcher) startTracers() error {
}

if ch.cfg.EnableNetworkTracing {
host.Init(host.Config{AutoMountFilesystems: true})

if err := ch.startKubernetesResolution(); err != nil {
logger.L().Error("error starting kubernetes resolution", helpers.Error(err))
return err
Expand Down
33 changes: 33 additions & 0 deletions pkg/objectcache/dnscache/dnscache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package dnscache

import (
"github.com/kubescape/go-logger"
"github.com/kubescape/node-agent/pkg/dnsmanager"
"github.com/kubescape/node-agent/pkg/objectcache"
)

var _ objectcache.DnsCache = (*DnsCacheImpl)(nil)

type DnsCacheImpl struct {
dnsResolver dnsmanager.DNSResolver
}

func NewDnsCache(dnsResolver dnsmanager.DNSResolver) *DnsCacheImpl {
return &DnsCacheImpl{
dnsResolver: dnsResolver,
}
}

func (d *DnsCacheImpl) ResolveIpToDomain(ip string) string {
if d.dnsResolver == nil {
logger.L().Debug("DNS resolver is not set")
return ""
}

domain, ok := d.dnsResolver.ResolveIPAddress(ip)
if !ok {
return ""
}

return domain
}
14 changes: 14 additions & 0 deletions pkg/objectcache/dnscache_interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package objectcache

type DnsCache interface {
ResolveIpToDomain(ip string) string
}

var _DnsCache = (*DnsCacheMock)(nil)

type DnsCacheMock struct {
}

func (dc *DnsCacheMock) ResolveIpToDomain(_ string) string {
return ""
}
5 changes: 5 additions & 0 deletions pkg/objectcache/objectcache_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ type ObjectCache interface {
K8sObjectCache() K8sObjectCache
ApplicationProfileCache() ApplicationProfileCache
NetworkNeighborhoodCache() NetworkNeighborhoodCache
DnsCache() DnsCache
}

var _ ObjectCache = (*ObjectCacheMock)(nil)
Expand All @@ -24,3 +25,7 @@ func (om *ObjectCacheMock) ApplicationProfileCache() ApplicationProfileCache {
func (om *ObjectCacheMock) NetworkNeighborhoodCache() NetworkNeighborhoodCache {
return &NetworkNeighborhoodCacheMock{}
}

func (om *ObjectCacheMock) DnsCache() DnsCache {
return &DnsCacheMock{}
}
8 changes: 7 additions & 1 deletion pkg/objectcache/v1/objectcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ type ObjectCacheImpl struct {
k objectcache.K8sObjectCache
ap objectcache.ApplicationProfileCache
np objectcache.NetworkNeighborhoodCache
dc objectcache.DnsCache
}

func NewObjectCache(k objectcache.K8sObjectCache, ap objectcache.ApplicationProfileCache, np objectcache.NetworkNeighborhoodCache) *ObjectCacheImpl {
func NewObjectCache(k objectcache.K8sObjectCache, ap objectcache.ApplicationProfileCache, np objectcache.NetworkNeighborhoodCache, dc objectcache.DnsCache) *ObjectCacheImpl {
return &ObjectCacheImpl{
k: k,
ap: ap,
np: np,
dc: dc,
}
}

Expand All @@ -30,3 +32,7 @@ func (o *ObjectCacheImpl) ApplicationProfileCache() objectcache.ApplicationProfi
func (o *ObjectCacheImpl) NetworkNeighborhoodCache() objectcache.NetworkNeighborhoodCache {
return o.np
}

func (o *ObjectCacheImpl) DnsCache() objectcache.DnsCache {
return o.dc
}
6 changes: 3 additions & 3 deletions pkg/objectcache/v1/objectcache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ import (

func TestK8sObjectCache(t *testing.T) {
k := &objectcache.K8sObjectCacheMock{}
k8sObjectCache := NewObjectCache(k, nil, nil)
k8sObjectCache := NewObjectCache(k, nil, nil, nil)
assert.NotNil(t, k8sObjectCache.K8sObjectCache())
}

func TestApplicationProfileCache(t *testing.T) {
ap := &objectcache.ApplicationProfileCacheMock{}
k8sObjectCache := NewObjectCache(nil, ap, nil)
k8sObjectCache := NewObjectCache(nil, ap, nil, nil)
assert.NotNil(t, k8sObjectCache.ApplicationProfileCache())
}

func TestNetworkNeighborhoodCache(t *testing.T) {
nn := &objectcache.NetworkNeighborhoodCacheMock{}
k8sObjectCache := NewObjectCache(nil, nil, nn)
k8sObjectCache := NewObjectCache(nil, nil, nn, nil)
assert.NotNil(t, k8sObjectCache.NetworkNeighborhoodCache())
}
1 change: 1 addition & 0 deletions pkg/ruleengine/v1/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func NewRuleCreator() *RuleCreatorImpl {
R0008ReadEnvironmentVariablesProcFSRuleDescriptor,
R0009EbpfProgramLoadRuleDescriptor,
R0010UnexpectedSensitiveFileAccessRuleDescriptor,
R0011UnexpectedEgressNetworkTrafficRuleDescriptor,
R1000ExecFromMaliciousSourceDescriptor,
R1001ExecBinaryNotInBaseImageRuleDescriptor,
R1002LoadKernelModuleRuleDescriptor,
Expand Down
18 changes: 18 additions & 0 deletions pkg/ruleengine/v1/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import (
var _ objectcache.ApplicationProfileCache = (*RuleObjectCacheMock)(nil)
var _ objectcache.K8sObjectCache = (*RuleObjectCacheMock)(nil)
var _ objectcache.NetworkNeighborhoodCache = (*RuleObjectCacheMock)(nil)
var _ objectcache.DnsCache = (*RuleObjectCacheMock)(nil)

type RuleObjectCacheMock struct {
profile *v1beta1.ApplicationProfile
podSpec *corev1.PodSpec
podStatus *corev1.PodStatus
nn *v1beta1.NetworkNeighborhood
dnsCache map[string]string
}

func (r *RuleObjectCacheMock) GetApplicationProfile(string) *v1beta1.ApplicationProfile {
Expand Down Expand Up @@ -68,3 +70,19 @@ func (r *RuleObjectCacheMock) GetNetworkNeighborhood(string) *v1beta1.NetworkNei
func (r *RuleObjectCacheMock) SetNetworkNeighborhood(nn *v1beta1.NetworkNeighborhood) {
r.nn = nn
}

func (r *RuleObjectCacheMock) DnsCache() objectcache.DnsCache {
return r
}

func (r *RuleObjectCacheMock) SetDnsCache(dnsCache map[string]string) {
r.dnsCache = dnsCache
}

func (r *RuleObjectCacheMock) ResolveIpToDomain(ip string) string {
if _, ok := r.dnsCache[ip]; ok {
return r.dnsCache[ip]
}

return ""
}
Loading

0 comments on commit fe5e5b8

Please sign in to comment.