diff --git a/KubeArmor/BPF/system_monitor.c b/KubeArmor/BPF/system_monitor.c index d1f76feff..fe239f29e 100644 --- a/KubeArmor/BPF/system_monitor.c +++ b/KubeArmor/BPF/system_monitor.c @@ -1067,6 +1067,12 @@ static __always_inline u32 init_context(sys_context_t *context) // To check if subsequent alerts should be dropped per container static __always_inline bool should_drop_alerts_per_container(sys_context_t *context, struct pt_regs *ctx, u32 types, args_t *args) { #if LINUX_VERSION_CODE > KERNEL_VERSION(5, 2, 0) + + // throttling for host in case of apparmor is handled in userspace + if (context->pid_id == 0 && context->mnt_id == 0) { + return false; + } + u64 current_timestamp = bpf_ktime_get_ns(); struct outer_key key = { diff --git a/KubeArmor/config/config.go b/KubeArmor/config/config.go index 22ccb3b50..4a71d8700 100644 --- a/KubeArmor/config/config.go +++ b/KubeArmor/config/config.go @@ -56,10 +56,10 @@ type KubearmorConfig struct { StateAgent bool // enable KubeArmor state agent - AlertThrottling bool // Enable/Disable Alert Throttling - MaxAlertPerSec int // Maximum alerts allowed per second - ThrottleSec int // Number of seconds for which subsequent alerts will be dropped - AnnotateResources bool // enable annotations by kubearmor if kubearmor-controller is not present + AlertThrottling bool // Enable/Disable Alert Throttling + MaxAlertPerSec int32 // Maximum alerts allowed per second + ThrottleSec int32 // Number of seconds for which subsequent alerts will be dropped + AnnotateResources bool // enable annotations by kubearmor if kubearmor-controller is not present ProcFsMount string // path where procfs is hosted } @@ -325,8 +325,8 @@ func LoadConfig() error { GlobalCfg.StateAgent = viper.GetBool(ConfigStateAgent) GlobalCfg.AlertThrottling = viper.GetBool(ConfigAlertThrottling) - GlobalCfg.MaxAlertPerSec = viper.GetInt(ConfigMaxAlertPerSec) - GlobalCfg.ThrottleSec = viper.GetInt(ConfigThrottleSec) + GlobalCfg.MaxAlertPerSec = int32(viper.GetInt(ConfigMaxAlertPerSec)) + GlobalCfg.ThrottleSec = int32(viper.GetInt(ConfigThrottleSec)) GlobalCfg.AnnotateResources = viper.GetBool(ConfigAnnotateResources) GlobalCfg.ProcFsMount = viper.GetString(ConfigProcFsMount) diff --git a/KubeArmor/core/kubeUpdate.go b/KubeArmor/core/kubeUpdate.go index 491ba6cc3..882b9b5b6 100644 --- a/KubeArmor/core/kubeUpdate.go +++ b/KubeArmor/core/kubeUpdate.go @@ -2740,16 +2740,18 @@ func (dm *KubeArmorDaemon) WatchConfigMap() cache.InformerSynced { cfg.GlobalCfg.AlertThrottling = (cm.Data[cfg.ConfigAlertThrottling] == "true") } if _, ok := cm.Data[cfg.ConfigMaxAlertPerSec]; ok { - cfg.GlobalCfg.MaxAlertPerSec, err = strconv.Atoi(cm.Data[cfg.ConfigMaxAlertPerSec]) + maxAlertPerSec, err := strconv.ParseInt(cm.Data[cfg.ConfigMaxAlertPerSec], 10, 32) if err != nil { dm.Logger.Warnf("Error: %s", err) } + cfg.GlobalCfg.MaxAlertPerSec = int32(maxAlertPerSec) } - if _, ok := cm.Data[cfg.ConfigMaxAlertPerSec]; ok { - cfg.GlobalCfg.ThrottleSec, err = strconv.Atoi(cm.Data[cfg.ConfigThrottleSec]) + if _, ok := cm.Data[cfg.ConfigThrottleSec]; ok { + throttleSec, err := strconv.ParseInt(cm.Data[cfg.ConfigThrottleSec], 10, 32) if err != nil { dm.Logger.Warnf("Error: %s", err) } + cfg.GlobalCfg.ThrottleSec = int32(throttleSec) } dm.SystemMonitor.UpdateThrottlingConfig() @@ -2790,14 +2792,18 @@ func (dm *KubeArmorDaemon) WatchConfigMap() cache.InformerSynced { if _, ok := cm.Data[cfg.ConfigAlertThrottling]; ok { cfg.GlobalCfg.AlertThrottling = (cm.Data[cfg.ConfigAlertThrottling] == "true") } - cfg.GlobalCfg.MaxAlertPerSec, err = strconv.Atoi(cm.Data[cfg.ConfigMaxAlertPerSec]) + + maxAlertPerSec, err := strconv.ParseInt(cm.Data[cfg.ConfigMaxAlertPerSec], 10, 32) if err != nil { dm.Logger.Warnf("Error: %s", err) } - cfg.GlobalCfg.ThrottleSec, err = strconv.Atoi(cm.Data[cfg.ConfigThrottleSec]) + cfg.GlobalCfg.MaxAlertPerSec = int32(maxAlertPerSec) + + throttleSec, err := strconv.ParseInt(cm.Data[cfg.ConfigThrottleSec], 10, 32) if err != nil { dm.Logger.Warnf("Error: %s", err) } + cfg.GlobalCfg.ThrottleSec = int32(throttleSec) dm.SystemMonitor.UpdateThrottlingConfig() } }, diff --git a/KubeArmor/enforcer/bpflsm/enforcer.go b/KubeArmor/enforcer/bpflsm/enforcer.go index 963eb0f3e..7c3fbc1c4 100644 --- a/KubeArmor/enforcer/bpflsm/enforcer.go +++ b/KubeArmor/enforcer/bpflsm/enforcer.go @@ -375,8 +375,8 @@ func (be *BPFEnforcer) TraceEvents() { case mon.DropAlert: log.Operation = "AlertThreshold" log.Type = "SystemEvent" - log.MaxAlertsPerSec = int32(cfg.GlobalCfg.MaxAlertPerSec) - log.DroppingAlertsInterval = int32(cfg.GlobalCfg.ThrottleSec) + log.MaxAlertsPerSec = cfg.GlobalCfg.MaxAlertPerSec + log.DroppingAlertsInterval = cfg.GlobalCfg.ThrottleSec } // fallback logic if we don't receive source from BuildLogBase() if log.Operation != "Process" && len(log.Source) == 0 { diff --git a/KubeArmor/feeder/feeder.go b/KubeArmor/feeder/feeder.go index 8917b3d0d..c1c4203c1 100644 --- a/KubeArmor/feeder/feeder.go +++ b/KubeArmor/feeder/feeder.go @@ -579,6 +579,20 @@ func (fd *Feeder) PushLog(log tp.Log) { // gRPC output if log.Type == "MatchedPolicy" || log.Type == "MatchedHostPolicy" || log.Type == "SystemEvent" { + + // checking throttling condition for "Audit" alerts when enforcer is 'eBPF Monitor' + if cfg.GlobalCfg.AlertThrottling && ((strings.Contains(log.Action, "Audit") && log.Enforcer == "eBPF Monitor") || (log.Type == "MatchedHostPolicy" && (log.Enforcer == "AppArmor" || log.Enforcer == "eBPF Monitor"))) { + nsKey := fd.ContainerNsKey[log.ContainerID] + alert, throttle := fd.ShouldDropAlertsPerContainer(nsKey.PidNs, nsKey.MntNs) + if alert && throttle { + return + } else if alert && !throttle { + log.Operation = "AlertThreshold" + log.Type = "SystemEvent" + log.MaxAlertsPerSec = cfg.GlobalCfg.MaxAlertPerSec + log.DroppingAlertsInterval = cfg.GlobalCfg.ThrottleSec + } + } pbAlert := pb.Alert{} pbAlert.Timestamp = log.Timestamp diff --git a/KubeArmor/feeder/policyMatcher.go b/KubeArmor/feeder/policyMatcher.go index 9970c228b..c369291e3 100644 --- a/KubeArmor/feeder/policyMatcher.go +++ b/KubeArmor/feeder/policyMatcher.go @@ -1299,7 +1299,7 @@ func (fd *Feeder) UpdateMatchedPolicy(log tp.Log) tp.Log { break // break, so that once source is matched for a log it doesn't look for other cases } // match sources - if (!secPolicy.IsFromSource) || (secPolicy.IsFromSource && (secPolicy.Source == log.ParentProcessName || secPolicy.Source == log.ProcessName)) { + if (!secPolicy.IsFromSource) || (secPolicy.IsFromSource && (strings.HasPrefix(log.Source, secPolicy.Source+" ") || secPolicy.Source == log.ProcessName)) { matchedFlags := false protocol := fetchProtocol(log.Resource) @@ -1481,7 +1481,7 @@ func (fd *Feeder) UpdateMatchedPolicy(log tp.Log) tp.Log { continue } // match sources - if (!secPolicy.IsFromSource) || (secPolicy.IsFromSource && (secPolicy.Source == log.ParentProcessName || secPolicy.Source == log.ProcessName)) { + if (!secPolicy.IsFromSource) || (secPolicy.IsFromSource && (strings.HasPrefix(log.Source, secPolicy.Source+" ") || secPolicy.Source == log.ProcessName)) { skip := false for _, matchCapability := range strings.Split(secPolicy.Resource, ",") { @@ -1741,20 +1741,6 @@ func (fd *Feeder) UpdateMatchedPolicy(log tp.Log) tp.Log { return tp.Log{} } - // check for throttling for "Audit" alerts - if cfg.GlobalCfg.AlertThrottling && strings.Contains(log.Action, "Audit") { - nsKey := fd.ContainerNsKey[log.ContainerID] - alert, throttle := fd.ShouldDropAlertsPerContainer(nsKey.PidNs, nsKey.MntNs) - if alert && throttle { - return tp.Log{} - } else if alert && !throttle { - log.Operation = "AlertThreshold" - log.Type = "SystemEvent" - log.MaxAlertsPerSec = int32(cfg.GlobalCfg.MaxAlertPerSec) - log.DroppingAlertsInterval = int32(cfg.GlobalCfg.ThrottleSec) - } - } - return log } } else { // host @@ -1784,20 +1770,6 @@ func (fd *Feeder) UpdateMatchedPolicy(log tp.Log) tp.Log { return tp.Log{} } - // check for throttling for "Audit" alerts - if cfg.GlobalCfg.AlertThrottling && strings.Contains(log.Action, "Audit") { - nsKey := fd.ContainerNsKey[log.ContainerID] - alert, throttle := fd.ShouldDropAlertsPerContainer(nsKey.PidNs, nsKey.MntNs) - if alert && throttle { - return tp.Log{} - } else if alert && !throttle { - log.Operation = "AlertThreshold" - log.Type = "SystemEvent" - log.MaxAlertsPerSec = int32(cfg.GlobalCfg.MaxAlertPerSec) - log.DroppingAlertsInterval = int32(cfg.GlobalCfg.ThrottleSec) - } - } - return log } } diff --git a/KubeArmor/monitor/logUpdate.go b/KubeArmor/monitor/logUpdate.go index a1d4951fe..1462249dc 100644 --- a/KubeArmor/monitor/logUpdate.go +++ b/KubeArmor/monitor/logUpdate.go @@ -517,8 +517,8 @@ func (mon *SystemMonitor) UpdateLogs() { case DropAlert: // throttling alert log.Operation = "AlertThreshold" log.Type = "SystemEvent" - log.MaxAlertsPerSec = int32(cfg.GlobalCfg.MaxAlertPerSec) - log.DroppingAlertsInterval = int32(cfg.GlobalCfg.ThrottleSec) + log.MaxAlertsPerSec = cfg.GlobalCfg.MaxAlertPerSec + log.DroppingAlertsInterval = cfg.GlobalCfg.ThrottleSec default: continue