Skip to content

Commit

Permalink
fix audit mode (w/ policy matcher)
Browse files Browse the repository at this point in the history
Signed-off-by: Jaehyun Nam <[email protected]>
  • Loading branch information
nam-jaehyun committed Apr 27, 2022
1 parent 441a380 commit 2ce14fb
Show file tree
Hide file tree
Showing 12 changed files with 245 additions and 359 deletions.
3 changes: 2 additions & 1 deletion KubeArmor/core/kubeArmor.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func (dm *KubeArmorDaemon) CloseLogger() bool {

// InitSystemMonitor Function
func (dm *KubeArmorDaemon) InitSystemMonitor() bool {
dm.SystemMonitor = mon.NewSystemMonitor(dm.Node, dm.Logger, &dm.Containers, &dm.ContainersLock,
dm.SystemMonitor = mon.NewSystemMonitor(&dm.Node, dm.Logger, &dm.Containers, &dm.ContainersLock,
&dm.ActivePidMap, &dm.ActiveHostPidMap, &dm.ActivePidMapLock, &dm.ActiveHostMap, &dm.ActiveHostMapLock)
if dm.SystemMonitor == nil {
return false
Expand Down Expand Up @@ -330,6 +330,7 @@ func KubeArmor() {

// Enable KubeArmorHostPolicy for both VM and KVMAgent and in non-k8s env
if cfg.GlobalCfg.KVMAgent || (!cfg.GlobalCfg.K8sEnv && cfg.GlobalCfg.HostPolicy) {
dm.Node.NodeName = cfg.GlobalCfg.Host
dm.Node.NodeIP = kl.GetExternalIPAddr()

dm.Node.Annotations = map[string]string{}
Expand Down
111 changes: 15 additions & 96 deletions KubeArmor/core/kubeUpdate.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ func (dm *KubeArmorDaemon) HandleNodeAnnotations(node *tp.Node) {
node.Annotations["kubearmor-policy"] = "audited"
}
}

if kl.IsInK8sCluster() && strings.Contains(string(lsm), "selinux") {
// exception: KubeArmor in a daemonset even though SELinux is enabled
if node.Annotations["kubearmor-policy"] == "enabled" {
node.Annotations["kubearmor-policy"] = "audited"
}
}
}

if node.Annotations["kubearmor-policy"] == "enabled" {
Expand Down Expand Up @@ -94,6 +101,9 @@ func (dm *KubeArmorDaemon) WatchK8sNodes() {

node := tp.Node{}

node.ClusterName = cfg.GlobalCfg.Cluster
node.NodeName = cfg.GlobalCfg.Host

for _, address := range event.Object.Status.Addresses {
if address.Type == "InternalIP" {
node.NodeIP = address.Address
Expand Down Expand Up @@ -190,7 +200,6 @@ func (dm *KubeArmorDaemon) UpdateEndPointWithPod(action string, pod tp.K8sPod) {

newPoint.Containers = []string{}
newPoint.AppArmorProfiles = []string{}
newPoint.SELinuxProfiles = []string{}

// update containers
for k := range pod.Containers {
Expand Down Expand Up @@ -236,13 +245,6 @@ func (dm *KubeArmorDaemon) UpdateEndPointWithPod(action string, pod tp.K8sPod) {
}
dm.DefaultPosturesLock.Unlock()

// update selinux profile names to the endpoint
for k, v := range pod.Annotations {
if strings.HasPrefix(k, "kubearmor-selinux") {
newPoint.SELinuxProfiles = append(newPoint.SELinuxProfiles, v)
}
}

// update security policies with the identities
newPoint.SecurityPolicies = dm.GetSecurityPolicies(newPoint.Identities)

Expand Down Expand Up @@ -362,13 +364,6 @@ func (dm *KubeArmorDaemon) UpdateEndPointWithPod(action string, pod tp.K8sPod) {
}
dm.DefaultPosturesLock.Unlock()

// update selinux profile names to the endpoint
for k, v := range pod.Annotations {
if strings.HasPrefix(k, "kubearmor-selinux") {
newEndPoint.SELinuxProfiles = append(newEndPoint.SELinuxProfiles, v)
}
}

// get security policies according to the updated identities
newEndPoint.SecurityPolicies = dm.GetSecurityPolicies(newEndPoint.Identities)

Expand Down Expand Up @@ -495,19 +490,10 @@ func (dm *KubeArmorDaemon) WatchK8sPods() {
if pod.Annotations["kubearmor-policy"] == "enabled" {
pod.Annotations["kubearmor-policy"] = "audited"
}
} else if lsm, err := ioutil.ReadFile("/sys/kernel/security/lsm"); err == nil {
if !strings.Contains(string(lsm), "apparmor") && !strings.Contains(string(lsm), "selinux") {
// exception: neither AppArmor nor SELinux
if pod.Annotations["kubearmor-policy"] == "enabled" {
pod.Annotations["kubearmor-policy"] = "audited"
}
}

if kl.IsInK8sCluster() && strings.Contains(string(lsm), "selinux") {
// exception: KubeArmor in a daemonset even though SELinux is enabled
if pod.Annotations["kubearmor-policy"] == "enabled" {
pod.Annotations["kubearmor-policy"] = "audited"
}
} else if dm.RuntimeEnforcer != nil && dm.RuntimeEnforcer.EnforcerType == "SELinux" {
// exception: no SELinux support for containers
if pod.Annotations["kubearmor-policy"] == "enabled" {
pod.Annotations["kubearmor-policy"] = "audited"
}
}

Expand Down Expand Up @@ -542,7 +528,7 @@ func (dm *KubeArmorDaemon) WatchK8sPods() {
pod.Annotations["kubearmor-visibility"] = cfg.GlobalCfg.Visibility
}

// == Skip if already patched == //
// == AppArmor == //

if event.Type == "ADDED" || event.Type == "MODIFIED" {
exist := false
Expand All @@ -563,8 +549,6 @@ func (dm *KubeArmorDaemon) WatchK8sPods() {
}
}

// == AppArmor == //

if dm.RuntimeEnforcer != nil && dm.RuntimeEnforcer.EnforcerType == "AppArmor" {
appArmorAnnotations := map[string]string{}
updateAppArmor := false
Expand Down Expand Up @@ -633,71 +617,6 @@ func (dm *KubeArmorDaemon) WatchK8sPods() {
}
}

// == SELinux == //

if dm.RuntimeEnforcer != nil && dm.RuntimeEnforcer.EnforcerType == "SELinux" {
seLinuxAnnotations := map[string]string{}
updateSELinux := false

for k, v := range pod.Annotations {
if strings.HasPrefix(k, "kubearmor-selinux") {
containerName := strings.Split(k, "/")[1]
seLinuxAnnotations[containerName] = v
}
}

for _, container := range event.Object.Spec.Containers {
if _, ok := seLinuxAnnotations[container.Name]; !ok {
seLinuxAnnotations[container.Name] = "kubearmor-" + pod.Metadata["namespaceName"] + "-" + container.Name
updateSELinux = true
}
}

if event.Type == "ADDED" {
// update selinux profiles
dm.RuntimeEnforcer.UpdateSELinuxProfiles(pod.Metadata["podName"], "ADDED", seLinuxAnnotations)

if updateSELinux && pod.Annotations["kubearmor-policy"] == "enabled" {
if deploymentName, ok := pod.Metadata["deploymentName"]; ok {
// patch the deployment with selinux annotations
if err := K8s.PatchDeploymentWithSELinuxAnnotations(pod.Metadata["namespaceName"], deploymentName, seLinuxAnnotations); err != nil {
dm.Logger.Errf("Failed to update SELinux Annotations for KubeArmor (%s/%s/%s, %s)", pod.Metadata["namespaceName"], deploymentName, pod.Metadata["podName"], err.Error())
} else {
dm.Logger.Printf("Patched SELinux Annotations for KubeArmor (%s/%s/%s)", pod.Metadata["namespaceName"], deploymentName, pod.Metadata["podName"])
}
pod.Annotations["kubearmor-policy"] = "patched"
}
}
} else if event.Type == "MODIFIED" {
for _, k8spod := range dm.K8sPods {
if k8spod.Metadata["namespaceName"] == pod.Metadata["namespaceName"] && k8spod.Metadata["podName"] == pod.Metadata["podName"] {
prevPolicyEnabled := "disabled"

if val, ok := k8spod.Annotations["kubearmor-policy"]; ok {
prevPolicyEnabled = val
}

if updateSELinux && prevPolicyEnabled != "enabled" && pod.Annotations["kubearmor-policy"] == "enabled" {
if deploymentName, ok := pod.Metadata["deploymentName"]; ok {
// patch the deployment with selinux annotations
if err := K8s.PatchDeploymentWithSELinuxAnnotations(pod.Metadata["namespaceName"], deploymentName, seLinuxAnnotations); err != nil {
dm.Logger.Errf("Failed to update SELinux Annotations for KubeArmor (%s/%s/%s, %s)", pod.Metadata["namespaceName"], deploymentName, pod.Metadata["podName"], err.Error())
} else {
dm.Logger.Printf("Patched SELinux Annotations for KubeArmor (%s/%s/%s)", pod.Metadata["namespaceName"], deploymentName, pod.Metadata["podName"])
}
pod.Annotations["kubearmor-policy"] = "patched"
}
}

break
}
}
} else if event.Type == "DELETED" {
// update selinux profiles
dm.RuntimeEnforcer.UpdateSELinuxProfiles(pod.Metadata["podName"], "DELETED", seLinuxAnnotations)
}
}

dm.K8sPodsLock.Lock()

if event.Type == "ADDED" {
Expand Down
22 changes: 5 additions & 17 deletions KubeArmor/enforcer/appArmorHostProfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,8 +575,6 @@ func (ae *AppArmorEnforcer) GenerateHostProfileBody(securityPolicies []tp.HostSe
for _, path := range secPolicy.Spec.Process.MatchPaths {
if path.Action == "Allow" {
ae.AllowedHostProcessMatchPaths(path, fromSources)
} else if path.Action == "Audit" {
//
} else if path.Action == "Block" {
ae.BlockedHostProcessMatchPaths(path, &processBlackList, fromSources)
}
Expand All @@ -586,18 +584,14 @@ func (ae *AppArmorEnforcer) GenerateHostProfileBody(securityPolicies []tp.HostSe
for _, dir := range secPolicy.Spec.Process.MatchDirectories {
if dir.Action == "Allow" {
ae.AllowedHostProcessMatchDirectories(dir, fromSources)
} else if dir.Action == "Audit" {
//
} else if dir.Action == "Block" {
ae.BlockedHostProcessMatchDirectories(dir, &processBlackList, fromSources)
}
}
}
if len(secPolicy.Spec.Process.MatchPatterns) > 0 {
for _, pat := range secPolicy.Spec.Process.MatchPatterns {
if pat.Action == "Audit" {
//
} else if pat.Action == "Block" {
if pat.Action == "Block" {
ae.BlockedHostProcessMatchPatterns(pat, &processBlackList)
}
}
Expand All @@ -607,8 +601,6 @@ func (ae *AppArmorEnforcer) GenerateHostProfileBody(securityPolicies []tp.HostSe
for _, path := range secPolicy.Spec.File.MatchPaths {
if path.Action == "Allow" {
ae.AllowedHostFileMatchPaths(path, fromSources)
} else if path.Action == "Audit" {
//
} else if path.Action == "Block" {
ae.BlockedHostFileMatchPaths(path, &fileBlackList, fromSources)
}
Expand All @@ -618,18 +610,14 @@ func (ae *AppArmorEnforcer) GenerateHostProfileBody(securityPolicies []tp.HostSe
for _, dir := range secPolicy.Spec.File.MatchDirectories {
if dir.Action == "Allow" {
ae.AllowedHostFileMatchDirectories(dir, fromSources)
} else if dir.Action == "Audit" {
//
} else if dir.Action == "Block" {
ae.BlockedHostFileMatchDirectories(dir, &fileBlackList, fromSources)
}
}
}
if len(secPolicy.Spec.File.MatchPatterns) > 0 {
for _, pat := range secPolicy.Spec.File.MatchPatterns {
if pat.Action == "Audit" {
//
} else if pat.Action == "Block" {
if pat.Action == "Block" {
ae.BlockedHostFileMatchPatterns(pat, &fileBlackList)
}
}
Expand Down Expand Up @@ -718,15 +706,15 @@ func (ae *AppArmorEnforcer) GenerateHostProfileBody(securityPolicies []tp.HostSe
file = false
}

if defaultPosture.FileAction != "block" && file {
if file {
bodyFromSource = bodyFromSource + " file,\n"
}

if defaultPosture.FileAction != "block" && network {
if network {
bodyFromSource = bodyFromSource + " network,\n"
}

if defaultPosture.CapabilitiesAction != "block" && capability {
if capability {
bodyFromSource = bodyFromSource + " capability,\n"
}

Expand Down
12 changes: 0 additions & 12 deletions KubeArmor/enforcer/appArmorProfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -752,8 +752,6 @@ func (ae *AppArmorEnforcer) GenerateProfileBody(securityPolicies []tp.SecurityPo
for _, path := range secPolicy.Spec.Process.MatchPaths {
if path.Action == "Allow" {
ae.AllowedProcessMatchPaths(path, &processWhiteList, fromSources)
} else if path.Action == "Audit" {
//
} else if path.Action == "Block" {
ae.BlockedProcessMatchPaths(path, &processBlackList, fromSources)
}
Expand All @@ -763,8 +761,6 @@ func (ae *AppArmorEnforcer) GenerateProfileBody(securityPolicies []tp.SecurityPo
for _, dir := range secPolicy.Spec.Process.MatchDirectories {
if dir.Action == "Allow" {
ae.AllowedProcessMatchDirectories(dir, &processWhiteList, fromSources)
} else if dir.Action == "Audit" {
//
} else if dir.Action == "Block" {
ae.BlockedProcessMatchDirectories(dir, &processBlackList, fromSources)
}
Expand All @@ -774,8 +770,6 @@ func (ae *AppArmorEnforcer) GenerateProfileBody(securityPolicies []tp.SecurityPo
for _, pat := range secPolicy.Spec.Process.MatchPatterns {
if pat.Action == "Allow" {
ae.AllowedProcessMatchPatterns(pat, &processWhiteList)
} else if pat.Action == "Audit" {
//
} else if pat.Action == "Block" {
ae.BlockedProcessMatchPatterns(pat, &processBlackList)
}
Expand All @@ -786,8 +780,6 @@ func (ae *AppArmorEnforcer) GenerateProfileBody(securityPolicies []tp.SecurityPo
for _, path := range secPolicy.Spec.File.MatchPaths {
if path.Action == "Allow" {
ae.AllowedFileMatchPaths(path, &fileWhiteList, fromSources)
} else if path.Action == "Audit" {
//
} else if path.Action == "Block" {
ae.BlockedFileMatchPaths(path, &fileBlackList, fromSources)
}
Expand All @@ -797,8 +789,6 @@ func (ae *AppArmorEnforcer) GenerateProfileBody(securityPolicies []tp.SecurityPo
for _, dir := range secPolicy.Spec.File.MatchDirectories {
if dir.Action == "Allow" {
ae.AllowedFileMatchDirectories(dir, &fileWhiteList, fromSources)
} else if dir.Action == "Audit" {
//
} else if dir.Action == "Block" {
ae.BlockedFileMatchDirectories(dir, &fileBlackList, fromSources)
}
Expand All @@ -808,8 +798,6 @@ func (ae *AppArmorEnforcer) GenerateProfileBody(securityPolicies []tp.SecurityPo
for _, pat := range secPolicy.Spec.File.MatchPatterns {
if pat.Action == "Allow" {
ae.AllowedFileMatchPatterns(pat, &fileWhiteList)
} else if pat.Action == "Audit" {
//
} else if pat.Action == "Block" {
ae.BlockedFileMatchPatterns(pat, &fileBlackList)
}
Expand Down
12 changes: 6 additions & 6 deletions KubeArmor/feeder/feeder.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ func (fd *Feeder) PushMessage(level, message string) {
func (fd *Feeder) PushLog(log tp.Log) {
log = fd.UpdateMatchedPolicy(log)

if log.UpdatedTime == "" {
if log.Source == "" {
return
}

Expand Down Expand Up @@ -571,8 +571,8 @@ func (fd *Feeder) PushLog(log tp.Log) {
pbAlert.Timestamp = log.Timestamp
pbAlert.UpdatedTime = log.UpdatedTime

pbAlert.ClusterName = cfg.GlobalCfg.Cluster
pbAlert.HostName = cfg.GlobalCfg.Host
pbAlert.ClusterName = fd.Node.ClusterName
pbAlert.HostName = fd.Node.NodeName

pbAlert.NamespaceName = log.NamespaceName
pbAlert.PodName = log.PodName
Expand Down Expand Up @@ -634,14 +634,14 @@ func (fd *Feeder) PushLog(log tp.Log) {
default:
}
}
} else { // ContainerLog
} else { // ContainerLog || HostLog
pbLog := pb.Log{}

pbLog.Timestamp = log.Timestamp
pbLog.UpdatedTime = log.UpdatedTime

pbLog.ClusterName = cfg.GlobalCfg.Cluster
pbLog.HostName = cfg.GlobalCfg.Host
pbLog.ClusterName = fd.Node.ClusterName
pbLog.HostName = fd.Node.NodeName

pbLog.NamespaceName = log.NamespaceName
pbLog.PodName = log.PodName
Expand Down
Loading

0 comments on commit 2ce14fb

Please sign in to comment.