From 8ad283dd0534cbbb194ddadab6a1a848f05b7116 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Tue, 10 Sep 2024 15:56:16 +0000 Subject: [PATCH 01/23] Adding base refactor Signed-off-by: Amit Schendel --- main.go | 2 +- .../container_watcher_interface.go | 16 +++++++ .../container_watcher_mock.go | 44 +++++++++++++++++++ pkg/containerwatcher/v1/container_watcher.go | 42 ++++++++++++++++++ .../v1/container_watcher_private.go | 16 +++++++ pkg/ruleengine/v1/factory.go | 4 ++ pkg/rulemanager/rule_manager_interface.go | 3 ++ pkg/rulemanager/rule_manager_mock.go | 6 +++ pkg/rulemanager/v1/rule_manager.go | 11 +++++ pkg/utils/events.go | 24 +++++----- {internal => pkg}/validator/ebpf/verifier.go | 0 {internal => pkg}/validator/validator.go | 2 +- {internal => pkg}/validator/validator_test.go | 0 13 files changed, 156 insertions(+), 14 deletions(-) rename {internal => pkg}/validator/ebpf/verifier.go (100%) rename {internal => pkg}/validator/validator.go (98%) rename {internal => pkg}/validator/validator_test.go (100%) diff --git a/main.go b/main.go index f4c8eeda..bdc0b22b 100644 --- a/main.go +++ b/main.go @@ -10,7 +10,6 @@ import ( "strings" "syscall" - "github.com/kubescape/node-agent/internal/validator" "github.com/kubescape/node-agent/pkg/applicationprofilemanager" applicationprofilemanagerv1 "github.com/kubescape/node-agent/pkg/applicationprofilemanager/v1" "github.com/kubescape/node-agent/pkg/config" @@ -44,6 +43,7 @@ import ( seccompmanagerv1 "github.com/kubescape/node-agent/pkg/seccompmanager/v1" "github.com/kubescape/node-agent/pkg/storage/v1" "github.com/kubescape/node-agent/pkg/utils" + "github.com/kubescape/node-agent/pkg/validator" "github.com/kubescape/node-agent/pkg/watcher/dynamicwatcher" "github.com/kubescape/node-agent/pkg/watcher/seccompprofilewatcher" diff --git a/pkg/containerwatcher/container_watcher_interface.go b/pkg/containerwatcher/container_watcher_interface.go index c63b5754..5e8ab799 100644 --- a/pkg/containerwatcher/container_watcher_interface.go +++ b/pkg/containerwatcher/container_watcher_interface.go @@ -2,10 +2,26 @@ package containerwatcher import ( "context" + + containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" + "github.com/inspektor-gadget/inspektor-gadget/pkg/socketenricher" + tracercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/tracer-collection" ) type ContainerWatcher interface { Ready() bool Start(ctx context.Context) error Stop() + GetTracerCollection() *tracercollection.TracerCollection + GetContainerCollection() *containercollection.ContainerCollection + GetSocketEnricher() *socketenricher.SocketEnricher + GetContainerSelector() *containercollection.ContainerSelector + RegisterCustomTracer(tracer CustomTracer) error + UnregisterCustomTracer(tracerName string) error +} + +type CustomTracer interface { + Start() error + Stop() error + Name() string } diff --git a/pkg/containerwatcher/container_watcher_mock.go b/pkg/containerwatcher/container_watcher_mock.go index c043231d..472a3d73 100644 --- a/pkg/containerwatcher/container_watcher_mock.go +++ b/pkg/containerwatcher/container_watcher_mock.go @@ -2,6 +2,10 @@ package containerwatcher import ( "context" + + containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" + "github.com/inspektor-gadget/inspektor-gadget/pkg/socketenricher" + tracercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/tracer-collection" ) type ContainerWatcherMock struct{} @@ -16,4 +20,44 @@ func (c ContainerWatcherMock) Start(_ context.Context) error { func (c ContainerWatcherMock) Stop() {} +func (c ContainerWatcherMock) RegisterCustomTracer(_ CustomTracer) error { + return nil +} + +func (c ContainerWatcherMock) UnregisterCustomTracer(_ string) error { + return nil +} + +func (c ContainerWatcherMock) GetTracerCollection() *tracercollection.TracerCollection { + return nil +} + +func (c ContainerWatcherMock) GetContainerCollection() *containercollection.ContainerCollection { + return nil +} + +func (c ContainerWatcherMock) GetSocketEnricher() *socketenricher.SocketEnricher { + return nil +} + +func (c ContainerWatcherMock) GetContainerSelector() *containercollection.ContainerSelector { + return nil +} + var _ ContainerWatcher = (*ContainerWatcherMock)(nil) + +type CustomTracerMock struct{} + +func (c CustomTracerMock) Start() error { + return nil +} + +func (c CustomTracerMock) Stop() error { + return nil +} + +func (c CustomTracerMock) Name() string { + return "" +} + +var _ CustomTracer = (*CustomTracerMock)(nil) diff --git a/pkg/containerwatcher/v1/container_watcher.go b/pkg/containerwatcher/v1/container_watcher.go index e3ec2c39..bd249c07 100644 --- a/pkg/containerwatcher/v1/container_watcher.go +++ b/pkg/containerwatcher/v1/container_watcher.go @@ -103,6 +103,8 @@ type IGContainerWatcher struct { sshTracer *tracerssh.Tracer kubeIPInstance operators.OperatorInstance kubeNameInstance operators.OperatorInstance + // Third party tracers + thirdPartyTracers []containerwatcher.CustomTracer // Worker pools capabilitiesWorkerPool *ants.PoolWithFunc @@ -358,9 +360,49 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli timeBasedContainers: mapset.NewSet[string](), ruleManagedPods: mapset.NewSet[string](), runtime: runtime, + thirdPartyTracers: []containerwatcher.CustomTracer{}, }, nil } +func (ch *IGContainerWatcher) GetContainerCollection() *containercollection.ContainerCollection { + return ch.containerCollection +} + +func (ch *IGContainerWatcher) GetTracerCollection() *tracercollection.TracerCollection { + return ch.tracerCollection +} + +func (ch *IGContainerWatcher) GetSocketEnricher() *socketenricher.SocketEnricher { + return ch.socketEnricher +} + +func (ch *IGContainerWatcher) GetContainerSelector() *containercollection.ContainerSelector { + return &ch.containerSelector +} + +func (ch *IGContainerWatcher) RegisterCustomTracer(tracer containerwatcher.CustomTracer) error { + for _, t := range ch.thirdPartyTracers { + if t.Name() == tracer.Name() { + return fmt.Errorf("tracer with name %s already registered", tracer.Name()) + } + } + + ch.thirdPartyTracers = append(ch.thirdPartyTracers, tracer) + return nil +} + +func (ch *IGContainerWatcher) UnregisterCustomTracer(name string) error { + for i, t := range ch.thirdPartyTracers { + if t.Name() == name { + // Remove the tracer from the slice + ch.thirdPartyTracers = append(ch.thirdPartyTracers[:i], ch.thirdPartyTracers[i+1:]...) + return nil + } + } + + return fmt.Errorf("tracer with name %s not found", name) +} + func (ch *IGContainerWatcher) Start(ctx context.Context) error { if !ch.running { diff --git a/pkg/containerwatcher/v1/container_watcher_private.go b/pkg/containerwatcher/v1/container_watcher_private.go index da81b489..7789382b 100644 --- a/pkg/containerwatcher/v1/container_watcher_private.go +++ b/pkg/containerwatcher/v1/container_watcher_private.go @@ -267,6 +267,14 @@ func (ch *IGContainerWatcher) startTracers() error { logger.L().Error("error starting ssh tracing", helpers.Error(err)) return err } + + // Start third party tracers + for _, tracer := range ch.thirdPartyTracers { + if err := tracer.Start(); err != nil { + logger.L().Error("error starting custom tracer", helpers.String("tracer", tracer.Name()), helpers.Error(err)) + return err + } + } } return nil @@ -338,6 +346,14 @@ func (ch *IGContainerWatcher) stopTracers() error { logger.L().Error("error stopping ssh tracing", helpers.Error(err)) errs = errors.Join(errs, err) } + + // Stop third party tracers + for _, tracer := range ch.thirdPartyTracers { + if err := tracer.Stop(); err != nil { + logger.L().Error("error stopping custom tracer", helpers.String("tracer", tracer.Name()), helpers.Error(err)) + errs = errors.Join(errs, err) + } + } } return errs diff --git a/pkg/ruleengine/v1/factory.go b/pkg/ruleengine/v1/factory.go index df3c0d01..485b918e 100644 --- a/pkg/ruleengine/v1/factory.go +++ b/pkg/ruleengine/v1/factory.go @@ -70,3 +70,7 @@ func (r *RuleCreatorImpl) CreateRuleByName(name string) ruleengine.RuleEvaluator func (r *RuleCreatorImpl) GetAllRuleDescriptors() []RuleDescriptor { return r.ruleDescriptions } + +func (r *RuleCreatorImpl) AddRuleDescriptor(rule RuleDescriptor) { + r.ruleDescriptions = append(r.ruleDescriptions, rule) +} diff --git a/pkg/rulemanager/rule_manager_interface.go b/pkg/rulemanager/rule_manager_interface.go index 52ae18c6..4be952aa 100644 --- a/pkg/rulemanager/rule_manager_interface.go +++ b/pkg/rulemanager/rule_manager_interface.go @@ -5,6 +5,7 @@ import ( tracerrandomxtype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/randomx/types" tracersshtype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/ssh/types" tracersymlinktype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/symlink/types" + "github.com/kubescape/node-agent/pkg/utils" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" tracercapabilitiestype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/capabilities/types" @@ -12,6 +13,7 @@ import ( tracerexectype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/exec/types" tracernetworktype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/network/types" traceropentype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/open/types" + eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types" v1 "k8s.io/api/core/v1" ) @@ -28,6 +30,7 @@ type RuleManagerClient interface { ReportSymlinkEvent(event tracersymlinktype.Event) ReportHardlinkEvent(event tracerhardlinktype.Event) ReportSSHEvent(event tracersshtype.Event) + ReportEvent(eventType utils.EventType, event eventtypes.Event) HasApplicableRuleBindings(namespace, name string) bool HasFinalApplicationProfile(pod *v1.Pod) bool IsContainerMonitored(k8sContainerID string) bool diff --git a/pkg/rulemanager/rule_manager_mock.go b/pkg/rulemanager/rule_manager_mock.go index 08d0cbd1..ac406b5f 100644 --- a/pkg/rulemanager/rule_manager_mock.go +++ b/pkg/rulemanager/rule_manager_mock.go @@ -5,6 +5,7 @@ import ( tracerrandomxtype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/randomx/types" tracersshtype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/ssh/types" tracersymlinktype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/symlink/types" + "github.com/kubescape/node-agent/pkg/utils" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" tracercapabilitiestype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/capabilities/types" @@ -12,6 +13,7 @@ import ( tracerexectype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/exec/types" tracernetworktype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/network/types" traceropentype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/open/types" + eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types" v1 "k8s.io/api/core/v1" ) @@ -68,6 +70,10 @@ func (r *RuleManagerMock) ReportSSHEvent(_ tracersshtype.Event) { // noop } +func (r *RuleManagerMock) ReportEvent(_ utils.EventType, _ eventtypes.Event) { + // noop +} + func (r *RuleManagerMock) HasApplicableRuleBindings(_, _ string) bool { return false } diff --git a/pkg/rulemanager/v1/rule_manager.go b/pkg/rulemanager/v1/rule_manager.go index 1e3a2f63..d632323d 100644 --- a/pkg/rulemanager/v1/rule_manager.go +++ b/pkg/rulemanager/v1/rule_manager.go @@ -440,6 +440,17 @@ func (rm *RuleManager) ReportSSHEvent(event tracersshtype.Event) { rm.processEvent(utils.SSHEventType, &event, rules) } +func (rm *RuleManager) ReportEvent(eventType utils.EventType, event eventtypes.Event) { + if event.GetNamespace() == "" || event.GetPod() == "" { + logger.L().Error("RuleManager - failed to get namespace and pod name from custom event") + return + } + + // list custom rules + rules := rm.ruleBindingCache.ListRulesForPod(event.GetNamespace(), event.GetPod()) + rm.processEvent(eventType, &event, rules) +} + func (rm *RuleManager) processEvent(eventType utils.EventType, event interface{}, rules []ruleengine.RuleEvaluator) { for _, rule := range rules { if rule == nil { diff --git a/pkg/utils/events.go b/pkg/utils/events.go index 5af8e2e0..1886e77b 100644 --- a/pkg/utils/events.go +++ b/pkg/utils/events.go @@ -1,17 +1,17 @@ package utils -type EventType int +type EventType string const ( - ExecveEventType EventType = iota - OpenEventType - CapabilitiesEventType - DnsEventType - NetworkEventType - SyscallEventType - RandomXEventType - SymlinkEventType - HardlinkEventType - SSHEventType - AllEventType + ExecveEventType EventType = "exec" + OpenEventType EventType = "open" + CapabilitiesEventType EventType = "capabilities" + DnsEventType EventType = "dns" + NetworkEventType EventType = "network" + SyscallEventType EventType = "syscall" + RandomXEventType EventType = "randomx" + SymlinkEventType EventType = "symlink" + HardlinkEventType EventType = "hardlink" + SSHEventType EventType = "ssh" + AllEventType EventType = "all" ) diff --git a/internal/validator/ebpf/verifier.go b/pkg/validator/ebpf/verifier.go similarity index 100% rename from internal/validator/ebpf/verifier.go rename to pkg/validator/ebpf/verifier.go diff --git a/internal/validator/validator.go b/pkg/validator/validator.go similarity index 98% rename from internal/validator/validator.go rename to pkg/validator/validator.go index fa655242..0db9834d 100644 --- a/internal/validator/validator.go +++ b/pkg/validator/validator.go @@ -5,8 +5,8 @@ import ( "os" "syscall" - "github.com/kubescape/node-agent/internal/validator/ebpf" "github.com/kubescape/node-agent/pkg/config" + "github.com/kubescape/node-agent/pkg/validator/ebpf" "github.com/cilium/ebpf/rlimit" "github.com/facette/natsort" diff --git a/internal/validator/validator_test.go b/pkg/validator/validator_test.go similarity index 100% rename from internal/validator/validator_test.go rename to pkg/validator/validator_test.go From fdbd8daf7bb35fd629f8415143451d25dbb6a7c1 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 11 Sep 2024 07:54:57 +0000 Subject: [PATCH 02/23] Adding a way to extend rules writing Signed-off-by: Amit Schendel --- pkg/rulebindingmanager/cache/cache.go | 5 ++++ pkg/ruleengine/ruleengine_interface.go | 29 +++++++++++++++++++ pkg/ruleengine/ruleengine_mock.go | 3 ++ pkg/ruleengine/v1/factory.go | 8 ++--- .../v1/r0001_unexpected_process_launched.go | 2 +- .../v1/r0002_unexpected_file_access.go | 2 +- .../v1/r0003_unexpected_system_call.go | 2 +- .../v1/r0004_unexpected_capability_used.go | 2 +- .../v1/r0005_unexpected_domain_request.go | 2 +- ...unexpected_service_account_token_access.go | 2 +- .../v1/r0007_kubernetes_client_executed.go | 2 +- .../v1/r0008_read_env_variables_procfs.go | 2 +- pkg/ruleengine/v1/r0009_ebpf_program_load.go | 4 +-- .../r0010_unexpected_sensitive_file_access.go | 2 +- ...r0011_unexpected_egress_network_traffic.go | 2 +- .../v1/r1000_exec_from_malicious_source.go | 2 +- .../v1/r1001_exec_binary_not_in_base_image.go | 2 +- pkg/ruleengine/v1/r1002_load_kernel_module.go | 2 +- .../v1/r1003_malicious_ssh_connection.go | 2 +- pkg/ruleengine/v1/r1004_exec_from_mount.go | 2 +- pkg/ruleengine/v1/r1005_fileless_execution.go | 2 +- .../v1/r1006_unshare_system_call.go | 2 +- pkg/ruleengine/v1/r1007_xmr_crypto_mining.go | 2 +- .../v1/r1008_crypto_mining_domain.go | 2 +- pkg/ruleengine/v1/r1009_crypto_mining_port.go | 2 +- ...010_symlink_created_over_sensitive_file.go | 2 +- pkg/ruleengine/v1/r1011_ld_preload_hook.go | 2 +- ...12_hardlink_created_over_sensitive_file.go | 2 +- pkg/ruleengine/v1/rule.go | 28 ------------------ 29 files changed, 66 insertions(+), 57 deletions(-) diff --git a/pkg/rulebindingmanager/cache/cache.go b/pkg/rulebindingmanager/cache/cache.go index 5bd7b841..a5e6667f 100644 --- a/pkg/rulebindingmanager/cache/cache.go +++ b/pkg/rulebindingmanager/cache/cache.go @@ -389,6 +389,11 @@ func (c *RBCache) createRule(r *typesv1.RuntimeAlertRuleBindingRule) []ruleengin return []ruleengine.RuleEvaluator{} } +// Expose the rule creator to be able to create rules from third party. +func (c *RBCache) GetRuleCreator() ruleengine.RuleCreator { + return c.ruleCreator +} + func diff(a, b []rulebindingmanager.RuleBindingNotify) []rulebindingmanager.RuleBindingNotify { m := make(map[string]rulebindingmanager.RuleBindingNotify) diff := make([]rulebindingmanager.RuleBindingNotify, 0) diff --git a/pkg/ruleengine/ruleengine_interface.go b/pkg/ruleengine/ruleengine_interface.go index 3756c183..84dfe2e4 100644 --- a/pkg/ruleengine/ruleengine_interface.go +++ b/pkg/ruleengine/ruleengine_interface.go @@ -17,11 +17,40 @@ const ( RulePrioritySystemIssue = 1000 ) +type RuleDescriptor struct { + // Rule ID + ID string + // Rule Name + Name string + // Rule Description + Description string + // Priority + Priority int + // Tags + Tags []string + // Rule requirements + Requirements RuleSpec + // Create a rule function + RuleCreationFunc func() RuleEvaluator +} + +func (r *RuleDescriptor) HasTags(tags []string) bool { + for _, tag := range tags { + for _, ruleTag := range r.Tags { + if tag == ruleTag { + return true + } + } + } + return false +} + // RuleCreator is an interface for creating rules by tags, IDs, and names type RuleCreator interface { CreateRulesByTags(tags []string) []RuleEvaluator CreateRuleByID(id string) RuleEvaluator CreateRuleByName(name string) RuleEvaluator + RegisterRule(rule RuleDescriptor) } type RuleEvaluator interface { diff --git a/pkg/ruleengine/ruleengine_mock.go b/pkg/ruleengine/ruleengine_mock.go index 0f4894e1..28ab3775 100644 --- a/pkg/ruleengine/ruleengine_mock.go +++ b/pkg/ruleengine/ruleengine_mock.go @@ -25,6 +25,9 @@ func (r *RuleCreatorMock) CreateRuleByName(name string) RuleEvaluator { return &RuleMock{RuleName: name} } +func (r *RuleCreatorMock) RegisterRule(rule RuleDescriptor) { +} + var _ RuleEvaluator = (*RuleMock)(nil) type RuleMock struct { diff --git a/pkg/ruleengine/v1/factory.go b/pkg/ruleengine/v1/factory.go index 485b918e..bde9333c 100644 --- a/pkg/ruleengine/v1/factory.go +++ b/pkg/ruleengine/v1/factory.go @@ -5,12 +5,12 @@ import "github.com/kubescape/node-agent/pkg/ruleengine" var _ ruleengine.RuleCreator = (*RuleCreatorImpl)(nil) type RuleCreatorImpl struct { - ruleDescriptions []RuleDescriptor + ruleDescriptions []ruleengine.RuleDescriptor } func NewRuleCreator() *RuleCreatorImpl { return &RuleCreatorImpl{ - ruleDescriptions: []RuleDescriptor{ + ruleDescriptions: []ruleengine.RuleDescriptor{ R0001UnexpectedProcessLaunchedRuleDescriptor, R0002UnexpectedFileAccessRuleDescriptor, R0003UnexpectedSystemCallRuleDescriptor, @@ -67,10 +67,10 @@ func (r *RuleCreatorImpl) CreateRuleByName(name string) ruleengine.RuleEvaluator return nil } -func (r *RuleCreatorImpl) GetAllRuleDescriptors() []RuleDescriptor { +func (r *RuleCreatorImpl) GetAllRuleDescriptors() []ruleengine.RuleDescriptor { return r.ruleDescriptions } -func (r *RuleCreatorImpl) AddRuleDescriptor(rule RuleDescriptor) { +func (r *RuleCreatorImpl) RegisterRule(rule ruleengine.RuleDescriptor) { r.ruleDescriptions = append(r.ruleDescriptions, rule) } diff --git a/pkg/ruleengine/v1/r0001_unexpected_process_launched.go b/pkg/ruleengine/v1/r0001_unexpected_process_launched.go index fdd7ebc5..90203160 100644 --- a/pkg/ruleengine/v1/r0001_unexpected_process_launched.go +++ b/pkg/ruleengine/v1/r0001_unexpected_process_launched.go @@ -21,7 +21,7 @@ const ( R0001Name = "Unexpected process launched" ) -var R0001UnexpectedProcessLaunchedRuleDescriptor = RuleDescriptor{ +var R0001UnexpectedProcessLaunchedRuleDescriptor = ruleengine.RuleDescriptor{ ID: R0001ID, Name: R0001Name, Description: "Detecting exec calls that are not whitelisted by application profile", diff --git a/pkg/ruleengine/v1/r0002_unexpected_file_access.go b/pkg/ruleengine/v1/r0002_unexpected_file_access.go index 17321270..b17ec651 100644 --- a/pkg/ruleengine/v1/r0002_unexpected_file_access.go +++ b/pkg/ruleengine/v1/r0002_unexpected_file_access.go @@ -22,7 +22,7 @@ const ( R0002Name = "Unexpected file access" ) -var R0002UnexpectedFileAccessRuleDescriptor = RuleDescriptor{ +var R0002UnexpectedFileAccessRuleDescriptor = ruleengine.RuleDescriptor{ ID: R0002ID, Name: R0002Name, Description: "Detecting file access that are not whitelisted by application profile. File access is defined by the combination of path and flags", diff --git a/pkg/ruleengine/v1/r0003_unexpected_system_call.go b/pkg/ruleengine/v1/r0003_unexpected_system_call.go index 22c2bce9..eb87d911 100644 --- a/pkg/ruleengine/v1/r0003_unexpected_system_call.go +++ b/pkg/ruleengine/v1/r0003_unexpected_system_call.go @@ -18,7 +18,7 @@ const ( R0003Name = "Unexpected system call" ) -var R0003UnexpectedSystemCallRuleDescriptor = RuleDescriptor{ +var R0003UnexpectedSystemCallRuleDescriptor = ruleengine.RuleDescriptor{ ID: R0003ID, Name: R0003Name, Description: "Detecting unexpected system calls that are not whitelisted by application profile.", diff --git a/pkg/ruleengine/v1/r0004_unexpected_capability_used.go b/pkg/ruleengine/v1/r0004_unexpected_capability_used.go index dd77fca0..46adf8a9 100644 --- a/pkg/ruleengine/v1/r0004_unexpected_capability_used.go +++ b/pkg/ruleengine/v1/r0004_unexpected_capability_used.go @@ -17,7 +17,7 @@ const ( R0004Name = "Unexpected capability used" ) -var R0004UnexpectedCapabilityUsedRuleDescriptor = RuleDescriptor{ +var R0004UnexpectedCapabilityUsedRuleDescriptor = ruleengine.RuleDescriptor{ ID: R0004ID, Name: R0004Name, Description: "Detecting unexpected capabilities that are not whitelisted by application profile. Every unexpected capability is identified in context of a syscall and will be alerted only once per container.", diff --git a/pkg/ruleengine/v1/r0005_unexpected_domain_request.go b/pkg/ruleengine/v1/r0005_unexpected_domain_request.go index c5ab77b7..b8562c8f 100644 --- a/pkg/ruleengine/v1/r0005_unexpected_domain_request.go +++ b/pkg/ruleengine/v1/r0005_unexpected_domain_request.go @@ -20,7 +20,7 @@ const ( R0005Name = "Unexpected domain request" ) -var R0005UnexpectedDomainRequestRuleDescriptor = RuleDescriptor{ +var R0005UnexpectedDomainRequestRuleDescriptor = ruleengine.RuleDescriptor{ ID: R0005ID, Name: R0005Name, Description: "Detecting unexpected domain requests that are not whitelisted by application profile.", diff --git a/pkg/ruleengine/v1/r0006_unexpected_service_account_token_access.go b/pkg/ruleengine/v1/r0006_unexpected_service_account_token_access.go index 891f8f97..8d6c4687 100644 --- a/pkg/ruleengine/v1/r0006_unexpected_service_account_token_access.go +++ b/pkg/ruleengine/v1/r0006_unexpected_service_account_token_access.go @@ -27,7 +27,7 @@ var serviceAccountTokenPathsPrefix = []string{ "/var/run/secrets/eks.amazonaws.com/serviceaccount", } -var R0006UnexpectedServiceAccountTokenAccessRuleDescriptor = RuleDescriptor{ +var R0006UnexpectedServiceAccountTokenAccessRuleDescriptor = ruleengine.RuleDescriptor{ ID: R0006ID, Name: R0006Name, Description: "Detecting unexpected access to service account token.", diff --git a/pkg/ruleengine/v1/r0007_kubernetes_client_executed.go b/pkg/ruleengine/v1/r0007_kubernetes_client_executed.go index 58e3766a..66bd9add 100644 --- a/pkg/ruleengine/v1/r0007_kubernetes_client_executed.go +++ b/pkg/ruleengine/v1/r0007_kubernetes_client_executed.go @@ -44,7 +44,7 @@ var kubernetesClients = []string{ "containerd-shim-runc", } -var R0007KubernetesClientExecutedDescriptor = RuleDescriptor{ +var R0007KubernetesClientExecutedDescriptor = ruleengine.RuleDescriptor{ ID: R0007ID, Name: R0007Name, Description: "Detecting exececution of kubernetes client", diff --git a/pkg/ruleengine/v1/r0008_read_env_variables_procfs.go b/pkg/ruleengine/v1/r0008_read_env_variables_procfs.go index 86c55fb9..2558225b 100644 --- a/pkg/ruleengine/v1/r0008_read_env_variables_procfs.go +++ b/pkg/ruleengine/v1/r0008_read_env_variables_procfs.go @@ -17,7 +17,7 @@ const ( R0008Name = "Read Environment Variables from procfs" ) -var R0008ReadEnvironmentVariablesProcFSRuleDescriptor = RuleDescriptor{ +var R0008ReadEnvironmentVariablesProcFSRuleDescriptor = ruleengine.RuleDescriptor{ ID: R0008ID, Name: R0008Name, Description: "Detecting reading environment variables from procfs.", diff --git a/pkg/ruleengine/v1/r0009_ebpf_program_load.go b/pkg/ruleengine/v1/r0009_ebpf_program_load.go index af12b834..655ceefc 100644 --- a/pkg/ruleengine/v1/r0009_ebpf_program_load.go +++ b/pkg/ruleengine/v1/r0009_ebpf_program_load.go @@ -18,7 +18,7 @@ const ( R0009Name = "eBPF Program Load" ) -var R0009EbpfProgramLoadRuleDescriptor = RuleDescriptor{ +var R0009EbpfProgramLoadRuleDescriptor = ruleengine.RuleDescriptor{ ID: R0009ID, Name: R0009Name, Description: "Detecting eBPF program load.", @@ -105,7 +105,7 @@ func (rule *R0009EbpfProgramLoad) ProcessEvent(eventType utils.EventType, event RuleDescription: fmt.Sprintf("bpf system call executed in %s", syscallEvent.GetContainer()), }, RuntimeAlertK8sDetails: apitypes.RuntimeAlertK8sDetails{ - PodName: syscallEvent.GetPod(), + PodName: syscallEvent.GetPod(), PodLabels: syscallEvent.K8s.PodLabels, }, RuleID: rule.ID(), diff --git a/pkg/ruleengine/v1/r0010_unexpected_sensitive_file_access.go b/pkg/ruleengine/v1/r0010_unexpected_sensitive_file_access.go index 868306e3..85448133 100644 --- a/pkg/ruleengine/v1/r0010_unexpected_sensitive_file_access.go +++ b/pkg/ruleengine/v1/r0010_unexpected_sensitive_file_access.go @@ -19,7 +19,7 @@ const ( R0010Name = "Unexpected Sensitive File Access" ) -var R0010UnexpectedSensitiveFileAccessRuleDescriptor = RuleDescriptor{ +var R0010UnexpectedSensitiveFileAccessRuleDescriptor = ruleengine.RuleDescriptor{ ID: R0010ID, Name: R0010Name, Description: "Detecting access to sensitive files.", diff --git a/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic.go b/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic.go index 78384fa9..7c57843e 100644 --- a/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic.go +++ b/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic.go @@ -21,7 +21,7 @@ const ( R0011Name = "Unexpected Egress Network Traffic" ) -var R0011UnexpectedEgressNetworkTrafficRuleDescriptor = RuleDescriptor{ +var R0011UnexpectedEgressNetworkTrafficRuleDescriptor = ruleengine.RuleDescriptor{ ID: R0011ID, Name: R0011Name, Description: "Detecting unexpected egress network traffic that is not whitelisted by application profile.", diff --git a/pkg/ruleengine/v1/r1000_exec_from_malicious_source.go b/pkg/ruleengine/v1/r1000_exec_from_malicious_source.go index b60eacd6..c70fbbf3 100644 --- a/pkg/ruleengine/v1/r1000_exec_from_malicious_source.go +++ b/pkg/ruleengine/v1/r1000_exec_from_malicious_source.go @@ -18,7 +18,7 @@ const ( R1000Name = "Exec from malicious source" ) -var R1000ExecFromMaliciousSourceDescriptor = RuleDescriptor{ +var R1000ExecFromMaliciousSourceDescriptor = ruleengine.RuleDescriptor{ ID: R1000ID, Name: R1000Name, Description: "Detecting exec calls that are from malicious source like: /dev/shm, /proc/self", diff --git a/pkg/ruleengine/v1/r1001_exec_binary_not_in_base_image.go b/pkg/ruleengine/v1/r1001_exec_binary_not_in_base_image.go index 5f09e550..fa12dcb3 100644 --- a/pkg/ruleengine/v1/r1001_exec_binary_not_in_base_image.go +++ b/pkg/ruleengine/v1/r1001_exec_binary_not_in_base_image.go @@ -18,7 +18,7 @@ const ( R1001Name = "Exec Binary Not In Base Image" ) -var R1001ExecBinaryNotInBaseImageRuleDescriptor = RuleDescriptor{ +var R1001ExecBinaryNotInBaseImageRuleDescriptor = ruleengine.RuleDescriptor{ ID: R1001ID, Name: R1001Name, Description: "Detecting exec calls of binaries that are not included in the base image", diff --git a/pkg/ruleengine/v1/r1002_load_kernel_module.go b/pkg/ruleengine/v1/r1002_load_kernel_module.go index b50e1a91..28c17f25 100644 --- a/pkg/ruleengine/v1/r1002_load_kernel_module.go +++ b/pkg/ruleengine/v1/r1002_load_kernel_module.go @@ -17,7 +17,7 @@ const ( R1002Name = "Kernel Module Load" ) -var R1002LoadKernelModuleRuleDescriptor = RuleDescriptor{ +var R1002LoadKernelModuleRuleDescriptor = ruleengine.RuleDescriptor{ ID: R1002ID, Name: R1002Name, Description: "Detecting Kernel Module Load.", diff --git a/pkg/ruleengine/v1/r1003_malicious_ssh_connection.go b/pkg/ruleengine/v1/r1003_malicious_ssh_connection.go index c10f9f2a..18390290 100644 --- a/pkg/ruleengine/v1/r1003_malicious_ssh_connection.go +++ b/pkg/ruleengine/v1/r1003_malicious_ssh_connection.go @@ -25,7 +25,7 @@ const ( R1003Name = "Malicious SSH Connection" ) -var R1003MaliciousSSHConnectionRuleDescriptor = RuleDescriptor{ +var R1003MaliciousSSHConnectionRuleDescriptor = ruleengine.RuleDescriptor{ ID: R1003ID, Name: R1003Name, Description: "Detecting ssh connection to disallowed port", diff --git a/pkg/ruleengine/v1/r1004_exec_from_mount.go b/pkg/ruleengine/v1/r1004_exec_from_mount.go index 06b97958..abb93f1f 100644 --- a/pkg/ruleengine/v1/r1004_exec_from_mount.go +++ b/pkg/ruleengine/v1/r1004_exec_from_mount.go @@ -18,7 +18,7 @@ const ( R1004Name = "Exec from mount" ) -var R1004ExecFromMountRuleDescriptor = RuleDescriptor{ +var R1004ExecFromMountRuleDescriptor = ruleengine.RuleDescriptor{ ID: R1004ID, Name: R1004Name, Description: "Detecting exec calls from mounted paths.", diff --git a/pkg/ruleengine/v1/r1005_fileless_execution.go b/pkg/ruleengine/v1/r1005_fileless_execution.go index 8e63a613..96b4bd4e 100644 --- a/pkg/ruleengine/v1/r1005_fileless_execution.go +++ b/pkg/ruleengine/v1/r1005_fileless_execution.go @@ -18,7 +18,7 @@ const ( R1005Name = "Fileless Execution" ) -var R1005FilelessExecutionRuleDescriptor = RuleDescriptor{ +var R1005FilelessExecutionRuleDescriptor = ruleengine.RuleDescriptor{ ID: R1005ID, Name: R1005Name, Description: "Detecting Fileless Execution", diff --git a/pkg/ruleengine/v1/r1006_unshare_system_call.go b/pkg/ruleengine/v1/r1006_unshare_system_call.go index 974557cd..74885e34 100644 --- a/pkg/ruleengine/v1/r1006_unshare_system_call.go +++ b/pkg/ruleengine/v1/r1006_unshare_system_call.go @@ -17,7 +17,7 @@ const ( R1006Name = "Unshare System Call usage" ) -var R1006UnshareSyscallRuleDescriptor = RuleDescriptor{ +var R1006UnshareSyscallRuleDescriptor = ruleengine.RuleDescriptor{ ID: R1006ID, Name: R1006Name, Description: "Detecting Unshare System Call usage, which can be used to escape container.", diff --git a/pkg/ruleengine/v1/r1007_xmr_crypto_mining.go b/pkg/ruleengine/v1/r1007_xmr_crypto_mining.go index 64eb1121..ed59b016 100644 --- a/pkg/ruleengine/v1/r1007_xmr_crypto_mining.go +++ b/pkg/ruleengine/v1/r1007_xmr_crypto_mining.go @@ -17,7 +17,7 @@ const ( R1007Name = "XMR Crypto Mining Detection" ) -var R1007XMRCryptoMiningRuleDescriptor = RuleDescriptor{ +var R1007XMRCryptoMiningRuleDescriptor = ruleengine.RuleDescriptor{ ID: R1007ID, Name: R1007Name, Description: "Detecting XMR Crypto Miners by randomx algorithm usage.", diff --git a/pkg/ruleengine/v1/r1008_crypto_mining_domain.go b/pkg/ruleengine/v1/r1008_crypto_mining_domain.go index 9f9dd2f6..fb95b092 100644 --- a/pkg/ruleengine/v1/r1008_crypto_mining_domain.go +++ b/pkg/ruleengine/v1/r1008_crypto_mining_domain.go @@ -128,7 +128,7 @@ var commonlyUsedCryptoMinersDomains = []string{ "us.monero.herominers.com.", } -var R1008CryptoMiningDomainCommunicationRuleDescriptor = RuleDescriptor{ +var R1008CryptoMiningDomainCommunicationRuleDescriptor = ruleengine.RuleDescriptor{ ID: R1008ID, Name: R1008Name, Description: "Detecting Crypto miners communication by domain", diff --git a/pkg/ruleengine/v1/r1009_crypto_mining_port.go b/pkg/ruleengine/v1/r1009_crypto_mining_port.go index d69f493e..6c347167 100644 --- a/pkg/ruleengine/v1/r1009_crypto_mining_port.go +++ b/pkg/ruleengine/v1/r1009_crypto_mining_port.go @@ -22,7 +22,7 @@ var CommonlyUsedCryptoMinersPorts = []uint16{ 45700, // Monero (XMR) - Stratum mining protocol (TCP). (stratum+tcp://xmr.pool.minergate.com) } -var R1009CryptoMiningRelatedPortRuleDescriptor = RuleDescriptor{ +var R1009CryptoMiningRelatedPortRuleDescriptor = ruleengine.RuleDescriptor{ ID: R1009ID, Name: R1009Name, Description: "Detecting Crypto Miners by suspicious port usage.", diff --git a/pkg/ruleengine/v1/r1010_symlink_created_over_sensitive_file.go b/pkg/ruleengine/v1/r1010_symlink_created_over_sensitive_file.go index 7b575c90..898efe3b 100644 --- a/pkg/ruleengine/v1/r1010_symlink_created_over_sensitive_file.go +++ b/pkg/ruleengine/v1/r1010_symlink_created_over_sensitive_file.go @@ -21,7 +21,7 @@ const ( R1010Name = "Symlink Created Over Sensitive File" ) -var R1010SymlinkCreatedOverSensitiveFileRuleDescriptor = RuleDescriptor{ +var R1010SymlinkCreatedOverSensitiveFileRuleDescriptor = ruleengine.RuleDescriptor{ ID: R1010ID, Name: R1010Name, Description: "Detecting symlink creation over sensitive files.", diff --git a/pkg/ruleengine/v1/r1011_ld_preload_hook.go b/pkg/ruleengine/v1/r1011_ld_preload_hook.go index 86a1ccab..c20e4b46 100644 --- a/pkg/ruleengine/v1/r1011_ld_preload_hook.go +++ b/pkg/ruleengine/v1/r1011_ld_preload_hook.go @@ -25,7 +25,7 @@ const ( var LD_PRELOAD_ENV_VARS = []string{"LD_PRELOAD", "LD_AUDIT", "LD_LIBRARY_PATH"} -var R1011LdPreloadHookRuleDescriptor = RuleDescriptor{ +var R1011LdPreloadHookRuleDescriptor = ruleengine.RuleDescriptor{ ID: R1011ID, Name: R1011Name, Description: "Detecting ld_preload hook techniques.", diff --git a/pkg/ruleengine/v1/r1012_hardlink_created_over_sensitive_file.go b/pkg/ruleengine/v1/r1012_hardlink_created_over_sensitive_file.go index a6adedd1..b6868bc7 100644 --- a/pkg/ruleengine/v1/r1012_hardlink_created_over_sensitive_file.go +++ b/pkg/ruleengine/v1/r1012_hardlink_created_over_sensitive_file.go @@ -21,7 +21,7 @@ const ( R1012Name = "Hardlink Created Over Sensitive File" ) -var R1012HardlinkCreatedOverSensitiveFileRuleDescriptor = RuleDescriptor{ +var R1012HardlinkCreatedOverSensitiveFileRuleDescriptor = ruleengine.RuleDescriptor{ ID: R1012ID, Name: R1012Name, Description: "Detecting hardlink creation over sensitive files.", diff --git a/pkg/ruleengine/v1/rule.go b/pkg/ruleengine/v1/rule.go index 2a084263..8c198ab6 100644 --- a/pkg/ruleengine/v1/rule.go +++ b/pkg/ruleengine/v1/rule.go @@ -16,34 +16,6 @@ const ( RulePrioritySystemIssue = 1000 ) -type RuleDescriptor struct { - // Rule ID - ID string - // Rule Name - Name string - // Rule Description - Description string - // Priority - Priority int - // Tags - Tags []string - // Rule requirements - Requirements ruleengine.RuleSpec - // Create a rule function - RuleCreationFunc func() ruleengine.RuleEvaluator -} - -func (r *RuleDescriptor) HasTags(tags []string) bool { - for _, tag := range tags { - for _, ruleTag := range r.Tags { - if tag == ruleTag { - return true - } - } - } - return false -} - var _ ruleengine.RuleSpec = (*RuleRequirements)(nil) type RuleRequirements struct { From b37ebddd4ab9224ecd856f660969b5a2f566feb6 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 11 Sep 2024 08:01:24 +0000 Subject: [PATCH 03/23] Changing tracers to be mapset Signed-off-by: Amit Schendel --- .../container_watcher_interface.go | 2 +- .../container_watcher_mock.go | 2 +- pkg/containerwatcher/v1/container_watcher.go | 21 +++++++------------ .../v1/container_watcher_private.go | 4 ++-- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/pkg/containerwatcher/container_watcher_interface.go b/pkg/containerwatcher/container_watcher_interface.go index 5e8ab799..b73603aa 100644 --- a/pkg/containerwatcher/container_watcher_interface.go +++ b/pkg/containerwatcher/container_watcher_interface.go @@ -17,7 +17,7 @@ type ContainerWatcher interface { GetSocketEnricher() *socketenricher.SocketEnricher GetContainerSelector() *containercollection.ContainerSelector RegisterCustomTracer(tracer CustomTracer) error - UnregisterCustomTracer(tracerName string) error + UnregisterCustomTracer(tracer CustomTracer) error } type CustomTracer interface { diff --git a/pkg/containerwatcher/container_watcher_mock.go b/pkg/containerwatcher/container_watcher_mock.go index 472a3d73..83152d20 100644 --- a/pkg/containerwatcher/container_watcher_mock.go +++ b/pkg/containerwatcher/container_watcher_mock.go @@ -24,7 +24,7 @@ func (c ContainerWatcherMock) RegisterCustomTracer(_ CustomTracer) error { return nil } -func (c ContainerWatcherMock) UnregisterCustomTracer(_ string) error { +func (c ContainerWatcherMock) UnregisterCustomTracer(_ CustomTracer) error { return nil } diff --git a/pkg/containerwatcher/v1/container_watcher.go b/pkg/containerwatcher/v1/container_watcher.go index bd249c07..897bf4e7 100644 --- a/pkg/containerwatcher/v1/container_watcher.go +++ b/pkg/containerwatcher/v1/container_watcher.go @@ -104,7 +104,7 @@ type IGContainerWatcher struct { kubeIPInstance operators.OperatorInstance kubeNameInstance operators.OperatorInstance // Third party tracers - thirdPartyTracers []containerwatcher.CustomTracer + thirdPartyTracers mapset.Set[containerwatcher.CustomTracer] // Worker pools capabilitiesWorkerPool *ants.PoolWithFunc @@ -360,7 +360,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli timeBasedContainers: mapset.NewSet[string](), ruleManagedPods: mapset.NewSet[string](), runtime: runtime, - thirdPartyTracers: []containerwatcher.CustomTracer{}, + thirdPartyTracers: mapset.NewSet[containerwatcher.CustomTracer](), }, nil } @@ -381,26 +381,19 @@ func (ch *IGContainerWatcher) GetContainerSelector() *containercollection.Contai } func (ch *IGContainerWatcher) RegisterCustomTracer(tracer containerwatcher.CustomTracer) error { - for _, t := range ch.thirdPartyTracers { + for t := range ch.thirdPartyTracers.Iter() { if t.Name() == tracer.Name() { return fmt.Errorf("tracer with name %s already registered", tracer.Name()) } } - ch.thirdPartyTracers = append(ch.thirdPartyTracers, tracer) + ch.thirdPartyTracers.Add(tracer) return nil } -func (ch *IGContainerWatcher) UnregisterCustomTracer(name string) error { - for i, t := range ch.thirdPartyTracers { - if t.Name() == name { - // Remove the tracer from the slice - ch.thirdPartyTracers = append(ch.thirdPartyTracers[:i], ch.thirdPartyTracers[i+1:]...) - return nil - } - } - - return fmt.Errorf("tracer with name %s not found", name) +func (ch *IGContainerWatcher) UnregisterCustomTracer(tracer containerwatcher.CustomTracer) error { + ch.thirdPartyTracers.Remove(tracer) + return nil } func (ch *IGContainerWatcher) Start(ctx context.Context) error { diff --git a/pkg/containerwatcher/v1/container_watcher_private.go b/pkg/containerwatcher/v1/container_watcher_private.go index 7789382b..fc8351bf 100644 --- a/pkg/containerwatcher/v1/container_watcher_private.go +++ b/pkg/containerwatcher/v1/container_watcher_private.go @@ -269,7 +269,7 @@ func (ch *IGContainerWatcher) startTracers() error { } // Start third party tracers - for _, tracer := range ch.thirdPartyTracers { + for tracer := range ch.thirdPartyTracers.Iter() { if err := tracer.Start(); err != nil { logger.L().Error("error starting custom tracer", helpers.String("tracer", tracer.Name()), helpers.Error(err)) return err @@ -348,7 +348,7 @@ func (ch *IGContainerWatcher) stopTracers() error { } // Stop third party tracers - for _, tracer := range ch.thirdPartyTracers { + for tracer := range ch.thirdPartyTracers.Iter() { if err := tracer.Stop(); err != nil { logger.L().Error("error stopping custom tracer", helpers.String("tracer", tracer.Name()), helpers.Error(err)) errs = errors.Join(errs, err) From efcf95c12ef5a087d7014408a2f651d351055620 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 11 Sep 2024 13:06:22 +0000 Subject: [PATCH 04/23] Adding a k8s event interface to be able to pass all types of events Signed-off-by: Amit Schendel --- pkg/rulemanager/rule_manager_interface.go | 8 ++++++-- pkg/rulemanager/rule_manager_mock.go | 3 +-- pkg/rulemanager/v1/rule_manager.go | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pkg/rulemanager/rule_manager_interface.go b/pkg/rulemanager/rule_manager_interface.go index 4be952aa..1464eb7b 100644 --- a/pkg/rulemanager/rule_manager_interface.go +++ b/pkg/rulemanager/rule_manager_interface.go @@ -13,11 +13,15 @@ import ( tracerexectype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/exec/types" tracernetworktype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/network/types" traceropentype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/open/types" - eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types" v1 "k8s.io/api/core/v1" ) +type K8sEvent interface { + GetNamespace() string + GetPod() string +} + type RuleManagerClient interface { ContainerCallback(notif containercollection.PubSubEvent) RegisterPeekFunc(peek func(mntns uint64) ([]string, error)) @@ -30,7 +34,7 @@ type RuleManagerClient interface { ReportSymlinkEvent(event tracersymlinktype.Event) ReportHardlinkEvent(event tracerhardlinktype.Event) ReportSSHEvent(event tracersshtype.Event) - ReportEvent(eventType utils.EventType, event eventtypes.Event) + ReportEvent(eventType utils.EventType, event K8sEvent) HasApplicableRuleBindings(namespace, name string) bool HasFinalApplicationProfile(pod *v1.Pod) bool IsContainerMonitored(k8sContainerID string) bool diff --git a/pkg/rulemanager/rule_manager_mock.go b/pkg/rulemanager/rule_manager_mock.go index ac406b5f..73bf2110 100644 --- a/pkg/rulemanager/rule_manager_mock.go +++ b/pkg/rulemanager/rule_manager_mock.go @@ -13,7 +13,6 @@ import ( tracerexectype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/exec/types" tracernetworktype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/network/types" traceropentype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/open/types" - eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types" v1 "k8s.io/api/core/v1" ) @@ -70,7 +69,7 @@ func (r *RuleManagerMock) ReportSSHEvent(_ tracersshtype.Event) { // noop } -func (r *RuleManagerMock) ReportEvent(_ utils.EventType, _ eventtypes.Event) { +func (r *RuleManagerMock) ReportEvent(_ utils.EventType, _ K8sEvent) { // noop } diff --git a/pkg/rulemanager/v1/rule_manager.go b/pkg/rulemanager/v1/rule_manager.go index d632323d..f1c6f2ad 100644 --- a/pkg/rulemanager/v1/rule_manager.go +++ b/pkg/rulemanager/v1/rule_manager.go @@ -440,7 +440,7 @@ func (rm *RuleManager) ReportSSHEvent(event tracersshtype.Event) { rm.processEvent(utils.SSHEventType, &event, rules) } -func (rm *RuleManager) ReportEvent(eventType utils.EventType, event eventtypes.Event) { +func (rm *RuleManager) ReportEvent(eventType utils.EventType, event rulemanager.K8sEvent) { if event.GetNamespace() == "" || event.GetPod() == "" { logger.L().Error("RuleManager - failed to get namespace and pod name from custom event") return From d6672d6b12c3e7e05d41108114cfe6a3a11146a4 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 11 Sep 2024 13:23:13 +0000 Subject: [PATCH 05/23] Changing interface name Signed-off-by: Amit Schendel --- pkg/rulemanager/rule_manager_interface.go | 4 ++-- pkg/rulemanager/rule_manager_mock.go | 2 +- pkg/rulemanager/v1/rule_manager.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/rulemanager/rule_manager_interface.go b/pkg/rulemanager/rule_manager_interface.go index 1464eb7b..c749817a 100644 --- a/pkg/rulemanager/rule_manager_interface.go +++ b/pkg/rulemanager/rule_manager_interface.go @@ -17,7 +17,7 @@ import ( v1 "k8s.io/api/core/v1" ) -type K8sEvent interface { +type RuntimeK8sEvent interface { GetNamespace() string GetPod() string } @@ -34,7 +34,7 @@ type RuleManagerClient interface { ReportSymlinkEvent(event tracersymlinktype.Event) ReportHardlinkEvent(event tracerhardlinktype.Event) ReportSSHEvent(event tracersshtype.Event) - ReportEvent(eventType utils.EventType, event K8sEvent) + ReportEvent(eventType utils.EventType, event RuntimeK8sEvent) HasApplicableRuleBindings(namespace, name string) bool HasFinalApplicationProfile(pod *v1.Pod) bool IsContainerMonitored(k8sContainerID string) bool diff --git a/pkg/rulemanager/rule_manager_mock.go b/pkg/rulemanager/rule_manager_mock.go index 73bf2110..2f5c1872 100644 --- a/pkg/rulemanager/rule_manager_mock.go +++ b/pkg/rulemanager/rule_manager_mock.go @@ -69,7 +69,7 @@ func (r *RuleManagerMock) ReportSSHEvent(_ tracersshtype.Event) { // noop } -func (r *RuleManagerMock) ReportEvent(_ utils.EventType, _ K8sEvent) { +func (r *RuleManagerMock) ReportEvent(_ utils.EventType, _ RuntimeK8sEvent) { // noop } diff --git a/pkg/rulemanager/v1/rule_manager.go b/pkg/rulemanager/v1/rule_manager.go index f1c6f2ad..6b6750f1 100644 --- a/pkg/rulemanager/v1/rule_manager.go +++ b/pkg/rulemanager/v1/rule_manager.go @@ -440,7 +440,7 @@ func (rm *RuleManager) ReportSSHEvent(event tracersshtype.Event) { rm.processEvent(utils.SSHEventType, &event, rules) } -func (rm *RuleManager) ReportEvent(eventType utils.EventType, event rulemanager.K8sEvent) { +func (rm *RuleManager) ReportEvent(eventType utils.EventType, event rulemanager.RuntimeK8sEvent) { if event.GetNamespace() == "" || event.GetPod() == "" { logger.L().Error("RuleManager - failed to get namespace and pod name from custom event") return From 75edd63d7df64e8b9a68dd9f01d83358b093b5b6 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 11 Sep 2024 14:41:43 +0000 Subject: [PATCH 06/23] Adding an option to register for events and containers Signed-off-by: Amit Schendel --- main.go | 2 +- .../container_watcher_interface.go | 12 ++++ .../container_watcher_mock.go | 4 ++ pkg/containerwatcher/v1/container_watcher.go | 58 ++++++++++++++++++- .../v1/container_watcher_private.go | 4 ++ pkg/containerwatcher/v1/open_test.go | 2 +- 6 files changed, 79 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index bdc0b22b..9317358a 100644 --- a/main.go +++ b/main.go @@ -269,7 +269,7 @@ func main() { } // Create the container handler - mainHandler, err := containerwatcher.CreateIGContainerWatcher(cfg, applicationProfileManager, k8sClient, relevancyManager, networkManagerClient, dnsManagerClient, prometheusExporter, ruleManager, malwareManager, preRunningContainersIDs, &ruleBindingNotify, containerRuntime) + mainHandler, err := containerwatcher.CreateIGContainerWatcher(cfg, applicationProfileManager, k8sClient, relevancyManager, networkManagerClient, dnsManagerClient, prometheusExporter, ruleManager, malwareManager, preRunningContainersIDs, &ruleBindingNotify, containerRuntime, nil) if err != nil { logger.L().Ctx(ctx).Fatal("error creating the container watcher", helpers.Error(err)) } diff --git a/pkg/containerwatcher/container_watcher_interface.go b/pkg/containerwatcher/container_watcher_interface.go index b73603aa..3add1072 100644 --- a/pkg/containerwatcher/container_watcher_interface.go +++ b/pkg/containerwatcher/container_watcher_interface.go @@ -6,6 +6,8 @@ import ( containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" "github.com/inspektor-gadget/inspektor-gadget/pkg/socketenricher" tracercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/tracer-collection" + "github.com/kubescape/node-agent/pkg/rulemanager" + "github.com/kubescape/node-agent/pkg/utils" ) type ContainerWatcher interface { @@ -18,6 +20,8 @@ type ContainerWatcher interface { GetContainerSelector() *containercollection.ContainerSelector RegisterCustomTracer(tracer CustomTracer) error UnregisterCustomTracer(tracer CustomTracer) error + RegisterContainerReceiver(receiver ContainerReceiver) + UnregisterContainerReceiver(receiver ContainerReceiver) } type CustomTracer interface { @@ -25,3 +29,11 @@ type CustomTracer interface { Stop() error Name() string } + +type EventReceiver interface { + ReportEvent(eventType utils.EventType, event rulemanager.RuntimeK8sEvent) +} + +type ContainerReceiver interface { + ContainerCallback(notif containercollection.PubSubEvent) +} diff --git a/pkg/containerwatcher/container_watcher_mock.go b/pkg/containerwatcher/container_watcher_mock.go index 83152d20..66989e11 100644 --- a/pkg/containerwatcher/container_watcher_mock.go +++ b/pkg/containerwatcher/container_watcher_mock.go @@ -28,6 +28,10 @@ func (c ContainerWatcherMock) UnregisterCustomTracer(_ CustomTracer) error { return nil } +func (c ContainerWatcherMock) RegisterContainerReceiver(_ ContainerReceiver) {} + +func (c ContainerWatcherMock) UnregisterContainerReceiver(_ ContainerReceiver) {} + func (c ContainerWatcherMock) GetTracerCollection() *tracercollection.TracerCollection { return nil } diff --git a/pkg/containerwatcher/v1/container_watcher.go b/pkg/containerwatcher/v1/container_watcher.go index 897bf4e7..a6ae96b5 100644 --- a/pkg/containerwatcher/v1/container_watcher.go +++ b/pkg/containerwatcher/v1/container_watcher.go @@ -6,6 +6,7 @@ import ( "os" mapset "github.com/deckarep/golang-set/v2" + "github.com/goradd/maps" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" containerutilsTypes "github.com/inspektor-gadget/inspektor-gadget/pkg/container-utils/types" tracerseccomp "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/advise/seccomp/tracer" @@ -105,6 +106,8 @@ type IGContainerWatcher struct { kubeNameInstance operators.OperatorInstance // Third party tracers thirdPartyTracers mapset.Set[containerwatcher.CustomTracer] + // Third party container receivers + thirdPartyContainerReceivers mapset.Set[containerwatcher.ContainerReceiver] // Worker pools capabilitiesWorkerPool *ants.PoolWithFunc @@ -139,7 +142,7 @@ type IGContainerWatcher struct { var _ containerwatcher.ContainerWatcher = (*IGContainerWatcher)(nil) -func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager applicationprofilemanager.ApplicationProfileManagerClient, k8sClient *k8sinterface.KubernetesApi, relevancyManager relevancymanager.RelevancyManagerClient, networkManagerClient networkmanager.NetworkManagerClient, dnsManagerClient dnsmanager.DNSManagerClient, metrics metricsmanager.MetricsManager, ruleManager rulemanager.RuleManagerClient, malwareManager malwaremanager.MalwareManagerClient, preRunningContainers mapset.Set[string], ruleBindingPodNotify *chan rulebinding.RuleBindingNotify, runtime *containerutilsTypes.RuntimeConfig) (*IGContainerWatcher, error) { +func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager applicationprofilemanager.ApplicationProfileManagerClient, k8sClient *k8sinterface.KubernetesApi, relevancyManager relevancymanager.RelevancyManagerClient, networkManagerClient networkmanager.NetworkManagerClient, dnsManagerClient dnsmanager.DNSManagerClient, metrics metricsmanager.MetricsManager, ruleManager rulemanager.RuleManagerClient, malwareManager malwaremanager.MalwareManagerClient, preRunningContainers mapset.Set[string], ruleBindingPodNotify *chan rulebinding.RuleBindingNotify, runtime *containerutilsTypes.RuntimeConfig, thirdPartyEventReceivers *maps.SafeMap[utils.EventType, mapset.Set[containerwatcher.EventReceiver]]) (*IGContainerWatcher, error) { // Use container collection to get notified for new containers containerCollection := &containercollection.ContainerCollection{} // Create a tracer collection instance @@ -158,6 +161,11 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli k8sContainerID := utils.CreateK8sContainerID(event.K8s.Namespace, event.K8s.PodName, event.K8s.ContainerName) applicationProfileManager.ReportCapability(k8sContainerID, event.CapName) ruleManager.ReportCapability(event) + + // Report capabilities to event receivers + for receiver := range thirdPartyEventReceivers.Get(utils.CapabilitiesEventType).Iter() { + receiver.ReportEvent(utils.CapabilitiesEventType, &event) + } }) if err != nil { return nil, fmt.Errorf("creating capabilities worker pool: %w", err) @@ -186,6 +194,11 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli relevancyManager.ReportFileExec(event.Runtime.ContainerID, k8sContainerID, path) ruleManager.ReportFileExec(event) malwareManager.ReportFileExec(k8sContainerID, event) + + // Report exec events to event receivers + for receiver := range thirdPartyEventReceivers.Get(utils.ExecveEventType).Iter() { + receiver.ReportEvent(utils.ExecveEventType, &event) + } }) if err != nil { return nil, fmt.Errorf("creating exec worker pool: %w", err) @@ -214,6 +227,11 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli relevancyManager.ReportFileOpen(event.Runtime.ContainerID, k8sContainerID, path) ruleManager.ReportFileOpen(event) malwareManager.ReportFileOpen(k8sContainerID, event) + + // Report open events to event receivers + for receiver := range thirdPartyEventReceivers.Get(utils.OpenEventType).Iter() { + receiver.ReportEvent(utils.OpenEventType, &event) + } }) if err != nil { return nil, fmt.Errorf("creating open worker pool: %w", err) @@ -234,6 +252,11 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli metrics.ReportEvent(utils.NetworkEventType) networkManagerClient.ReportNetworkEvent(k8sContainerID, event) ruleManager.ReportNetworkEvent(event) + + // Report network events to event receivers + for receiver := range thirdPartyEventReceivers.Get(utils.NetworkEventType).Iter() { + receiver.ReportEvent(utils.NetworkEventType, &event) + } }) if err != nil { return nil, fmt.Errorf("creating network worker pool: %w", err) @@ -259,6 +282,11 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli metrics.ReportEvent(utils.DnsEventType) dnsManagerClient.ReportDNSEvent(event) ruleManager.ReportDNSEvent(event) + + // Report DNS events to event receivers + for receiver := range thirdPartyEventReceivers.Get(utils.DnsEventType).Iter() { + receiver.ReportEvent(utils.DnsEventType, &event) + } }) if err != nil { return nil, fmt.Errorf("creating dns worker pool: %w", err) @@ -271,6 +299,11 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli } metrics.ReportEvent(utils.RandomXEventType) ruleManager.ReportRandomxEvent(event) + + // Report randomx events to event receivers + for receiver := range thirdPartyEventReceivers.Get(utils.RandomXEventType).Iter() { + receiver.ReportEvent(utils.RandomXEventType, &event) + } }) if err != nil { return nil, fmt.Errorf("creating randomx worker pool: %w", err) @@ -283,6 +316,11 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli } metrics.ReportEvent(utils.SymlinkEventType) ruleManager.ReportSymlinkEvent(event) + + // Report symlink events to event receivers + for receiver := range thirdPartyEventReceivers.Get(utils.SymlinkEventType).Iter() { + receiver.ReportEvent(utils.SymlinkEventType, &event) + } }) if err != nil { return nil, fmt.Errorf("creating symlink worker pool: %w", err) @@ -295,6 +333,11 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli } metrics.ReportEvent(utils.HardlinkEventType) ruleManager.ReportHardlinkEvent(event) + + // Report hardlink events to event receivers + for receiver := range thirdPartyEventReceivers.Get(utils.HardlinkEventType).Iter() { + receiver.ReportEvent(utils.HardlinkEventType, &event) + } }) if err != nil { return nil, fmt.Errorf("creating hardlink worker pool: %w", err) @@ -307,6 +350,11 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli } metrics.ReportEvent(utils.SSHEventType) ruleManager.ReportSSHEvent(event) + + // Report ssh events to event receivers + for receiver := range thirdPartyEventReceivers.Get(utils.SSHEventType).Iter() { + receiver.ReportEvent(utils.SSHEventType, &event) + } }) if err != nil { return nil, fmt.Errorf("creating ssh worker pool: %w", err) @@ -396,6 +444,14 @@ func (ch *IGContainerWatcher) UnregisterCustomTracer(tracer containerwatcher.Cus return nil } +func (ch *IGContainerWatcher) RegisterContainerReceiver(receiver containerwatcher.ContainerReceiver) { + ch.thirdPartyContainerReceivers.Add(receiver) +} + +func (ch *IGContainerWatcher) UnregisterContainerReceiver(receiver containerwatcher.ContainerReceiver) { + ch.thirdPartyContainerReceivers.Remove(receiver) +} + func (ch *IGContainerWatcher) Start(ctx context.Context) error { if !ch.running { diff --git a/pkg/containerwatcher/v1/container_watcher_private.go b/pkg/containerwatcher/v1/container_watcher_private.go index fc8351bf..6f2a4b65 100644 --- a/pkg/containerwatcher/v1/container_watcher_private.go +++ b/pkg/containerwatcher/v1/container_watcher_private.go @@ -89,6 +89,10 @@ func (ch *IGContainerWatcher) startContainerCollection(ctx context.Context) erro ch.ruleManager.ContainerCallback, } + for receiver := range ch.thirdPartyContainerReceivers.Iter() { + containerEventFuncs = append(containerEventFuncs, receiver.ContainerCallback) + } + // Define the different options for the container collection instance opts := []containercollection.ContainerCollectionOption{ // Get Notifications from the container collection diff --git a/pkg/containerwatcher/v1/open_test.go b/pkg/containerwatcher/v1/open_test.go index 65d05237..7c91dd6f 100644 --- a/pkg/containerwatcher/v1/open_test.go +++ b/pkg/containerwatcher/v1/open_test.go @@ -23,7 +23,7 @@ func BenchmarkIGContainerWatcher_openEventCallback(b *testing.B) { assert.NoError(b, err) mockExporter := metricsmanager.NewMetricsMock() - mainHandler, err := CreateIGContainerWatcher(cfg, nil, nil, relevancyManager, nil, nil, mockExporter, nil, nil, nil, nil, nil) + mainHandler, err := CreateIGContainerWatcher(cfg, nil, nil, relevancyManager, nil, nil, mockExporter, nil, nil, nil, nil, nil, nil) assert.NoError(b, err) event := &traceropentype.Event{ Event: types.Event{ From 759bbdd612d92f4d8fc80396dd9a9041a1da5463 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 11 Sep 2024 14:45:38 +0000 Subject: [PATCH 07/23] Fixing types Signed-off-by: Amit Schendel --- pkg/containerwatcher/v1/container_watcher.go | 54 +++++++++++++------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/pkg/containerwatcher/v1/container_watcher.go b/pkg/containerwatcher/v1/container_watcher.go index a6ae96b5..4bcd6cb2 100644 --- a/pkg/containerwatcher/v1/container_watcher.go +++ b/pkg/containerwatcher/v1/container_watcher.go @@ -163,8 +163,10 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportCapability(event) // Report capabilities to event receivers - for receiver := range thirdPartyEventReceivers.Get(utils.CapabilitiesEventType).Iter() { - receiver.ReportEvent(utils.CapabilitiesEventType, &event) + if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.CapabilitiesEventType) { + for receiver := range thirdPartyEventReceivers.Get(utils.CapabilitiesEventType).Iter() { + receiver.ReportEvent(utils.CapabilitiesEventType, &event) + } } }) if err != nil { @@ -196,8 +198,10 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli malwareManager.ReportFileExec(k8sContainerID, event) // Report exec events to event receivers - for receiver := range thirdPartyEventReceivers.Get(utils.ExecveEventType).Iter() { - receiver.ReportEvent(utils.ExecveEventType, &event) + if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.ExecveEventType) { + for receiver := range thirdPartyEventReceivers.Get(utils.ExecveEventType).Iter() { + receiver.ReportEvent(utils.ExecveEventType, &event) + } } }) if err != nil { @@ -229,8 +233,10 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli malwareManager.ReportFileOpen(k8sContainerID, event) // Report open events to event receivers - for receiver := range thirdPartyEventReceivers.Get(utils.OpenEventType).Iter() { - receiver.ReportEvent(utils.OpenEventType, &event) + if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.OpenEventType) { + for receiver := range thirdPartyEventReceivers.Get(utils.OpenEventType).Iter() { + receiver.ReportEvent(utils.OpenEventType, &event) + } } }) if err != nil { @@ -254,8 +260,10 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportNetworkEvent(event) // Report network events to event receivers - for receiver := range thirdPartyEventReceivers.Get(utils.NetworkEventType).Iter() { - receiver.ReportEvent(utils.NetworkEventType, &event) + if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.NetworkEventType) { + for receiver := range thirdPartyEventReceivers.Get(utils.NetworkEventType).Iter() { + receiver.ReportEvent(utils.NetworkEventType, &event) + } } }) if err != nil { @@ -284,8 +292,10 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportDNSEvent(event) // Report DNS events to event receivers - for receiver := range thirdPartyEventReceivers.Get(utils.DnsEventType).Iter() { - receiver.ReportEvent(utils.DnsEventType, &event) + if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.DnsEventType) { + for receiver := range thirdPartyEventReceivers.Get(utils.DnsEventType).Iter() { + receiver.ReportEvent(utils.DnsEventType, &event) + } } }) if err != nil { @@ -301,8 +311,10 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportRandomxEvent(event) // Report randomx events to event receivers - for receiver := range thirdPartyEventReceivers.Get(utils.RandomXEventType).Iter() { - receiver.ReportEvent(utils.RandomXEventType, &event) + if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.RandomXEventType) { + for receiver := range thirdPartyEventReceivers.Get(utils.RandomXEventType).Iter() { + receiver.ReportEvent(utils.RandomXEventType, &event) + } } }) if err != nil { @@ -318,8 +330,10 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportSymlinkEvent(event) // Report symlink events to event receivers - for receiver := range thirdPartyEventReceivers.Get(utils.SymlinkEventType).Iter() { - receiver.ReportEvent(utils.SymlinkEventType, &event) + if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.SymlinkEventType) { + for receiver := range thirdPartyEventReceivers.Get(utils.SymlinkEventType).Iter() { + receiver.ReportEvent(utils.SymlinkEventType, &event) + } } }) if err != nil { @@ -335,8 +349,10 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportHardlinkEvent(event) // Report hardlink events to event receivers - for receiver := range thirdPartyEventReceivers.Get(utils.HardlinkEventType).Iter() { - receiver.ReportEvent(utils.HardlinkEventType, &event) + if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.HardlinkEventType) { + for receiver := range thirdPartyEventReceivers.Get(utils.HardlinkEventType).Iter() { + receiver.ReportEvent(utils.HardlinkEventType, &event) + } } }) if err != nil { @@ -352,8 +368,10 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportSSHEvent(event) // Report ssh events to event receivers - for receiver := range thirdPartyEventReceivers.Get(utils.SSHEventType).Iter() { - receiver.ReportEvent(utils.SSHEventType, &event) + if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.SSHEventType) { + for receiver := range thirdPartyEventReceivers.Get(utils.SSHEventType).Iter() { + receiver.ReportEvent(utils.SSHEventType, &event) + } } }) if err != nil { From b1b3f849bc1bfa55f24f3f4367e7019fd5683846 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 11 Sep 2024 14:58:13 +0000 Subject: [PATCH 08/23] Fixing nil deref Signed-off-by: Amit Schendel --- pkg/containerwatcher/v1/container_watcher.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pkg/containerwatcher/v1/container_watcher.go b/pkg/containerwatcher/v1/container_watcher.go index 4bcd6cb2..cec6df63 100644 --- a/pkg/containerwatcher/v1/container_watcher.go +++ b/pkg/containerwatcher/v1/container_watcher.go @@ -422,11 +422,12 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli sshWorkerChan: make(chan *tracersshtype.Event, 1000), // cache - ruleBindingPodNotify: ruleBindingPodNotify, - timeBasedContainers: mapset.NewSet[string](), - ruleManagedPods: mapset.NewSet[string](), - runtime: runtime, - thirdPartyTracers: mapset.NewSet[containerwatcher.CustomTracer](), + ruleBindingPodNotify: ruleBindingPodNotify, + timeBasedContainers: mapset.NewSet[string](), + ruleManagedPods: mapset.NewSet[string](), + runtime: runtime, + thirdPartyTracers: mapset.NewSet[containerwatcher.CustomTracer](), + thirdPartyContainerReceivers: mapset.NewSet[containerwatcher.ContainerReceiver](), }, nil } From 65070731a2c0b5819addc15b0c1fccb17ee706be Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Thu, 12 Sep 2024 07:57:14 +0000 Subject: [PATCH 09/23] Unite interfaces Signed-off-by: Amit Schendel --- .../container_watcher_interface.go | 3 +- pkg/containerwatcher/v1/container_watcher.go | 22 ++-- .../malware_manager_interface.go | 5 +- pkg/malwaremanager/malwaremanager_mock.go | 9 +- pkg/malwaremanager/v1/malware_manager.go | 23 +++- pkg/rulemanager/rule_manager_interface.go | 25 +--- pkg/rulemanager/rule_manager_mock.go | 47 +------ pkg/rulemanager/v1/rule_manager.go | 121 +----------------- pkg/utils/events.go | 5 + 9 files changed, 44 insertions(+), 216 deletions(-) diff --git a/pkg/containerwatcher/container_watcher_interface.go b/pkg/containerwatcher/container_watcher_interface.go index 3add1072..1df0f17b 100644 --- a/pkg/containerwatcher/container_watcher_interface.go +++ b/pkg/containerwatcher/container_watcher_interface.go @@ -6,7 +6,6 @@ import ( containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" "github.com/inspektor-gadget/inspektor-gadget/pkg/socketenricher" tracercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/tracer-collection" - "github.com/kubescape/node-agent/pkg/rulemanager" "github.com/kubescape/node-agent/pkg/utils" ) @@ -31,7 +30,7 @@ type CustomTracer interface { } type EventReceiver interface { - ReportEvent(eventType utils.EventType, event rulemanager.RuntimeK8sEvent) + ReportEvent(eventType utils.EventType, event utils.RuntimeK8sEvent) } type ContainerReceiver interface { diff --git a/pkg/containerwatcher/v1/container_watcher.go b/pkg/containerwatcher/v1/container_watcher.go index cec6df63..8ab68c6a 100644 --- a/pkg/containerwatcher/v1/container_watcher.go +++ b/pkg/containerwatcher/v1/container_watcher.go @@ -160,7 +160,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli metrics.ReportEvent(utils.CapabilitiesEventType) k8sContainerID := utils.CreateK8sContainerID(event.K8s.Namespace, event.K8s.PodName, event.K8s.ContainerName) applicationProfileManager.ReportCapability(k8sContainerID, event.CapName) - ruleManager.ReportCapability(event) + ruleManager.ReportEvent(utils.CapabilitiesEventType, &event) // Report capabilities to event receivers if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.CapabilitiesEventType) { @@ -194,8 +194,8 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli metrics.ReportEvent(utils.ExecveEventType) applicationProfileManager.ReportFileExec(k8sContainerID, path, event.Args) relevancyManager.ReportFileExec(event.Runtime.ContainerID, k8sContainerID, path) - ruleManager.ReportFileExec(event) - malwareManager.ReportFileExec(k8sContainerID, event) + ruleManager.ReportEvent(utils.ExecveEventType, &event) + malwareManager.ReportEvent(utils.ExecveEventType, &event) // Report exec events to event receivers if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.ExecveEventType) { @@ -229,8 +229,8 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli metrics.ReportEvent(utils.OpenEventType) applicationProfileManager.ReportFileOpen(k8sContainerID, path, event.Flags) relevancyManager.ReportFileOpen(event.Runtime.ContainerID, k8sContainerID, path) - ruleManager.ReportFileOpen(event) - malwareManager.ReportFileOpen(k8sContainerID, event) + ruleManager.ReportEvent(utils.OpenEventType, &event) + malwareManager.ReportEvent(utils.OpenEventType, &event) // Report open events to event receivers if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.OpenEventType) { @@ -257,7 +257,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli } metrics.ReportEvent(utils.NetworkEventType) networkManagerClient.ReportNetworkEvent(k8sContainerID, event) - ruleManager.ReportNetworkEvent(event) + ruleManager.ReportEvent(utils.NetworkEventType, &event) // Report network events to event receivers if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.NetworkEventType) { @@ -289,7 +289,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli metrics.ReportEvent(utils.DnsEventType) dnsManagerClient.ReportDNSEvent(event) - ruleManager.ReportDNSEvent(event) + ruleManager.ReportEvent(utils.DnsEventType, &event) // Report DNS events to event receivers if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.DnsEventType) { @@ -308,7 +308,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli return } metrics.ReportEvent(utils.RandomXEventType) - ruleManager.ReportRandomxEvent(event) + ruleManager.ReportEvent(utils.RandomXEventType, &event) // Report randomx events to event receivers if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.RandomXEventType) { @@ -327,7 +327,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli return } metrics.ReportEvent(utils.SymlinkEventType) - ruleManager.ReportSymlinkEvent(event) + ruleManager.ReportEvent(utils.SymlinkEventType, &event) // Report symlink events to event receivers if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.SymlinkEventType) { @@ -346,7 +346,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli return } metrics.ReportEvent(utils.HardlinkEventType) - ruleManager.ReportHardlinkEvent(event) + ruleManager.ReportEvent(utils.HardlinkEventType, &event) // Report hardlink events to event receivers if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.HardlinkEventType) { @@ -365,7 +365,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli return } metrics.ReportEvent(utils.SSHEventType) - ruleManager.ReportSSHEvent(event) + ruleManager.ReportEvent(utils.SSHEventType, &event) // Report ssh events to event receivers if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.SSHEventType) { diff --git a/pkg/malwaremanager/malware_manager_interface.go b/pkg/malwaremanager/malware_manager_interface.go index 40653c93..5e82c8c1 100644 --- a/pkg/malwaremanager/malware_manager_interface.go +++ b/pkg/malwaremanager/malware_manager_interface.go @@ -5,14 +5,11 @@ import ( apitypes "github.com/armosec/armoapi-go/armotypes" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" - tracerexectype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/exec/types" - traceropentype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/open/types" igtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types" ) type MalwareManagerClient interface { - ReportFileExec(k8sContainerID string, event tracerexectype.Event) - ReportFileOpen(k8sContainerID string, event traceropentype.Event) + ReportEvent(eventType utils.EventType, event utils.RuntimeK8sEvent) ContainerCallback(notif containercollection.PubSubEvent) } diff --git a/pkg/malwaremanager/malwaremanager_mock.go b/pkg/malwaremanager/malwaremanager_mock.go index ccb6fac4..84c86519 100644 --- a/pkg/malwaremanager/malwaremanager_mock.go +++ b/pkg/malwaremanager/malwaremanager_mock.go @@ -2,8 +2,7 @@ package malwaremanager import ( containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" - tracerexectype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/exec/types" - traceropentype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/open/types" + "github.com/kubescape/node-agent/pkg/utils" ) type MalwareManagerMock struct { @@ -15,11 +14,7 @@ func CreateMalwareManagerMock() *MalwareManagerMock { return &MalwareManagerMock{} } -func (r MalwareManagerMock) ReportFileExec(_ string, _ tracerexectype.Event) { - // noop -} - -func (r MalwareManagerMock) ReportFileOpen(_ string, _ traceropentype.Event) { +func (r MalwareManagerMock) ReportEvent(_ utils.EventType, _ utils.RuntimeK8sEvent) { // noop } diff --git a/pkg/malwaremanager/v1/malware_manager.go b/pkg/malwaremanager/v1/malware_manager.go index e7a0ec1d..d5fa3c3d 100644 --- a/pkg/malwaremanager/v1/malware_manager.go +++ b/pkg/malwaremanager/v1/malware_manager.go @@ -143,7 +143,26 @@ func (mm *MalwareManager) getWorkloadIdentifier(podNamespace, podName string) (s return generatedWlid, nil } -func (mm *MalwareManager) ReportFileExec(_ string, event tracerexectype.Event) { +func (mm *MalwareManager) ReportEvent(eventType utils.EventType, event utils.RuntimeK8sEvent) { + switch eventType { + case utils.ExecveEventType: + exec, ok := event.(*tracerexectype.Event) + if !ok { + logger.L().Error("MalwareManager - failed to cast event to execve event") + return + } + mm.reportFileExec(exec) + case utils.OpenEventType: + open, ok := event.(*traceropentype.Event) + if !ok { + logger.L().Error("MalwareManager - failed to cast event to open event") + return + } + mm.reportFileOpen(open) + } +} + +func (mm *MalwareManager) reportFileExec(event *tracerexectype.Event) { for _, scanner := range mm.malwareScanners { if result := scanner.Scan(utils.ExecveEventType, &event, mm.containerIdToPid.Get(event.Runtime.ContainerID)); result != nil { result = mm.enrichMalwareResult(result) @@ -162,7 +181,7 @@ func (mm *MalwareManager) ReportFileExec(_ string, event tracerexectype.Event) { } } -func (mm *MalwareManager) ReportFileOpen(_ string, event traceropentype.Event) { +func (mm *MalwareManager) reportFileOpen(event *traceropentype.Event) { // TODO: Add a check if the file is being opened for read. // Skip directories. diff --git a/pkg/rulemanager/rule_manager_interface.go b/pkg/rulemanager/rule_manager_interface.go index c749817a..e26f9b2b 100644 --- a/pkg/rulemanager/rule_manager_interface.go +++ b/pkg/rulemanager/rule_manager_interface.go @@ -1,40 +1,17 @@ package rulemanager import ( - tracerhardlinktype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/hardlink/types" - tracerrandomxtype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/randomx/types" - tracersshtype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/ssh/types" - tracersymlinktype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/symlink/types" "github.com/kubescape/node-agent/pkg/utils" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" - tracercapabilitiestype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/capabilities/types" - tracerdnstype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/dns/types" - tracerexectype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/exec/types" - tracernetworktype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/network/types" - traceropentype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/open/types" v1 "k8s.io/api/core/v1" ) -type RuntimeK8sEvent interface { - GetNamespace() string - GetPod() string -} - type RuleManagerClient interface { ContainerCallback(notif containercollection.PubSubEvent) RegisterPeekFunc(peek func(mntns uint64) ([]string, error)) - ReportCapability(event tracercapabilitiestype.Event) - ReportFileExec(event tracerexectype.Event) - ReportFileOpen(event traceropentype.Event) - ReportNetworkEvent(event tracernetworktype.Event) - ReportDNSEvent(event tracerdnstype.Event) - ReportRandomxEvent(event tracerrandomxtype.Event) - ReportSymlinkEvent(event tracersymlinktype.Event) - ReportHardlinkEvent(event tracerhardlinktype.Event) - ReportSSHEvent(event tracersshtype.Event) - ReportEvent(eventType utils.EventType, event RuntimeK8sEvent) + ReportEvent(eventType utils.EventType, event utils.RuntimeK8sEvent) HasApplicableRuleBindings(namespace, name string) bool HasFinalApplicationProfile(pod *v1.Pod) bool IsContainerMonitored(k8sContainerID string) bool diff --git a/pkg/rulemanager/rule_manager_mock.go b/pkg/rulemanager/rule_manager_mock.go index 2f5c1872..d8b4a965 100644 --- a/pkg/rulemanager/rule_manager_mock.go +++ b/pkg/rulemanager/rule_manager_mock.go @@ -1,18 +1,9 @@ package rulemanager import ( - tracerhardlinktype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/hardlink/types" - tracerrandomxtype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/randomx/types" - tracersshtype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/ssh/types" - tracersymlinktype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/symlink/types" "github.com/kubescape/node-agent/pkg/utils" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" - tracercapabilitiestype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/capabilities/types" - tracerdnstype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/dns/types" - tracerexectype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/exec/types" - tracernetworktype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/network/types" - traceropentype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/open/types" v1 "k8s.io/api/core/v1" ) @@ -33,43 +24,7 @@ func (r *RuleManagerMock) RegisterPeekFunc(_ func(mntns uint64) ([]string, error // noop } -func (r *RuleManagerMock) ReportCapability(_ tracercapabilitiestype.Event) { - // noop -} - -func (r *RuleManagerMock) ReportFileExec(_ tracerexectype.Event) { - // noop -} - -func (r *RuleManagerMock) ReportFileOpen(_ traceropentype.Event) { - // noop -} - -func (r *RuleManagerMock) ReportNetworkEvent(_ tracernetworktype.Event) { - // noop -} - -func (r *RuleManagerMock) ReportDNSEvent(_ tracerdnstype.Event) { - // noop -} - -func (r *RuleManagerMock) ReportRandomxEvent(_ tracerrandomxtype.Event) { - // noop -} - -func (r *RuleManagerMock) ReportSymlinkEvent(_ tracersymlinktype.Event) { - // noop -} - -func (r *RuleManagerMock) ReportHardlinkEvent(_ tracerhardlinktype.Event) { - // noop -} - -func (r *RuleManagerMock) ReportSSHEvent(_ tracersshtype.Event) { - // noop -} - -func (r *RuleManagerMock) ReportEvent(_ utils.EventType, _ RuntimeK8sEvent) { +func (r *RuleManagerMock) ReportEvent(_ utils.EventType, _ utils.RuntimeK8sEvent) { // noop } diff --git a/pkg/rulemanager/v1/rule_manager.go b/pkg/rulemanager/v1/rule_manager.go index 6b6750f1..70079054 100644 --- a/pkg/rulemanager/v1/rule_manager.go +++ b/pkg/rulemanager/v1/rule_manager.go @@ -26,20 +26,11 @@ import ( "github.com/kubescape/node-agent/pkg/metricsmanager" "github.com/kubescape/node-agent/pkg/objectcache" - tracerhardlinktype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/hardlink/types" - tracerrandomxtype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/randomx/types" - tracersshtype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/ssh/types" - tracersymlinktype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/symlink/types" ruleenginetypes "github.com/kubescape/node-agent/pkg/ruleengine/types" mapset "github.com/deckarep/golang-set/v2" "github.com/goradd/maps" containercollection "github.com/inspektor-gadget/inspektor-gadget/pkg/container-collection" - tracercapabilitiestype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/capabilities/types" - tracerdnstype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/dns/types" - tracerexectype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/exec/types" - tracernetworktype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/network/types" - traceropentype "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/open/types" eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -330,117 +321,7 @@ func (rm *RuleManager) RegisterPeekFunc(peek func(mntns uint64) ([]string, error rm.syscallPeekFunc = peek } -func (rm *RuleManager) ReportCapability(event tracercapabilitiestype.Event) { - if event.GetNamespace() == "" || event.GetPod() == "" { - logger.L().Error("RuleManager - failed to get namespace and pod name from ReportCapability event") - return - } - - // list capability rules - rules := rm.ruleBindingCache.ListRulesForPod(event.GetNamespace(), event.GetPod()) - - rm.processEvent(utils.CapabilitiesEventType, &event, rules) -} - -func (rm *RuleManager) ReportFileExec(event tracerexectype.Event) { - if event.GetNamespace() == "" || event.GetPod() == "" { - logger.L().Error("RuleManager - failed to get namespace and pod name from ReportFileExec event") - return - } - - // list exec rules - rules := rm.ruleBindingCache.ListRulesForPod(event.GetNamespace(), event.GetPod()) - rm.processEvent(utils.ExecveEventType, &event, rules) -} - -func (rm *RuleManager) ReportFileOpen(event traceropentype.Event) { - if event.GetNamespace() == "" || event.GetPod() == "" { - logger.L().Error("RuleManager - failed to get namespace and pod name from ReportFileOpen event") - return - } - - // list open rules - rules := rm.ruleBindingCache.ListRulesForPod(event.GetNamespace(), event.GetPod()) - - rm.processEvent(utils.OpenEventType, &event, rules) - -} - -func (rm *RuleManager) ReportNetworkEvent(event tracernetworktype.Event) { - if event.GetNamespace() == "" || event.GetPod() == "" { - logger.L().Error("RuleManager - failed to get namespace and pod name from ReportNetworkEvent event") - return - } - - // list network rules - rules := rm.ruleBindingCache.ListRulesForPod(event.GetNamespace(), event.GetPod()) - - rm.processEvent(utils.NetworkEventType, &event, rules) -} - -func (rm *RuleManager) ReportDNSEvent(event tracerdnstype.Event) { - // ignore events with empty container name - if event.K8s.ContainerName == "" { - return - } - - if event.GetNamespace() == "" || event.GetPod() == "" { - logger.L().Error("RuleManager - failed to get namespace and pod name from ReportDNSEvent event") - return - } - - // list dns rules - rules := rm.ruleBindingCache.ListRulesForPod(event.GetNamespace(), event.GetPod()) - - rm.processEvent(utils.DnsEventType, &event, rules) -} - -func (rm *RuleManager) ReportRandomxEvent(event tracerrandomxtype.Event) { - if event.GetNamespace() == "" || event.GetPod() == "" { - logger.L().Error("RuleManager - failed to get namespace and pod name from randomx event") - return - } - - // list randomx rules - rules := rm.ruleBindingCache.ListRulesForPod(event.GetNamespace(), event.GetPod()) - - rm.processEvent(utils.RandomXEventType, &event, rules) -} - -func (rm *RuleManager) ReportSymlinkEvent(event tracersymlinktype.Event) { - if event.GetNamespace() == "" || event.GetPod() == "" { - logger.L().Error("RuleManager - failed to get namespace and pod name from ReportSymlinkEvent event") - return - } - - // list symlink rules - rules := rm.ruleBindingCache.ListRulesForPod(event.GetNamespace(), event.GetPod()) - rm.processEvent(utils.SymlinkEventType, &event, rules) -} - -func (rm *RuleManager) ReportHardlinkEvent(event tracerhardlinktype.Event) { - if event.GetNamespace() == "" || event.GetPod() == "" { - logger.L().Error("RuleManager - failed to get namespace and pod name from ReportHardlinkEvent event") - return - } - - // list hardlink rules - rules := rm.ruleBindingCache.ListRulesForPod(event.GetNamespace(), event.GetPod()) - rm.processEvent(utils.HardlinkEventType, &event, rules) -} - -func (rm *RuleManager) ReportSSHEvent(event tracersshtype.Event) { - if event.GetNamespace() == "" || event.GetPod() == "" { - logger.L().Error("RuleManager - failed to get namespace and pod name from ReportSSHEvent event") - return - } - - // list ssh rules - rules := rm.ruleBindingCache.ListRulesForPod(event.GetNamespace(), event.GetPod()) - rm.processEvent(utils.SSHEventType, &event, rules) -} - -func (rm *RuleManager) ReportEvent(eventType utils.EventType, event rulemanager.RuntimeK8sEvent) { +func (rm *RuleManager) ReportEvent(eventType utils.EventType, event utils.RuntimeK8sEvent) { if event.GetNamespace() == "" || event.GetPod() == "" { logger.L().Error("RuleManager - failed to get namespace and pod name from custom event") return diff --git a/pkg/utils/events.go b/pkg/utils/events.go index 1886e77b..ba147fbf 100644 --- a/pkg/utils/events.go +++ b/pkg/utils/events.go @@ -1,5 +1,10 @@ package utils +type RuntimeK8sEvent interface { + GetNamespace() string + GetPod() string +} + type EventType string const ( From d62d87b61e1225315505c1e0207035037dac2bab Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Thu, 12 Sep 2024 08:20:59 +0000 Subject: [PATCH 10/23] Converting event to interface Signed-off-by: Amit Schendel --- pkg/malwaremanager/malware_manager_interface.go | 2 +- pkg/malwaremanager/malwaremanager_mock.go | 2 +- pkg/malwaremanager/v1/malware_manager.go | 2 +- pkg/rulemanager/rule_manager_interface.go | 2 +- pkg/rulemanager/rule_manager_mock.go | 2 +- pkg/rulemanager/v1/rule_manager.go | 9 +++++---- pkg/utils/events.go | 5 ----- 7 files changed, 10 insertions(+), 14 deletions(-) diff --git a/pkg/malwaremanager/malware_manager_interface.go b/pkg/malwaremanager/malware_manager_interface.go index 5e82c8c1..45814fae 100644 --- a/pkg/malwaremanager/malware_manager_interface.go +++ b/pkg/malwaremanager/malware_manager_interface.go @@ -9,7 +9,7 @@ import ( ) type MalwareManagerClient interface { - ReportEvent(eventType utils.EventType, event utils.RuntimeK8sEvent) + ReportEvent(eventType utils.EventType, event interface{}) ContainerCallback(notif containercollection.PubSubEvent) } diff --git a/pkg/malwaremanager/malwaremanager_mock.go b/pkg/malwaremanager/malwaremanager_mock.go index 84c86519..163fe4f4 100644 --- a/pkg/malwaremanager/malwaremanager_mock.go +++ b/pkg/malwaremanager/malwaremanager_mock.go @@ -14,7 +14,7 @@ func CreateMalwareManagerMock() *MalwareManagerMock { return &MalwareManagerMock{} } -func (r MalwareManagerMock) ReportEvent(_ utils.EventType, _ utils.RuntimeK8sEvent) { +func (r MalwareManagerMock) ReportEvent(_ utils.EventType, _ interface{}) { // noop } diff --git a/pkg/malwaremanager/v1/malware_manager.go b/pkg/malwaremanager/v1/malware_manager.go index d5fa3c3d..07835882 100644 --- a/pkg/malwaremanager/v1/malware_manager.go +++ b/pkg/malwaremanager/v1/malware_manager.go @@ -143,7 +143,7 @@ func (mm *MalwareManager) getWorkloadIdentifier(podNamespace, podName string) (s return generatedWlid, nil } -func (mm *MalwareManager) ReportEvent(eventType utils.EventType, event utils.RuntimeK8sEvent) { +func (mm *MalwareManager) ReportEvent(eventType utils.EventType, event interface{}) { switch eventType { case utils.ExecveEventType: exec, ok := event.(*tracerexectype.Event) diff --git a/pkg/rulemanager/rule_manager_interface.go b/pkg/rulemanager/rule_manager_interface.go index e26f9b2b..86a48fd8 100644 --- a/pkg/rulemanager/rule_manager_interface.go +++ b/pkg/rulemanager/rule_manager_interface.go @@ -11,7 +11,7 @@ import ( type RuleManagerClient interface { ContainerCallback(notif containercollection.PubSubEvent) RegisterPeekFunc(peek func(mntns uint64) ([]string, error)) - ReportEvent(eventType utils.EventType, event utils.RuntimeK8sEvent) + ReportEvent(eventType utils.EventType, event interface{}) HasApplicableRuleBindings(namespace, name string) bool HasFinalApplicationProfile(pod *v1.Pod) bool IsContainerMonitored(k8sContainerID string) bool diff --git a/pkg/rulemanager/rule_manager_mock.go b/pkg/rulemanager/rule_manager_mock.go index d8b4a965..0aa11fb2 100644 --- a/pkg/rulemanager/rule_manager_mock.go +++ b/pkg/rulemanager/rule_manager_mock.go @@ -24,7 +24,7 @@ func (r *RuleManagerMock) RegisterPeekFunc(_ func(mntns uint64) ([]string, error // noop } -func (r *RuleManagerMock) ReportEvent(_ utils.EventType, _ utils.RuntimeK8sEvent) { +func (r *RuleManagerMock) ReportEvent(_ utils.EventType, _ interface{}) { // noop } diff --git a/pkg/rulemanager/v1/rule_manager.go b/pkg/rulemanager/v1/rule_manager.go index 70079054..efb86524 100644 --- a/pkg/rulemanager/v1/rule_manager.go +++ b/pkg/rulemanager/v1/rule_manager.go @@ -321,15 +321,16 @@ func (rm *RuleManager) RegisterPeekFunc(peek func(mntns uint64) ([]string, error rm.syscallPeekFunc = peek } -func (rm *RuleManager) ReportEvent(eventType utils.EventType, event utils.RuntimeK8sEvent) { - if event.GetNamespace() == "" || event.GetPod() == "" { +func (rm *RuleManager) ReportEvent(eventType utils.EventType, event interface{}) { + k8sEvent := event.(eventtypes.Event) + if k8sEvent.GetNamespace() == "" || k8sEvent.GetPod() == "" { logger.L().Error("RuleManager - failed to get namespace and pod name from custom event") return } // list custom rules - rules := rm.ruleBindingCache.ListRulesForPod(event.GetNamespace(), event.GetPod()) - rm.processEvent(eventType, &event, rules) + rules := rm.ruleBindingCache.ListRulesForPod(k8sEvent.GetNamespace(), k8sEvent.GetPod()) + rm.processEvent(eventType, event, rules) } func (rm *RuleManager) processEvent(eventType utils.EventType, event interface{}, rules []ruleengine.RuleEvaluator) { diff --git a/pkg/utils/events.go b/pkg/utils/events.go index ba147fbf..1886e77b 100644 --- a/pkg/utils/events.go +++ b/pkg/utils/events.go @@ -1,10 +1,5 @@ package utils -type RuntimeK8sEvent interface { - GetNamespace() string - GetPod() string -} - type EventType string const ( From 5aeff9d28070418200a551060b93f54d4de8dd04 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Thu, 12 Sep 2024 08:23:14 +0000 Subject: [PATCH 11/23] Fixing event receiver Signed-off-by: Amit Schendel --- pkg/containerwatcher/container_watcher_interface.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/containerwatcher/container_watcher_interface.go b/pkg/containerwatcher/container_watcher_interface.go index 1df0f17b..4efa9a5d 100644 --- a/pkg/containerwatcher/container_watcher_interface.go +++ b/pkg/containerwatcher/container_watcher_interface.go @@ -30,7 +30,7 @@ type CustomTracer interface { } type EventReceiver interface { - ReportEvent(eventType utils.EventType, event utils.RuntimeK8sEvent) + ReportEvent(eventType utils.EventType, event interface{}) } type ContainerReceiver interface { From 2ec49a8ecba1a43c5efa56ec05d9e1efe671c016 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Thu, 12 Sep 2024 08:32:53 +0000 Subject: [PATCH 12/23] Adding ptr to event Signed-off-by: Amit Schendel --- pkg/rulemanager/v1/rule_manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/rulemanager/v1/rule_manager.go b/pkg/rulemanager/v1/rule_manager.go index efb86524..10796ba9 100644 --- a/pkg/rulemanager/v1/rule_manager.go +++ b/pkg/rulemanager/v1/rule_manager.go @@ -322,7 +322,7 @@ func (rm *RuleManager) RegisterPeekFunc(peek func(mntns uint64) ([]string, error } func (rm *RuleManager) ReportEvent(eventType utils.EventType, event interface{}) { - k8sEvent := event.(eventtypes.Event) + k8sEvent := event.(*eventtypes.Event) if k8sEvent.GetNamespace() == "" || k8sEvent.GetPod() == "" { logger.L().Error("RuleManager - failed to get namespace and pod name from custom event") return From e46977213d174194ea83f09f74874f192fad2b9b Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Thu, 12 Sep 2024 08:53:03 +0000 Subject: [PATCH 13/23] Adding interface for k8s events Signed-off-by: Amit Schendel --- .../container_watcher_interface.go | 2 +- .../malware_manager_interface.go | 4 +- pkg/malwaremanager/malwaremanager_mock.go | 2 +- pkg/malwaremanager/v1/clamav/clamav.go | 3 +- pkg/malwaremanager/v1/malware_manager.go | 10 +- pkg/ruleengine/ruleengine_interface.go | 2 +- pkg/ruleengine/ruleengine_mock.go | 2 +- .../v1/r0001_unexpected_process_launched.go | 2 +- .../v1/r0002_unexpected_file_access.go | 2 +- .../v1/r0003_unexpected_system_call.go | 2 +- .../v1/r0004_unexpected_capability_used.go | 2 +- .../v1/r0005_unexpected_domain_request.go | 2 +- ...unexpected_service_account_token_access.go | 2 +- .../v1/r0007_kubernetes_client_executed.go | 2 +- .../v1/r0008_read_env_variables_procfs.go | 2 +- pkg/ruleengine/v1/r0009_ebpf_program_load.go | 2 +- .../r0010_unexpected_sensitive_file_access.go | 2 +- ...r0011_unexpected_egress_network_traffic.go | 2 +- .../v1/r1000_exec_from_malicious_source.go | 2 +- .../v1/r1001_exec_binary_not_in_base_image.go | 2 +- pkg/ruleengine/v1/r1002_load_kernel_module.go | 2 +- .../v1/r1003_malicious_ssh_connection.go | 2 +- pkg/ruleengine/v1/r1004_exec_from_mount.go | 2 +- pkg/ruleengine/v1/r1005_fileless_execution.go | 2 +- .../v1/r1006_unshare_system_call.go | 2 +- pkg/ruleengine/v1/r1007_xmr_crypto_mining.go | 2 +- .../v1/r1008_crypto_mining_domain.go | 2 +- pkg/ruleengine/v1/r1009_crypto_mining_port.go | 2 +- ...010_symlink_created_over_sensitive_file.go | 2 +- pkg/ruleengine/v1/r1011_ld_preload_hook.go | 2 +- ...12_hardlink_created_over_sensitive_file.go | 2 +- pkg/rulemanager/rule_manager_interface.go | 2 +- pkg/rulemanager/rule_manager_mock.go | 2 +- pkg/rulemanager/v1/rule_manager.go | 9 +- pkg/rulemanager/v1/rule_manager_test.go | 104 ++++++------------ pkg/utils/events.go | 5 + pkg/utils/utils.go | 2 +- 37 files changed, 82 insertions(+), 115 deletions(-) diff --git a/pkg/containerwatcher/container_watcher_interface.go b/pkg/containerwatcher/container_watcher_interface.go index 4efa9a5d..bc9ce8e5 100644 --- a/pkg/containerwatcher/container_watcher_interface.go +++ b/pkg/containerwatcher/container_watcher_interface.go @@ -30,7 +30,7 @@ type CustomTracer interface { } type EventReceiver interface { - ReportEvent(eventType utils.EventType, event interface{}) + ReportEvent(eventType utils.EventType, event utils.K8sEvent) } type ContainerReceiver interface { diff --git a/pkg/malwaremanager/malware_manager_interface.go b/pkg/malwaremanager/malware_manager_interface.go index 45814fae..00ce1884 100644 --- a/pkg/malwaremanager/malware_manager_interface.go +++ b/pkg/malwaremanager/malware_manager_interface.go @@ -9,7 +9,7 @@ import ( ) type MalwareManagerClient interface { - ReportEvent(eventType utils.EventType, event interface{}) + ReportEvent(eventType utils.EventType, event utils.K8sEvent) ContainerCallback(notif containercollection.PubSubEvent) } @@ -41,5 +41,5 @@ type MalwareResult interface { type MalwareScanner interface { // Scan scans the event for malware. - Scan(eventType utils.EventType, event interface{}, containerPid uint32) MalwareResult + Scan(eventType utils.EventType, event utils.K8sEvent, containerPid uint32) MalwareResult } diff --git a/pkg/malwaremanager/malwaremanager_mock.go b/pkg/malwaremanager/malwaremanager_mock.go index 163fe4f4..e0a3f3c9 100644 --- a/pkg/malwaremanager/malwaremanager_mock.go +++ b/pkg/malwaremanager/malwaremanager_mock.go @@ -14,7 +14,7 @@ func CreateMalwareManagerMock() *MalwareManagerMock { return &MalwareManagerMock{} } -func (r MalwareManagerMock) ReportEvent(_ utils.EventType, _ interface{}) { +func (r MalwareManagerMock) ReportEvent(_ utils.EventType, _ utils.K8sEvent) { // noop } diff --git a/pkg/malwaremanager/v1/clamav/clamav.go b/pkg/malwaremanager/v1/clamav/clamav.go index 1a12b9da..10c893f6 100644 --- a/pkg/malwaremanager/v1/clamav/clamav.go +++ b/pkg/malwaremanager/v1/clamav/clamav.go @@ -8,6 +8,7 @@ import ( "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" "github.com/kubescape/node-agent/pkg/malwaremanager" + "github.com/kubescape/node-agent/pkg/utils" nautils "github.com/kubescape/node-agent/pkg/utils" ) @@ -39,7 +40,7 @@ func CreateClamAVClient(clamavSocket string) (*ClamAVClient, error) { return &clamavClient, nil } -func (c *ClamAVClient) Scan(eventType nautils.EventType, event interface{}, containerPid uint32) malwaremanager.MalwareResult { +func (c *ClamAVClient) Scan(eventType nautils.EventType, event utils.K8sEvent, containerPid uint32) malwaremanager.MalwareResult { // Check if the event is of type tracerexectype.Event or traceropentype.Event. switch eventType { case nautils.ExecveEventType: diff --git a/pkg/malwaremanager/v1/malware_manager.go b/pkg/malwaremanager/v1/malware_manager.go index 07835882..aee48edf 100644 --- a/pkg/malwaremanager/v1/malware_manager.go +++ b/pkg/malwaremanager/v1/malware_manager.go @@ -143,7 +143,7 @@ func (mm *MalwareManager) getWorkloadIdentifier(podNamespace, podName string) (s return generatedWlid, nil } -func (mm *MalwareManager) ReportEvent(eventType utils.EventType, event interface{}) { +func (mm *MalwareManager) ReportEvent(eventType utils.EventType, event utils.K8sEvent) { switch eventType { case utils.ExecveEventType: exec, ok := event.(*tracerexectype.Event) @@ -164,7 +164,7 @@ func (mm *MalwareManager) ReportEvent(eventType utils.EventType, event interface func (mm *MalwareManager) reportFileExec(event *tracerexectype.Event) { for _, scanner := range mm.malwareScanners { - if result := scanner.Scan(utils.ExecveEventType, &event, mm.containerIdToPid.Get(event.Runtime.ContainerID)); result != nil { + if result := scanner.Scan(utils.ExecveEventType, event, mm.containerIdToPid.Get(event.Runtime.ContainerID)); result != nil { result = mm.enrichMalwareResult(result) result.SetWorkloadDetails(mm.podToWlid.Get(utils.CreateK8sPodID(event.GetNamespace(), event.GetPod()))) mm.exporter.SendMalwareAlert(result) @@ -172,7 +172,7 @@ func (mm *MalwareManager) reportFileExec(event *tracerexectype.Event) { } if mm.scannedFiles.Has(event.Runtime.ContainerID) && mm.scannedFiles.Get(event.Runtime.ContainerID).Cardinality() <= ScannedFilesMaxBufferLength { - hostFilePath, err := utils.GetHostFilePathFromEvent(&event, mm.containerIdToPid.Get(event.Runtime.ContainerID)) + hostFilePath, err := utils.GetHostFilePathFromEvent(event, mm.containerIdToPid.Get(event.Runtime.ContainerID)) if err != nil { return } @@ -189,7 +189,7 @@ func (mm *MalwareManager) reportFileOpen(event *traceropentype.Event) { return } - hostFilePath, err := utils.GetHostFilePathFromEvent(&event, mm.containerIdToPid.Get(event.Runtime.ContainerID)) + hostFilePath, err := utils.GetHostFilePathFromEvent(event, mm.containerIdToPid.Get(event.Runtime.ContainerID)) if err != nil { return } @@ -208,7 +208,7 @@ func (mm *MalwareManager) reportFileOpen(event *traceropentype.Event) { } for _, scanner := range mm.malwareScanners { - if result := scanner.Scan(utils.OpenEventType, &event, mm.containerIdToPid.Get(event.Runtime.ContainerID)); result != nil { + if result := scanner.Scan(utils.OpenEventType, event, mm.containerIdToPid.Get(event.Runtime.ContainerID)); result != nil { result = mm.enrichMalwareResult(result) result.SetWorkloadDetails(mm.podToWlid.Get(utils.CreateK8sPodID(event.GetNamespace(), event.GetPod()))) mm.exporter.SendMalwareAlert(result) diff --git a/pkg/ruleengine/ruleengine_interface.go b/pkg/ruleengine/ruleengine_interface.go index 84dfe2e4..d512670f 100644 --- a/pkg/ruleengine/ruleengine_interface.go +++ b/pkg/ruleengine/ruleengine_interface.go @@ -61,7 +61,7 @@ type RuleEvaluator interface { Name() string // Rule processing - ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) RuleFailure + ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) RuleFailure // Rule requirements Requirements() RuleSpec diff --git a/pkg/ruleengine/ruleengine_mock.go b/pkg/ruleengine/ruleengine_mock.go index 28ab3775..40e46b89 100644 --- a/pkg/ruleengine/ruleengine_mock.go +++ b/pkg/ruleengine/ruleengine_mock.go @@ -48,7 +48,7 @@ func (rule *RuleMock) ID() string { func (rule *RuleMock) DeleteRule() { } -func (rule *RuleMock) ProcessEvent(_ utils.EventType, _ interface{}, _ objectcache.ObjectCache) RuleFailure { +func (rule *RuleMock) ProcessEvent(_ utils.EventType, _ utils.K8sEvent, _ objectcache.ObjectCache) RuleFailure { return nil } diff --git a/pkg/ruleengine/v1/r0001_unexpected_process_launched.go b/pkg/ruleengine/v1/r0001_unexpected_process_launched.go index 90203160..35342e2d 100644 --- a/pkg/ruleengine/v1/r0001_unexpected_process_launched.go +++ b/pkg/ruleengine/v1/r0001_unexpected_process_launched.go @@ -75,7 +75,7 @@ func (rule *R0001UnexpectedProcessLaunched) generatePatchCommand(event *tracerex event.GetContainer(), getExecPathFromEvent(event), argList) } -func (rule *R0001UnexpectedProcessLaunched) ProcessEvent(eventType utils.EventType, event interface{}, objectCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R0001UnexpectedProcessLaunched) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objectCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.ExecveEventType { return nil } diff --git a/pkg/ruleengine/v1/r0002_unexpected_file_access.go b/pkg/ruleengine/v1/r0002_unexpected_file_access.go index b17ec651..fd91852d 100644 --- a/pkg/ruleengine/v1/r0002_unexpected_file_access.go +++ b/pkg/ruleengine/v1/r0002_unexpected_file_access.go @@ -93,7 +93,7 @@ func (rule *R0002UnexpectedFileAccess) generatePatchCommand(event *traceropentyp return fmt.Sprintf(baseTemplate, ap.GetName(), ap.GetNamespace(), event.GetContainer(), event.FullPath, flagList) } -func (rule *R0002UnexpectedFileAccess) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R0002UnexpectedFileAccess) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.OpenEventType { return nil } diff --git a/pkg/ruleengine/v1/r0003_unexpected_system_call.go b/pkg/ruleengine/v1/r0003_unexpected_system_call.go index eb87d911..06c93cee 100644 --- a/pkg/ruleengine/v1/r0003_unexpected_system_call.go +++ b/pkg/ruleengine/v1/r0003_unexpected_system_call.go @@ -58,7 +58,7 @@ func (rule *R0003UnexpectedSystemCall) ID() string { func (rule *R0003UnexpectedSystemCall) DeleteRule() { } -func (rule *R0003UnexpectedSystemCall) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R0003UnexpectedSystemCall) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.SyscallEventType { return nil } diff --git a/pkg/ruleengine/v1/r0004_unexpected_capability_used.go b/pkg/ruleengine/v1/r0004_unexpected_capability_used.go index 46adf8a9..5e96899b 100644 --- a/pkg/ruleengine/v1/r0004_unexpected_capability_used.go +++ b/pkg/ruleengine/v1/r0004_unexpected_capability_used.go @@ -56,7 +56,7 @@ func (rule *R0004UnexpectedCapabilityUsed) generatePatchCommand(event *tracercap event.GetContainer(), event.Syscall, event.CapName) } -func (rule *R0004UnexpectedCapabilityUsed) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R0004UnexpectedCapabilityUsed) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.CapabilitiesEventType { return nil } diff --git a/pkg/ruleengine/v1/r0005_unexpected_domain_request.go b/pkg/ruleengine/v1/r0005_unexpected_domain_request.go index b8562c8f..bc372fd7 100644 --- a/pkg/ruleengine/v1/r0005_unexpected_domain_request.go +++ b/pkg/ruleengine/v1/r0005_unexpected_domain_request.go @@ -61,7 +61,7 @@ func (rule *R0005UnexpectedDomainRequest) generatePatchCommand(event *tracerdnst event.GetContainer(), event.DNSName) } -func (rule *R0005UnexpectedDomainRequest) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R0005UnexpectedDomainRequest) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.DnsEventType { return nil } diff --git a/pkg/ruleengine/v1/r0006_unexpected_service_account_token_access.go b/pkg/ruleengine/v1/r0006_unexpected_service_account_token_access.go index 8d6c4687..b6b7fe0d 100644 --- a/pkg/ruleengine/v1/r0006_unexpected_service_account_token_access.go +++ b/pkg/ruleengine/v1/r0006_unexpected_service_account_token_access.go @@ -76,7 +76,7 @@ func (rule *R0006UnexpectedServiceAccountTokenAccess) generatePatchCommand(event event.GetContainer(), event.FullPath, flagList) } -func (rule *R0006UnexpectedServiceAccountTokenAccess) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R0006UnexpectedServiceAccountTokenAccess) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.OpenEventType { return nil } diff --git a/pkg/ruleengine/v1/r0007_kubernetes_client_executed.go b/pkg/ruleengine/v1/r0007_kubernetes_client_executed.go index 66bd9add..39951124 100644 --- a/pkg/ruleengine/v1/r0007_kubernetes_client_executed.go +++ b/pkg/ruleengine/v1/r0007_kubernetes_client_executed.go @@ -186,7 +186,7 @@ func (rule *R0007KubernetesClientExecuted) handleExecEvent(event *tracerexectype return nil } -func (rule *R0007KubernetesClientExecuted) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R0007KubernetesClientExecuted) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.ExecveEventType && eventType != utils.NetworkEventType { return nil } diff --git a/pkg/ruleengine/v1/r0008_read_env_variables_procfs.go b/pkg/ruleengine/v1/r0008_read_env_variables_procfs.go index 2558225b..ef29e017 100644 --- a/pkg/ruleengine/v1/r0008_read_env_variables_procfs.go +++ b/pkg/ruleengine/v1/r0008_read_env_variables_procfs.go @@ -52,7 +52,7 @@ func (rule *R0008ReadEnvironmentVariablesProcFS) ID() string { func (rule *R0008ReadEnvironmentVariablesProcFS) DeleteRule() { } -func (rule *R0008ReadEnvironmentVariablesProcFS) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R0008ReadEnvironmentVariablesProcFS) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.OpenEventType { return nil } diff --git a/pkg/ruleengine/v1/r0009_ebpf_program_load.go b/pkg/ruleengine/v1/r0009_ebpf_program_load.go index 655ceefc..3c064d38 100644 --- a/pkg/ruleengine/v1/r0009_ebpf_program_load.go +++ b/pkg/ruleengine/v1/r0009_ebpf_program_load.go @@ -55,7 +55,7 @@ func (rule *R0009EbpfProgramLoad) ID() string { func (rule *R0009EbpfProgramLoad) DeleteRule() { } -func (rule *R0009EbpfProgramLoad) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R0009EbpfProgramLoad) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if rule.alreadyNotified { return nil } diff --git a/pkg/ruleengine/v1/r0010_unexpected_sensitive_file_access.go b/pkg/ruleengine/v1/r0010_unexpected_sensitive_file_access.go index 85448133..54d35e64 100644 --- a/pkg/ruleengine/v1/r0010_unexpected_sensitive_file_access.go +++ b/pkg/ruleengine/v1/r0010_unexpected_sensitive_file_access.go @@ -76,7 +76,7 @@ func (rule *R0010UnexpectedSensitiveFileAccess) ID() string { func (rule *R0010UnexpectedSensitiveFileAccess) DeleteRule() { } -func (rule *R0010UnexpectedSensitiveFileAccess) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R0010UnexpectedSensitiveFileAccess) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.OpenEventType { return nil } diff --git a/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic.go b/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic.go index 7c57843e..3c91f107 100644 --- a/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic.go +++ b/pkg/ruleengine/v1/r0011_unexpected_egress_network_traffic.go @@ -133,7 +133,7 @@ func (rule *R0011UnexpectedEgressNetworkTraffic) handleNetworkEvent(networkEvent return nil } -func (rule *R0011UnexpectedEgressNetworkTraffic) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R0011UnexpectedEgressNetworkTraffic) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.NetworkEventType { return nil } diff --git a/pkg/ruleengine/v1/r1000_exec_from_malicious_source.go b/pkg/ruleengine/v1/r1000_exec_from_malicious_source.go index c70fbbf3..2be1abf2 100644 --- a/pkg/ruleengine/v1/r1000_exec_from_malicious_source.go +++ b/pkg/ruleengine/v1/r1000_exec_from_malicious_source.go @@ -49,7 +49,7 @@ func (rule *R1000ExecFromMaliciousSource) ID() string { return R1000ID } -func (rule *R1000ExecFromMaliciousSource) ProcessEvent(eventType utils.EventType, event interface{}, _ objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1000ExecFromMaliciousSource) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, _ objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.ExecveEventType { return nil } diff --git a/pkg/ruleengine/v1/r1001_exec_binary_not_in_base_image.go b/pkg/ruleengine/v1/r1001_exec_binary_not_in_base_image.go index fa12dcb3..f9236509 100644 --- a/pkg/ruleengine/v1/r1001_exec_binary_not_in_base_image.go +++ b/pkg/ruleengine/v1/r1001_exec_binary_not_in_base_image.go @@ -52,7 +52,7 @@ func (rule *R1001ExecBinaryNotInBaseImage) ID() string { func (rule *R1001ExecBinaryNotInBaseImage) DeleteRule() { } -func (rule *R1001ExecBinaryNotInBaseImage) ProcessEvent(eventType utils.EventType, event interface{}, objectCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1001ExecBinaryNotInBaseImage) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objectCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.ExecveEventType { return nil } diff --git a/pkg/ruleengine/v1/r1002_load_kernel_module.go b/pkg/ruleengine/v1/r1002_load_kernel_module.go index 28c17f25..b74dfda4 100644 --- a/pkg/ruleengine/v1/r1002_load_kernel_module.go +++ b/pkg/ruleengine/v1/r1002_load_kernel_module.go @@ -52,7 +52,7 @@ func (rule *R1002LoadKernelModule) ID() string { func (rule *R1002LoadKernelModule) DeleteRule() { } -func (rule *R1002LoadKernelModule) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1002LoadKernelModule) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if rule.alerted { return nil } diff --git a/pkg/ruleengine/v1/r1003_malicious_ssh_connection.go b/pkg/ruleengine/v1/r1003_malicious_ssh_connection.go index 18390290..bf7382dd 100644 --- a/pkg/ruleengine/v1/r1003_malicious_ssh_connection.go +++ b/pkg/ruleengine/v1/r1003_malicious_ssh_connection.go @@ -127,7 +127,7 @@ func (rule *R1003MaliciousSSHConnection) SetParameters(params map[string]interfa func (rule *R1003MaliciousSSHConnection) DeleteRule() { } -func (rule *R1003MaliciousSSHConnection) ProcessEvent(eventType utils.EventType, event interface{}, objectCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1003MaliciousSSHConnection) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objectCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.SSHEventType { return nil } diff --git a/pkg/ruleengine/v1/r1004_exec_from_mount.go b/pkg/ruleengine/v1/r1004_exec_from_mount.go index abb93f1f..3c06c18a 100644 --- a/pkg/ruleengine/v1/r1004_exec_from_mount.go +++ b/pkg/ruleengine/v1/r1004_exec_from_mount.go @@ -50,7 +50,7 @@ func (rule *R1004ExecFromMount) ID() string { func (rule *R1004ExecFromMount) DeleteRule() { } -func (rule *R1004ExecFromMount) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1004ExecFromMount) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.ExecveEventType { return nil } diff --git a/pkg/ruleengine/v1/r1005_fileless_execution.go b/pkg/ruleengine/v1/r1005_fileless_execution.go index 96b4bd4e..d1645caa 100644 --- a/pkg/ruleengine/v1/r1005_fileless_execution.go +++ b/pkg/ruleengine/v1/r1005_fileless_execution.go @@ -54,7 +54,7 @@ func (rule *R1005FilelessExecution) ID() string { func (rule *R1005FilelessExecution) DeleteRule() { } -func (rule *R1005FilelessExecution) ProcessEvent(eventType utils.EventType, event interface{}, _ objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1005FilelessExecution) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, _ objectcache.ObjectCache) ruleengine.RuleFailure { if eventType == utils.ExecveEventType { return rule.handleExecveEvent(event.(*tracerexectype.Event)) } diff --git a/pkg/ruleengine/v1/r1006_unshare_system_call.go b/pkg/ruleengine/v1/r1006_unshare_system_call.go index 74885e34..5440d673 100644 --- a/pkg/ruleengine/v1/r1006_unshare_system_call.go +++ b/pkg/ruleengine/v1/r1006_unshare_system_call.go @@ -54,7 +54,7 @@ func (rule *R1006UnshareSyscall) ID() string { func (rule *R1006UnshareSyscall) DeleteRule() { } -func (rule *R1006UnshareSyscall) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1006UnshareSyscall) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if rule.alreadyNotified { return nil } diff --git a/pkg/ruleengine/v1/r1007_xmr_crypto_mining.go b/pkg/ruleengine/v1/r1007_xmr_crypto_mining.go index ed59b016..4083afd9 100644 --- a/pkg/ruleengine/v1/r1007_xmr_crypto_mining.go +++ b/pkg/ruleengine/v1/r1007_xmr_crypto_mining.go @@ -54,7 +54,7 @@ func (rule *R1007XMRCryptoMining) ID() string { func (rule *R1007XMRCryptoMining) DeleteRule() { } -func (rule *R1007XMRCryptoMining) ProcessEvent(eventType utils.EventType, event interface{}, _ objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1007XMRCryptoMining) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, _ objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.RandomXEventType { return nil } diff --git a/pkg/ruleengine/v1/r1008_crypto_mining_domain.go b/pkg/ruleengine/v1/r1008_crypto_mining_domain.go index fb95b092..b1a25f4b 100644 --- a/pkg/ruleengine/v1/r1008_crypto_mining_domain.go +++ b/pkg/ruleengine/v1/r1008_crypto_mining_domain.go @@ -166,7 +166,7 @@ func (rule *R1008CryptoMiningDomainCommunication) ID() string { func (rule *R1008CryptoMiningDomainCommunication) DeleteRule() { } -func (rule *R1008CryptoMiningDomainCommunication) ProcessEvent(eventType utils.EventType, event interface{}, _ objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1008CryptoMiningDomainCommunication) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, _ objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.DnsEventType { return nil } diff --git a/pkg/ruleengine/v1/r1009_crypto_mining_port.go b/pkg/ruleengine/v1/r1009_crypto_mining_port.go index 6c347167..006bbe4e 100644 --- a/pkg/ruleengine/v1/r1009_crypto_mining_port.go +++ b/pkg/ruleengine/v1/r1009_crypto_mining_port.go @@ -59,7 +59,7 @@ func (rule *R1009CryptoMiningRelatedPort) ID() string { func (rule *R1009CryptoMiningRelatedPort) DeleteRule() { } -func (rule *R1009CryptoMiningRelatedPort) ProcessEvent(eventType utils.EventType, event interface{}, objectcache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1009CryptoMiningRelatedPort) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objectcache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.NetworkEventType { return nil } diff --git a/pkg/ruleengine/v1/r1010_symlink_created_over_sensitive_file.go b/pkg/ruleengine/v1/r1010_symlink_created_over_sensitive_file.go index 898efe3b..40537200 100644 --- a/pkg/ruleengine/v1/r1010_symlink_created_over_sensitive_file.go +++ b/pkg/ruleengine/v1/r1010_symlink_created_over_sensitive_file.go @@ -78,7 +78,7 @@ func (rule *R1010SymlinkCreatedOverSensitiveFile) ID() string { func (rule *R1010SymlinkCreatedOverSensitiveFile) DeleteRule() { } -func (rule *R1010SymlinkCreatedOverSensitiveFile) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1010SymlinkCreatedOverSensitiveFile) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.SymlinkEventType { return nil } diff --git a/pkg/ruleengine/v1/r1011_ld_preload_hook.go b/pkg/ruleengine/v1/r1011_ld_preload_hook.go index c20e4b46..ea926fdd 100644 --- a/pkg/ruleengine/v1/r1011_ld_preload_hook.go +++ b/pkg/ruleengine/v1/r1011_ld_preload_hook.go @@ -183,7 +183,7 @@ func (rule *R1011LdPreloadHook) handleOpenEvent(openEvent *traceropentype.Event) return nil } -func (rule *R1011LdPreloadHook) ProcessEvent(eventType utils.EventType, event interface{}, objectCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1011LdPreloadHook) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objectCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.ExecveEventType && eventType != utils.OpenEventType { return nil } diff --git a/pkg/ruleengine/v1/r1012_hardlink_created_over_sensitive_file.go b/pkg/ruleengine/v1/r1012_hardlink_created_over_sensitive_file.go index b6868bc7..3d70f34c 100644 --- a/pkg/ruleengine/v1/r1012_hardlink_created_over_sensitive_file.go +++ b/pkg/ruleengine/v1/r1012_hardlink_created_over_sensitive_file.go @@ -78,7 +78,7 @@ func (rule *R1012HardlinkCreatedOverSensitiveFile) ID() string { func (rule *R1012HardlinkCreatedOverSensitiveFile) DeleteRule() { } -func (rule *R1012HardlinkCreatedOverSensitiveFile) ProcessEvent(eventType utils.EventType, event interface{}, objCache objectcache.ObjectCache) ruleengine.RuleFailure { +func (rule *R1012HardlinkCreatedOverSensitiveFile) ProcessEvent(eventType utils.EventType, event utils.K8sEvent, objCache objectcache.ObjectCache) ruleengine.RuleFailure { if eventType != utils.HardlinkEventType { return nil } diff --git a/pkg/rulemanager/rule_manager_interface.go b/pkg/rulemanager/rule_manager_interface.go index 86a48fd8..76f71de8 100644 --- a/pkg/rulemanager/rule_manager_interface.go +++ b/pkg/rulemanager/rule_manager_interface.go @@ -11,7 +11,7 @@ import ( type RuleManagerClient interface { ContainerCallback(notif containercollection.PubSubEvent) RegisterPeekFunc(peek func(mntns uint64) ([]string, error)) - ReportEvent(eventType utils.EventType, event interface{}) + ReportEvent(eventType utils.EventType, event utils.K8sEvent) HasApplicableRuleBindings(namespace, name string) bool HasFinalApplicationProfile(pod *v1.Pod) bool IsContainerMonitored(k8sContainerID string) bool diff --git a/pkg/rulemanager/rule_manager_mock.go b/pkg/rulemanager/rule_manager_mock.go index 0aa11fb2..3cf78d59 100644 --- a/pkg/rulemanager/rule_manager_mock.go +++ b/pkg/rulemanager/rule_manager_mock.go @@ -24,7 +24,7 @@ func (r *RuleManagerMock) RegisterPeekFunc(_ func(mntns uint64) ([]string, error // noop } -func (r *RuleManagerMock) ReportEvent(_ utils.EventType, _ interface{}) { +func (r *RuleManagerMock) ReportEvent(_ utils.EventType, _ utils.K8sEvent) { // noop } diff --git a/pkg/rulemanager/v1/rule_manager.go b/pkg/rulemanager/v1/rule_manager.go index 10796ba9..56ce6156 100644 --- a/pkg/rulemanager/v1/rule_manager.go +++ b/pkg/rulemanager/v1/rule_manager.go @@ -321,19 +321,18 @@ func (rm *RuleManager) RegisterPeekFunc(peek func(mntns uint64) ([]string, error rm.syscallPeekFunc = peek } -func (rm *RuleManager) ReportEvent(eventType utils.EventType, event interface{}) { - k8sEvent := event.(*eventtypes.Event) - if k8sEvent.GetNamespace() == "" || k8sEvent.GetPod() == "" { +func (rm *RuleManager) ReportEvent(eventType utils.EventType, event utils.K8sEvent) { + if event.GetNamespace() == "" || event.GetPod() == "" { logger.L().Error("RuleManager - failed to get namespace and pod name from custom event") return } // list custom rules - rules := rm.ruleBindingCache.ListRulesForPod(k8sEvent.GetNamespace(), k8sEvent.GetPod()) + rules := rm.ruleBindingCache.ListRulesForPod(event.GetNamespace(), event.GetPod()) rm.processEvent(eventType, event, rules) } -func (rm *RuleManager) processEvent(eventType utils.EventType, event interface{}, rules []ruleengine.RuleEvaluator) { +func (rm *RuleManager) processEvent(eventType utils.EventType, event utils.K8sEvent, rules []ruleengine.RuleEvaluator) { for _, rule := range rules { if rule == nil { continue diff --git a/pkg/rulemanager/v1/rule_manager_test.go b/pkg/rulemanager/v1/rule_manager_test.go index 11ee67ea..19dc8ce1 100644 --- a/pkg/rulemanager/v1/rule_manager_test.go +++ b/pkg/rulemanager/v1/rule_manager_test.go @@ -1,77 +1,39 @@ package rulemanager -// func TestApplicationProfileManager(t *testing.T) { -// cfg := config.Config{ -// InitialDelay: 1 * time.Second, -// MaxSniffingTime: 5 * time.Minute, -// UpdateDataPeriod: 1 * time.Second, -// } -// ctx := context.TODO() -// k8sClient := &k8sclient.K8sClientMock{} -// storageClient := &storage.StorageHttpClientMock{} -// am, err := CreateApplicationProfileManager(ctx, cfg, "cluster", k8sClient, storageClient) -// assert.NoError(t, err) -// // prepare container -// container := &containercollection.Container{ -// K8s: containercollection.K8sMetadata{ -// BasicK8sMetadata: types.BasicK8sMetadata{ -// Namespace: "ns", -// PodName: "pod", -// ContainerName: "cont", -// }, -// }, -// Runtime: containercollection.RuntimeMetadata{ -// BasicRuntimeMetadata: types.BasicRuntimeMetadata{ -// ContainerID: "5fff6a395ce4e6984a9447cc6cfb09f473eaf278498243963fcc944889bc8400", +// import ( +// "testing" + +// eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types" +// "github.com/kubescape/go-logger" +// tracerhardlinktype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/hardlink/types" +// "github.com/kubescape/node-agent/pkg/utils" +// ) + +// func TestReportEvent(t *testing.T) { +// // Create a hardlink event +// e := &tracerhardlinktype.Event{ +// Event: eventtypes.Event{ +// CommonData: eventtypes.CommonData{ +// K8s: eventtypes.K8sMetadata{ +// BasicK8sMetadata: eventtypes.BasicK8sMetadata{ +// ContainerName: "test", +// }, +// }, // }, // }, +// Comm: "test", +// OldPath: "test", +// NewPath: "test", +// } + +// // Create a new rule +// reportEvent(utils.HardlinkEventType, e) +// } + +// func reportEvent(eventType utils.EventType, event utils.K8sEvent) { +// k8sEvent := event.(*eventtypes.Event) +// if k8sEvent.GetNamespace() == "" || k8sEvent.GetPod() == "" { +// logger.L().Error("RuleManager - failed to get namespace and pod name from custom event") +// return // } -// // register peek function for syscall tracer -// go am.RegisterPeekFunc(func(_ uint64) ([]string, error) { -// return []string{"dup", "listen"}, nil -// }) -// // report capability -// go am.ReportCapability("ns/pod/cont", "NET_BIND_SERVICE") -// // report file exec -// go am.ReportFileExec("ns/pod/cont", "", []string{"ls"}) // will not be reported -// go am.ReportFileExec("ns/pod/cont", "/bin/bash", []string{"-c", "ls"}) -// // report file open -// go am.ReportFileOpen("ns/pod/cont", "/etc/passwd", []string{"O_RDONLY"}) -// // report container started (race condition with reports) -// am.ContainerCallback(containercollection.PubSubEvent{ -// Type: containercollection.EventTypeAddContainer, -// Container: container, -// }) -// // let it run for a while -// time.Sleep(15 * time.Second) // need to sleep longer because of AddRandomDuration in startApplicationProfiling -// // report another file open -// go am.ReportFileOpen("ns/pod/cont", "/etc/hosts", []string{"O_RDONLY"}) -// // sleep more -// time.Sleep(2 * time.Second) -// // report container stopped -// am.ContainerCallback(containercollection.PubSubEvent{ -// Type: containercollection.EventTypeRemoveContainer, -// Container: container, -// }) -// // let it stop -// time.Sleep(2 * time.Second) -// // verify generated CRDs -// assert.Equal(t, 1, len(storageClient.ApplicationActivities)) -// sort.Strings(storageClient.ApplicationActivities[0].Spec.Syscalls) -// assert.Equal(t, []string{"dup", "listen"}, storageClient.ApplicationActivities[0].Spec.Syscalls) -// assert.Equal(t, 2, len(storageClient.ApplicationProfiles)) -// assert.Equal(t, 2, len(storageClient.ApplicationProfileSummaries)) -// // check the first profile -// sort.Strings(storageClient.ApplicationProfiles[0].Spec.Containers[0].Capabilities) -// assert.Equal(t, []string{"NET_BIND_SERVICE"}, storageClient.ApplicationProfiles[0].Spec.Containers[1].Capabilities) -// assert.Equal(t, []v1beta1.ExecCalls{{Path: "/bin/bash", Args: []string{"-c", "ls"}, Envs: []string(nil)}}, storageClient.ApplicationProfiles[0].Spec.Containers[1].Execs) -// assert.Equal(t, []v1beta1.OpenCalls{{Path: "/etc/passwd", Flags: []string{"O_RDONLY"}}}, storageClient.ApplicationProfiles[0].Spec.Containers[1].Opens) -// // check the second profile - this is a patch for execs and opens -// sort.Strings(storageClient.ApplicationProfiles[1].Spec.Containers[0].Capabilities) -// assert.Equal(t, []string{"NET_BIND_SERVICE"}, storageClient.ApplicationProfiles[1].Spec.Containers[1].Capabilities) -// assert.Equal(t, []v1beta1.ExecCalls{{Path: "/bin/bash", Args: []string{"-c", "ls"}, Envs: []string(nil)}}, storageClient.ApplicationProfiles[1].Spec.Containers[1].Execs) -// assert.Equal(t, []v1beta1.OpenCalls{ -// {Path: "/etc/passwd", Flags: []string{"O_RDONLY"}}, -// {Path: "/etc/hosts", Flags: []string{"O_RDONLY"}}, -// }, storageClient.ApplicationProfiles[1].Spec.Containers[1].Opens) // } diff --git a/pkg/utils/events.go b/pkg/utils/events.go index 1886e77b..0be17353 100644 --- a/pkg/utils/events.go +++ b/pkg/utils/events.go @@ -1,5 +1,10 @@ package utils +type K8sEvent interface { + GetPod() string + GetNamespace() string +} + type EventType string const ( diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 9234533a..57eb1c33 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -421,7 +421,7 @@ func GetProcessEnv(pid int) (map[string]string, error) { } // Get the path of the file on the node. -func GetHostFilePathFromEvent(event interface{}, containerPid uint32) (string, error) { +func GetHostFilePathFromEvent(event K8sEvent, containerPid uint32) (string, error) { if execEvent, ok := event.(*tracerexectype.Event); ok { realPath := filepath.Join("/proc", fmt.Sprintf("/%d/root/%s", containerPid, GetExecPathFromEvent(execEvent))) return realPath, nil From 48328b3b99ee015c9a90374a6fe93dd2eefd746a Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Thu, 12 Sep 2024 09:05:16 +0000 Subject: [PATCH 14/23] Adding test Signed-off-by: Amit Schendel --- pkg/rulemanager/v1/rule_manager_test.go | 66 ++++++++++++------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/pkg/rulemanager/v1/rule_manager_test.go b/pkg/rulemanager/v1/rule_manager_test.go index 19dc8ce1..cefa8559 100644 --- a/pkg/rulemanager/v1/rule_manager_test.go +++ b/pkg/rulemanager/v1/rule_manager_test.go @@ -1,39 +1,39 @@ package rulemanager -// import ( -// "testing" +import ( + "testing" -// eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types" -// "github.com/kubescape/go-logger" -// tracerhardlinktype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/hardlink/types" -// "github.com/kubescape/node-agent/pkg/utils" -// ) + eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types" + "github.com/kubescape/go-logger" + tracerhardlinktype "github.com/kubescape/node-agent/pkg/ebpf/gadgets/hardlink/types" + "github.com/kubescape/node-agent/pkg/utils" +) -// func TestReportEvent(t *testing.T) { -// // Create a hardlink event -// e := &tracerhardlinktype.Event{ -// Event: eventtypes.Event{ -// CommonData: eventtypes.CommonData{ -// K8s: eventtypes.K8sMetadata{ -// BasicK8sMetadata: eventtypes.BasicK8sMetadata{ -// ContainerName: "test", -// }, -// }, -// }, -// }, -// Comm: "test", -// OldPath: "test", -// NewPath: "test", -// } +func TestReportEvent(t *testing.T) { + // Create a hardlink event + e := &tracerhardlinktype.Event{ + Event: eventtypes.Event{ + CommonData: eventtypes.CommonData{ + K8s: eventtypes.K8sMetadata{ + BasicK8sMetadata: eventtypes.BasicK8sMetadata{ + ContainerName: "test", + }, + }, + }, + }, + Comm: "test", + OldPath: "test", + NewPath: "test", + } -// // Create a new rule -// reportEvent(utils.HardlinkEventType, e) -// } + // Create a new rule + reportEvent(utils.HardlinkEventType, e) +} -// func reportEvent(eventType utils.EventType, event utils.K8sEvent) { -// k8sEvent := event.(*eventtypes.Event) -// if k8sEvent.GetNamespace() == "" || k8sEvent.GetPod() == "" { -// logger.L().Error("RuleManager - failed to get namespace and pod name from custom event") -// return -// } -// } +func reportEvent(eventType utils.EventType, event utils.K8sEvent) { + k8sEvent := event.(*tracerhardlinktype.Event) + if k8sEvent.GetNamespace() == "" || k8sEvent.GetPod() == "" { + logger.L().Error("RuleManager - failed to get namespace and pod name from custom event") + return + } +} From 007b3489d03652aab9232b5abb91eac977be4077 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Mon, 16 Sep 2024 07:32:30 +0000 Subject: [PATCH 15/23] Adding common ssh port Signed-off-by: Amit Schendel --- pkg/ruleengine/v1/r1003_malicious_ssh_connection.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/ruleengine/v1/r1003_malicious_ssh_connection.go b/pkg/ruleengine/v1/r1003_malicious_ssh_connection.go index bf7382dd..e8205a4f 100644 --- a/pkg/ruleengine/v1/r1003_malicious_ssh_connection.go +++ b/pkg/ruleengine/v1/r1003_malicious_ssh_connection.go @@ -89,7 +89,7 @@ func CreateRuleR1003MaliciousSSHConnection() *R1003MaliciousSSHConnection { logger.L().Error("Failed to read port range, setting to default range:", helpers.Error(err)) } return &R1003MaliciousSSHConnection{ - allowedPorts: []uint16{22}, + allowedPorts: []uint16{22, 2022}, ephemeralPortRange: ephemeralPorts, } } From a7a420f2f9b8d59d3e9ec269a36378a6e138091d Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Tue, 17 Sep 2024 12:25:38 +0000 Subject: [PATCH 16/23] Adding default watcher for resources Signed-off-by: Amit Schendel --- pkg/watcher/dynamicwatcher/watch.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/watcher/dynamicwatcher/watch.go b/pkg/watcher/dynamicwatcher/watch.go index 760b25c1..80e6bd82 100644 --- a/pkg/watcher/dynamicwatcher/watch.go +++ b/pkg/watcher/dynamicwatcher/watch.go @@ -143,7 +143,10 @@ func (wh *WatchHandler) chooseWatcher(res schema.GroupVersionResource, opts meta return wh.k8sClient.GetDynamicClient().Resource(res).Namespace("").Watch(context.Background(), opts) case "seccompprofiles": return wh.storageClient.SeccompProfiles("").Watch(context.Background(), opts) + default: + return wh.k8sClient.GetDynamicClient().Resource(res).Watch(context.Background(), opts) } + return nil, errors2.NewNotFound(res.GroupResource(), "not implemented") } From 844ca373c396e301174e63d60f4ebd4f75abd6ce Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 18 Sep 2024 07:02:25 +0000 Subject: [PATCH 17/23] removing default watcher Signed-off-by: Amit Schendel --- pkg/watcher/dynamicwatcher/watch.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/watcher/dynamicwatcher/watch.go b/pkg/watcher/dynamicwatcher/watch.go index 098b3d04..99d8406c 100644 --- a/pkg/watcher/dynamicwatcher/watch.go +++ b/pkg/watcher/dynamicwatcher/watch.go @@ -144,8 +144,8 @@ func (wh *WatchHandler) chooseWatcher(res schema.GroupVersionResource, opts meta return wh.k8sClient.GetDynamicClient().Resource(res).Namespace("").Watch(context.Background(), opts) case "seccompprofiles": return wh.storageClient.SeccompProfiles("").Watch(context.Background(), opts) - default: - return wh.k8sClient.GetDynamicClient().Resource(res).Watch(context.Background(), opts) + case "operatorcommands": + wh.k8sClient.GetDynamicClient().Resource(res).Watch(context.Background(), opts) } return nil, fmt.Errorf("cannot watch for resource %s: %w", res.Resource, errNotImplemented) } From a44faf331d76e542418deeca9a92c56127474539 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 18 Sep 2024 07:58:19 +0000 Subject: [PATCH 18/23] Adding lister Signed-off-by: Amit Schendel --- pkg/watcher/dynamicwatcher/watch.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/watcher/dynamicwatcher/watch.go b/pkg/watcher/dynamicwatcher/watch.go index 99d8406c..fd09cc9c 100644 --- a/pkg/watcher/dynamicwatcher/watch.go +++ b/pkg/watcher/dynamicwatcher/watch.go @@ -215,6 +215,8 @@ func (wh *WatchHandler) chooseLister(res schema.GroupVersionResource, opts metav return wh.k8sClient.GetDynamicClient().Resource(res).Namespace("").List(context.Background(), opts) case "seccompprofiles": return wh.storageClient.SeccompProfiles("").List(context.Background(), opts) + case "operatorcommands": + wh.k8sClient.GetDynamicClient().Resource(res).List(context.Background(), opts) } return nil, errors2.NewNotFound(res.GroupResource(), "not implemented") } From 1ba2239ae9945047641e726ca6df6df21c70ef83 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 18 Sep 2024 08:30:14 +0000 Subject: [PATCH 19/23] Adding http tests to workflows Signed-off-by: Amit Schendel --- .github/workflows/component-tests.yaml | 1 + tests/chart/templates/node-agent/configmap.yaml | 1 + tests/chart/values.yaml | 1 + 3 files changed, 3 insertions(+) diff --git a/.github/workflows/component-tests.yaml b/.github/workflows/component-tests.yaml index e0947817..1ba77169 100644 --- a/.github/workflows/component-tests.yaml +++ b/.github/workflows/component-tests.yaml @@ -49,6 +49,7 @@ jobs: Test_07_RuleBindingApplyTest, Test_08_ApplicationProfilePatching, Test_10_MalwareDetectionTest, + Test_11_EndpointTest, # Test_10_DemoTest # Test_11_DuplicationTest ] diff --git a/tests/chart/templates/node-agent/configmap.yaml b/tests/chart/templates/node-agent/configmap.yaml index e1166887..ee1890c8 100644 --- a/tests/chart/templates/node-agent/configmap.yaml +++ b/tests/chart/templates/node-agent/configmap.yaml @@ -15,6 +15,7 @@ data: "runtimeDetectionEnabled": {{ eq .Values.capabilities.runtimeDetection "enable" }}, "networkServiceEnabled": {{ eq .Values.capabilities.networkPolicyService "enable" }}, "malwareDetectionEnabled": {{ eq .Values.capabilities.malwareDetection "enable" }}, + "httpDetectionEnabled": {{ eq .Values.capabilities.httpDetection "enable" }}, "initialDelay": "{{ .Values.nodeAgent.config.learningPeriod }}", "updateDataPeriod": "{{ .Values.nodeAgent.config.updatePeriod }}", "maxDelaySeconds": "{{ .Values.nodeAgent.config.maxDelaySeconds }}", diff --git a/tests/chart/values.yaml b/tests/chart/values.yaml index 534de197..1df339d5 100644 --- a/tests/chart/values.yaml +++ b/tests/chart/values.yaml @@ -11,6 +11,7 @@ capabilities: networkPolicyService: enable runtimeDetection: enable malwareDetection: enable + httpDetection: enable configurations: persistence: enable From 17f3385f0ffea92675241e34527167cd70ff9b67 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 18 Sep 2024 10:41:14 +0000 Subject: [PATCH 20/23] Fixing bug where we don't return Signed-off-by: Amit Schendel --- pkg/watcher/dynamicwatcher/watch.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/watcher/dynamicwatcher/watch.go b/pkg/watcher/dynamicwatcher/watch.go index fd09cc9c..58affa7e 100644 --- a/pkg/watcher/dynamicwatcher/watch.go +++ b/pkg/watcher/dynamicwatcher/watch.go @@ -145,7 +145,7 @@ func (wh *WatchHandler) chooseWatcher(res schema.GroupVersionResource, opts meta case "seccompprofiles": return wh.storageClient.SeccompProfiles("").Watch(context.Background(), opts) case "operatorcommands": - wh.k8sClient.GetDynamicClient().Resource(res).Watch(context.Background(), opts) + return wh.k8sClient.GetDynamicClient().Resource(res).Watch(context.Background(), opts) } return nil, fmt.Errorf("cannot watch for resource %s: %w", res.Resource, errNotImplemented) } @@ -216,7 +216,7 @@ func (wh *WatchHandler) chooseLister(res schema.GroupVersionResource, opts metav case "seccompprofiles": return wh.storageClient.SeccompProfiles("").List(context.Background(), opts) case "operatorcommands": - wh.k8sClient.GetDynamicClient().Resource(res).List(context.Background(), opts) + return wh.k8sClient.GetDynamicClient().Resource(res).List(context.Background(), opts) } return nil, errors2.NewNotFound(res.GroupResource(), "not implemented") } From ac4ce46e5044c24861542cdfedc573f3e9be19ef Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 18 Sep 2024 10:50:10 +0000 Subject: [PATCH 21/23] Adding default watcher with storage condition Signed-off-by: Amit Schendel --- pkg/watcher/dynamicwatcher/watch.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pkg/watcher/dynamicwatcher/watch.go b/pkg/watcher/dynamicwatcher/watch.go index 58affa7e..9f7380fe 100644 --- a/pkg/watcher/dynamicwatcher/watch.go +++ b/pkg/watcher/dynamicwatcher/watch.go @@ -18,7 +18,6 @@ import ( "github.com/kubescape/go-logger" "github.com/kubescape/go-logger/helpers" - errors2 "k8s.io/apimachinery/pkg/api/errors" k8sErrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -144,10 +143,14 @@ func (wh *WatchHandler) chooseWatcher(res schema.GroupVersionResource, opts meta return wh.k8sClient.GetDynamicClient().Resource(res).Namespace("").Watch(context.Background(), opts) case "seccompprofiles": return wh.storageClient.SeccompProfiles("").Watch(context.Background(), opts) - case "operatorcommands": + default: + // Make sure the resource version is not our storage, if so we panic. + if res.Group == kubescapeCustomResourceGroup { + panic("storage resources must use the storage client") + } + return wh.k8sClient.GetDynamicClient().Resource(res).Watch(context.Background(), opts) } - return nil, fmt.Errorf("cannot watch for resource %s: %w", res.Resource, errNotImplemented) } func (wh *WatchHandler) watchRetry(ctx context.Context, res schema.GroupVersionResource, watchOpts metav1.ListOptions, eventQueue *cooldownqueue.CooldownQueue) { @@ -215,10 +218,14 @@ func (wh *WatchHandler) chooseLister(res schema.GroupVersionResource, opts metav return wh.k8sClient.GetDynamicClient().Resource(res).Namespace("").List(context.Background(), opts) case "seccompprofiles": return wh.storageClient.SeccompProfiles("").List(context.Background(), opts) - case "operatorcommands": + default: + // Make sure the resource version is not our storage, if so we panic. + if res.Group == kubescapeCustomResourceGroup { + panic("storage resources must use the storage client") + } + return wh.k8sClient.GetDynamicClient().Resource(res).List(context.Background(), opts) } - return nil, errors2.NewNotFound(res.GroupResource(), "not implemented") } func (wh *WatchHandler) getExistingStorageObjects(ctx context.Context, res schema.GroupVersionResource, watchOpts metav1.ListOptions) (string, error) { From d8a7d19ded255719a6a684ded06f627dff0ffc63 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 18 Sep 2024 11:16:40 +0000 Subject: [PATCH 22/23] Moving panic handling to caller Signed-off-by: Amit Schendel --- pkg/watcher/dynamicwatcher/watch.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/watcher/dynamicwatcher/watch.go b/pkg/watcher/dynamicwatcher/watch.go index 9f7380fe..d67dbca9 100644 --- a/pkg/watcher/dynamicwatcher/watch.go +++ b/pkg/watcher/dynamicwatcher/watch.go @@ -146,7 +146,7 @@ func (wh *WatchHandler) chooseWatcher(res schema.GroupVersionResource, opts meta default: // Make sure the resource version is not our storage, if so we panic. if res.Group == kubescapeCustomResourceGroup { - panic("storage resources must use the storage client") + return nil, fmt.Errorf("resource must use the storage client %s: %w", res.Resource, errNotImplemented) } return wh.k8sClient.GetDynamicClient().Resource(res).Watch(context.Background(), opts) @@ -221,7 +221,7 @@ func (wh *WatchHandler) chooseLister(res schema.GroupVersionResource, opts metav default: // Make sure the resource version is not our storage, if so we panic. if res.Group == kubescapeCustomResourceGroup { - panic("storage resources must use the storage client") + return nil, fmt.Errorf("resource must use the storage client %s: %w", res.Resource, errNotImplemented) } return wh.k8sClient.GetDynamicClient().Resource(res).List(context.Background(), opts) From 273ae0993011708e1d4101cfdaa0d89701d558d2 Mon Sep 17 00:00:00 2001 From: Amit Schendel Date: Wed, 18 Sep 2024 13:46:29 +0000 Subject: [PATCH 23/23] Using a function instead of a for loop Signed-off-by: Amit Schendel --- pkg/containerwatcher/v1/container_watcher.go | 64 ++++++-------------- 1 file changed, 19 insertions(+), 45 deletions(-) diff --git a/pkg/containerwatcher/v1/container_watcher.go b/pkg/containerwatcher/v1/container_watcher.go index 785066b2..a09abd2b 100644 --- a/pkg/containerwatcher/v1/container_watcher.go +++ b/pkg/containerwatcher/v1/container_watcher.go @@ -170,11 +170,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportEvent(utils.CapabilitiesEventType, &event) // Report capabilities to event receivers - if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.CapabilitiesEventType) { - for receiver := range thirdPartyEventReceivers.Get(utils.CapabilitiesEventType).Iter() { - receiver.ReportEvent(utils.CapabilitiesEventType, &event) - } - } + reportEventToThirdPartyTracers(utils.CapabilitiesEventType, &event, thirdPartyEventReceivers) }) if err != nil { return nil, fmt.Errorf("creating capabilities worker pool: %w", err) @@ -205,11 +201,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli malwareManager.ReportEvent(utils.ExecveEventType, &event) // Report exec events to event receivers - if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.ExecveEventType) { - for receiver := range thirdPartyEventReceivers.Get(utils.ExecveEventType).Iter() { - receiver.ReportEvent(utils.ExecveEventType, &event) - } - } + reportEventToThirdPartyTracers(utils.ExecveEventType, &event, thirdPartyEventReceivers) }) if err != nil { return nil, fmt.Errorf("creating exec worker pool: %w", err) @@ -240,11 +232,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli malwareManager.ReportEvent(utils.OpenEventType, &event) // Report open events to event receivers - if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.OpenEventType) { - for receiver := range thirdPartyEventReceivers.Get(utils.OpenEventType).Iter() { - receiver.ReportEvent(utils.OpenEventType, &event) - } - } + reportEventToThirdPartyTracers(utils.OpenEventType, &event, thirdPartyEventReceivers) }) if err != nil { return nil, fmt.Errorf("creating open worker pool: %w", err) @@ -267,11 +255,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportEvent(utils.NetworkEventType, &event) // Report network events to event receivers - if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.NetworkEventType) { - for receiver := range thirdPartyEventReceivers.Get(utils.NetworkEventType).Iter() { - receiver.ReportEvent(utils.NetworkEventType, &event) - } - } + reportEventToThirdPartyTracers(utils.NetworkEventType, &event, thirdPartyEventReceivers) }) if err != nil { return nil, fmt.Errorf("creating network worker pool: %w", err) @@ -299,11 +283,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportEvent(utils.DnsEventType, &event) // Report DNS events to event receivers - if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.DnsEventType) { - for receiver := range thirdPartyEventReceivers.Get(utils.DnsEventType).Iter() { - receiver.ReportEvent(utils.DnsEventType, &event) - } - } + reportEventToThirdPartyTracers(utils.DnsEventType, &event, thirdPartyEventReceivers) }) if err != nil { return nil, fmt.Errorf("creating dns worker pool: %w", err) @@ -318,11 +298,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportEvent(utils.RandomXEventType, &event) // Report randomx events to event receivers - if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.RandomXEventType) { - for receiver := range thirdPartyEventReceivers.Get(utils.RandomXEventType).Iter() { - receiver.ReportEvent(utils.RandomXEventType, &event) - } - } + reportEventToThirdPartyTracers(utils.RandomXEventType, &event, thirdPartyEventReceivers) }) if err != nil { return nil, fmt.Errorf("creating randomx worker pool: %w", err) @@ -337,11 +313,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportEvent(utils.SymlinkEventType, &event) // Report symlink events to event receivers - if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.SymlinkEventType) { - for receiver := range thirdPartyEventReceivers.Get(utils.SymlinkEventType).Iter() { - receiver.ReportEvent(utils.SymlinkEventType, &event) - } - } + reportEventToThirdPartyTracers(utils.SymlinkEventType, &event, thirdPartyEventReceivers) }) if err != nil { return nil, fmt.Errorf("creating symlink worker pool: %w", err) @@ -356,11 +328,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportEvent(utils.HardlinkEventType, &event) // Report hardlink events to event receivers - if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.HardlinkEventType) { - for receiver := range thirdPartyEventReceivers.Get(utils.HardlinkEventType).Iter() { - receiver.ReportEvent(utils.HardlinkEventType, &event) - } - } + reportEventToThirdPartyTracers(utils.HardlinkEventType, &event, thirdPartyEventReceivers) }) if err != nil { return nil, fmt.Errorf("creating hardlink worker pool: %w", err) @@ -375,11 +343,7 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli ruleManager.ReportEvent(utils.SSHEventType, &event) // Report ssh events to event receivers - if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(utils.SSHEventType) { - for receiver := range thirdPartyEventReceivers.Get(utils.SSHEventType).Iter() { - receiver.ReportEvent(utils.SSHEventType, &event) - } - } + reportEventToThirdPartyTracers(utils.SSHEventType, &event, thirdPartyEventReceivers) }) if err != nil { return nil, fmt.Errorf("creating ssh worker pool: %w", err) @@ -402,6 +366,8 @@ func CreateIGContainerWatcher(cfg config.Config, applicationProfileManager appli metrics.ReportEvent(utils.HTTPEventType) applicationProfileManager.ReportHTTPEvent(k8sContainerID, &event) + + reportEventToThirdPartyTracers(utils.HTTPEventType, &event, thirdPartyEventReceivers) }) if err != nil { @@ -535,3 +501,11 @@ func (ch *IGContainerWatcher) Stop() { func (ch *IGContainerWatcher) Ready() bool { return ch.running } + +func reportEventToThirdPartyTracers(eventType utils.EventType, event utils.K8sEvent, thirdPartyEventReceivers *maps.SafeMap[utils.EventType, mapset.Set[containerwatcher.EventReceiver]]) { + if thirdPartyEventReceivers != nil && thirdPartyEventReceivers.Has(eventType) { + for receiver := range thirdPartyEventReceivers.Get(eventType).Iter() { + receiver.ReportEvent(eventType, event) + } + } +}