Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhancement(monitor): enable dropping events at the kernel level #1087

Merged
merged 2 commits into from
Mar 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,032 changes: 604 additions & 428 deletions KubeArmor/BPF/system_monitor.c

Large diffs are not rendered by default.

36 changes: 19 additions & 17 deletions KubeArmor/enforcer/bpflsm/bpffs.go → KubeArmor/common/bpffs.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Authors of KubeArmor

package bpflsm
package common

// This implementation for automounting bpffs has been inspired from
// Cilium - https://github.com/cilium/cilium/blob/master/pkg/bpf/bpffs_linux.go
Expand All @@ -11,8 +11,10 @@ import (
"os"
"sync"

"github.com/cilium/cilium/pkg/mountinfo"
"golang.org/x/sys/unix"

"github.com/cilium/cilium/pkg/mountinfo"
kg "github.com/kubearmor/KubeArmor/KubeArmor/log"
)

var (
Expand Down Expand Up @@ -52,23 +54,23 @@ var (
//
// We also check and error if there have been multiple mounts at
// the same point. See - https://patchwork.kernel.org/project/netdevbpf/patch/20220223131833.51991-1-laoar.shao@gmail.com/
func (be *BPFEnforcer) CheckOrMountBPFFs(bpfRoot string) {
func CheckOrMountBPFFs(bpfRoot string) {
mountOnce.Do(func() {
if err := be.checkOrMountBPFFs(bpfRoot); err != nil {
be.Logger.Err("Unable to mount BPF filesystem")
if err := checkOrMountBPFFs(bpfRoot); err != nil {
kg.Err("Unable to mount BPF filesystem")
}
daemon1024 marked this conversation as resolved.
Show resolved Hide resolved
})
}

func (be *BPFEnforcer) checkOrMountBPFFs(bpfRoot string) error {
func checkOrMountBPFFs(bpfRoot string) error {
if bpfRoot == defaultBPFFsPath {
// mount BPFFs at the default path
if err := be.checkOrMountDefaultLocations(); err != nil {
if err := checkOrMountDefaultLocations(); err != nil {
return err
}
} else {
// the user specified a custom path for BPFFs
if err := be.checkOrMountCustomLocation(bpfRoot); err != nil {
if err := checkOrMountCustomLocation(bpfRoot); err != nil {
return err
}
}
Expand All @@ -84,7 +86,7 @@ func (be *BPFEnforcer) checkOrMountBPFFs(bpfRoot string) error {
return nil
}

func (be *BPFEnforcer) checkOrMountDefaultLocations() error {
func checkOrMountDefaultLocations() error {
// Check whether /sys/fs/bpf has a BPFFS mount.
mounted, bpffsInstance, err := mountinfo.IsMountFS(mountinfo.FilesystemTypeBPFFS, mapRoot)
if err != nil {
Expand All @@ -94,7 +96,7 @@ func (be *BPFEnforcer) checkOrMountDefaultLocations() error {
// If /sys/fs/bpf is not mounted at all, we should mount
// BPFFS there.
if !mounted {
be.Logger.Printf("Mounting BPF Filesystem at %s", mapRoot)
kg.Printf("Mounting BPF Filesystem at %s", mapRoot)
if err := mountFs(); err != nil {
return err
}
Expand All @@ -109,7 +111,7 @@ func (be *BPFEnforcer) checkOrMountDefaultLocations() error {
// mount BPFFS in /run/kubearmor/bpffs inside the container.
// This will allow operation of Kubearmor but will result in
// unmounting of the filesystem when the pod is restarted.
be.Logger.Warnf("BPF filesystem is going to be mounted automatically "+
kg.Warnf("BPF filesystem is going to be mounted automatically "+
"in %s. However, it probably means that Kubearmor is running "+
"inside container and BPFFS is not mounted on the host. ",
mapRoot)
Expand All @@ -123,21 +125,21 @@ func (be *BPFEnforcer) checkOrMountDefaultLocations() error {
return err
}
if !cMounted {
be.Logger.Printf("Mounting BPF Filesystem at %s", mapRoot)
kg.Printf("Mounting BPF Filesystem at %s", mapRoot)
if err := mountFs(); err != nil {
return err
}
} else if !cBpffsInstance {
be.Logger.Printf("%s is mounted but has a different filesystem than BPFFS", fallbackBPFFsPath)
kg.Printf("%s is mounted but has a different filesystem than BPFFS", fallbackBPFFsPath)
}
}

be.Logger.Printf("Detected mounted BPF filesystem at %s", mapRoot)
kg.Printf("Detected mounted BPF filesystem at %s", mapRoot)

return nil
}

func (be *BPFEnforcer) checkOrMountCustomLocation(bpfRoot string) error {
func checkOrMountCustomLocation(bpfRoot string) error {
setMapRoot(bpfRoot)

// Check whether the custom location has a BPFFS mount.
Expand All @@ -149,7 +151,7 @@ func (be *BPFEnforcer) checkOrMountCustomLocation(bpfRoot string) error {
// If the custom location has no mount, let's mount BPFFS there.
if !mounted {
setMapRoot(bpfRoot)
be.Logger.Printf("Mounting BPF Filesystem at %s", mapRoot)
kg.Printf("Mounting BPF Filesystem at %s", mapRoot)
if err := mountFs(); err != nil {
return err
}
Expand All @@ -163,7 +165,7 @@ func (be *BPFEnforcer) checkOrMountCustomLocation(bpfRoot string) error {
return fmt.Errorf("mount in the custom directory %s has a different filesystem than BPFFS", bpfRoot)
}

be.Logger.Printf("Detected mounted BPF filesystem at %s", mapRoot)
kg.Printf("Detected mounted BPF filesystem at %s", mapRoot)

return nil
}
Expand Down
14 changes: 5 additions & 9 deletions KubeArmor/core/containerdHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ func (ch *ContainerdHandler) GetDeletedContainerdContainers(containers map[strin

for globalContainerID := range ch.containers {
if _, ok := containers[globalContainerID]; !ok {
deletedContainers[globalContainerID] = context.TODO()
delete(ch.containers, globalContainerID)
}
}
Expand Down Expand Up @@ -313,11 +314,11 @@ func (dm *KubeArmorDaemon) UpdateContainerdContainer(ctx context.Context, contai

if dm.SystemMonitor != nil && cfg.GlobalCfg.Policy {
// update NsMap
dm.SystemMonitor.AddContainerIDToNsMap(containerID, container.PidNS, container.MntNS)
dm.SystemMonitor.AddContainerIDToNsMap(containerID, container.NamespaceName, container.PidNS, container.MntNS)
dm.RuntimeEnforcer.RegisterContainer(containerID, container.PidNS, container.MntNS)
}

dm.Logger.Printf("Detected a container (added/%s)", containerID[:12])
dm.Logger.Printf("Detected a container (added/%s/pidns=%d/mntns=%d)", containerID[:12], container.PidNS, container.MntNS)

} else if action == "destroy" {
dm.ContainersLock.Lock()
Expand Down Expand Up @@ -348,11 +349,11 @@ func (dm *KubeArmorDaemon) UpdateContainerdContainer(ctx context.Context, contai

if dm.SystemMonitor != nil && cfg.GlobalCfg.Policy {
// update NsMap
dm.SystemMonitor.DeleteContainerIDFromNsMap(containerID)
dm.SystemMonitor.DeleteContainerIDFromNsMap(containerID, container.NamespaceName, container.PidNS, container.MntNS)
dm.RuntimeEnforcer.UnregisterContainer(containerID)
}

dm.Logger.Printf("Detected a container (removed/%s)", containerID[:12])
dm.Logger.Printf("Detected a container (removed/%s/pidns=%d/mntns=%d)", containerID[:12], container.PidNS, container.MntNS)
}

return true
Expand Down Expand Up @@ -380,11 +381,6 @@ func (dm *KubeArmorDaemon) MonitorContainerdEvents() {
default:
containers := Containerd.GetContainerdContainers()

if len(containers) == len(Containerd.containers) {
time.Sleep(time.Millisecond * 100)
continue
}

invalidContainers := []string{}

newContainers := Containerd.GetNewContainerdContainers(containers)
Expand Down
11 changes: 2 additions & 9 deletions KubeArmor/core/crioHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ func (dm *KubeArmorDaemon) UpdateCrioContainer(ctx context.Context, containerID,

if dm.SystemMonitor != nil && cfg.GlobalCfg.Policy {
// update NsMap
dm.SystemMonitor.AddContainerIDToNsMap(containerID, container.PidNS, container.MntNS)
dm.SystemMonitor.AddContainerIDToNsMap(containerID, container.NamespaceName, container.PidNS, container.MntNS)
dm.RuntimeEnforcer.RegisterContainer(containerID, container.PidNS, container.MntNS)
}

Expand Down Expand Up @@ -288,7 +288,7 @@ func (dm *KubeArmorDaemon) UpdateCrioContainer(ctx context.Context, containerID,

if dm.SystemMonitor != nil && cfg.GlobalCfg.Policy {
// update NsMap
dm.SystemMonitor.DeleteContainerIDFromNsMap(containerID)
dm.SystemMonitor.DeleteContainerIDFromNsMap(containerID, container.NamespaceName, container.PidNS, container.MntNS)
dm.RuntimeEnforcer.UnregisterContainer(containerID)
}

Expand Down Expand Up @@ -323,13 +323,6 @@ func (dm *KubeArmorDaemon) MonitorCrioEvents() {
return
}

// if number of stored container IDs is equal to number of container IDs
// returned by the API, no containers added/deleted
if len(containers) == len(Crio.containers) {
time.Sleep(time.Millisecond * 10)
continue
}

invalidContainers := []string{}

newContainers := Crio.GetNewCrioContainers(containers)
Expand Down
6 changes: 3 additions & 3 deletions KubeArmor/core/dockerHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ func (dm *KubeArmorDaemon) GetAlreadyDeployedDockerContainers() {

if dm.SystemMonitor != nil && cfg.GlobalCfg.Policy {
// update NsMap
dm.SystemMonitor.AddContainerIDToNsMap(container.ContainerID, container.PidNS, container.MntNS)
dm.SystemMonitor.AddContainerIDToNsMap(container.ContainerID, container.NamespaceName, container.PidNS, container.MntNS)
dm.RuntimeEnforcer.RegisterContainer(container.ContainerID, container.PidNS, container.MntNS)
}

Expand Down Expand Up @@ -353,7 +353,7 @@ func (dm *KubeArmorDaemon) UpdateDockerContainer(containerID, action string) {

if dm.SystemMonitor != nil && cfg.GlobalCfg.Policy {
// update NsMap
dm.SystemMonitor.AddContainerIDToNsMap(containerID, container.PidNS, container.MntNS)
dm.SystemMonitor.AddContainerIDToNsMap(containerID, container.NamespaceName, container.PidNS, container.MntNS)
dm.RuntimeEnforcer.RegisterContainer(containerID, container.PidNS, container.MntNS)
}

Expand Down Expand Up @@ -392,7 +392,7 @@ func (dm *KubeArmorDaemon) UpdateDockerContainer(containerID, action string) {

if dm.SystemMonitor != nil && cfg.GlobalCfg.Policy {
// update NsMap
dm.SystemMonitor.DeleteContainerIDFromNsMap(containerID)
dm.SystemMonitor.DeleteContainerIDFromNsMap(containerID, container.NamespaceName, container.PidNS, container.MntNS)
dm.RuntimeEnforcer.UnregisterContainer(containerID)
}

Expand Down
6 changes: 3 additions & 3 deletions KubeArmor/core/kubeArmor.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,8 @@ func (dm *KubeArmorDaemon) CloseSystemMonitor() bool {
// ====================== //

// InitRuntimeEnforcer Function
func (dm *KubeArmorDaemon) InitRuntimeEnforcer() bool {
dm.RuntimeEnforcer = efc.NewRuntimeEnforcer(dm.Node, dm.Logger)
func (dm *KubeArmorDaemon) InitRuntimeEnforcer(pinpath string) bool {
dm.RuntimeEnforcer = efc.NewRuntimeEnforcer(dm.Node, pinpath, dm.Logger)
return dm.RuntimeEnforcer != nil
}

Expand Down Expand Up @@ -447,7 +447,7 @@ func KubeArmor() {
dm.Logger.Print("Started to monitor system events")

// initialize runtime enforcer
if !dm.InitRuntimeEnforcer() {
if !dm.InitRuntimeEnforcer(dm.SystemMonitor.PinPath) {
dm.Logger.Print("Disabled KubeArmor Enforcer since No LSM is enabled")
} else {
dm.Logger.Print("Initialized KubeArmor Enforcer")
Expand Down
Loading