Skip to content

Commit

Permalink
Merge pull request #682 from nam-jaehyun/main
Browse files Browse the repository at this point in the history
Fix Audit Mode and minor bugs
  • Loading branch information
nam-jaehyun authored May 4, 2022
2 parents 68f3ba2 + bb9f2bb commit 6451e04
Show file tree
Hide file tree
Showing 57 changed files with 809 additions and 578 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature-request-enhancement.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ E.g., KubeArmor could support protecting the earth from malicious aliens.

**Is your feature request related to a problem? Please describe the use case.**

A description of what the problem/use case is. E.g. Protect the earth from been decimated by nefarious aliens.
A description of what the problem/use case is. E.g. Protect the earth from being decimated by nefarious aliens.

**Describe the solution you'd like**

Expand Down
25 changes: 17 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,26 @@

4. If the issue involves code changes you need to install development env using this [Development Guide](contribution/development_guide.md).

# Scope of contribution
# Scope of Contribution

Contributions are not necessarily in the form of code changes. Kubearmor community can benefit from contributions such as:
Contributions are not necessarily in the form of code changes. KubeArmor community can benefit from contributions such as:

1. [Policy-Templates](https://github.com/kubearmor/policy-templates): Users are welcome to contribute policy-templates for their workloads. The workloads have to be generic enough such that it benefits the wider community. E.g., if someone brings up a system policy restricting access to nginx process that would be useful in multiple scenarios and for the wider community then come up with a policy-template that is specific to your proprietary application.
1. [Policy-Templates](https://github.com/kubearmor/policy-templates)

Users are welcome to contribute policy-templates for their workloads. The workloads have to be generic enough such that it benefits the wider community. E.g., if someone brings up a system policy restricting access to nginx process that would be useful in multiple scenarios and for the wider community then come up with a policy-template that is specific to your proprietary application.

2. Blogs
a. explaining feature use (KVMService, Event Auditor, Visibility, etc)
b. How to use Kubearmor to protect your workload? Specific use-cases you may have. Please do not shy away from getting as technical as you can.
c. ... put your topic of interest here ...

3. Feedback to the community. Just helping advance any discussion on KubeArmor Slack, Community meetings, office hours will make a big difference.
a. Explain The use of KubeArmor's features (KVMService, Event Auditor, Visibility, etc)

b. Describe How to use KubeArmor to protect your workload with specific use-cases you may have. Please do not shy away from getting as technical as you can.

c. Put your topic of interest

3. Feedback to the community

Just helping advance any discussion on KubeArmor Slack, Community meetings, office hours will make a big difference.

4. Talking about KubeArmor in meetups

4. Talking about Kubearmor in meetups. We would certainly encourage users or devs of kubearmor to talk about it in open/closed forums. The community can help with logistics such as compiling/feedback on slide-decks, technical diagrams, etc.
We would certainly encourage users or devs of KubeArmor to talk about it in open/closed forums. The community can help with logistics such as compiling/feedback on slide-decks, technical diagrams, etc.
2 changes: 2 additions & 0 deletions KubeArmor/.goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,5 @@ nfpms:
rpm:
dependencies:
- bcc-tools
- policycoreutils-devel
- setools-console
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 @@ -243,13 +252,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 @@ -376,13 +378,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 @@ -509,19 +504,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 @@ -556,7 +542,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 @@ -577,8 +563,6 @@ func (dm *KubeArmorDaemon) WatchK8sPods() {
}
}

// == AppArmor == //

if dm.RuntimeEnforcer != nil && dm.RuntimeEnforcer.EnforcerType == "AppArmor" {
appArmorAnnotations := map[string]string{}
updateAppArmor := false
Expand Down Expand Up @@ -647,71 +631,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
Loading

0 comments on commit 6451e04

Please sign in to comment.