Skip to content

Commit

Permalink
Merge pull request kubearmor#668 from kloudmax/main
Browse files Browse the repository at this point in the history
Update Policy Matcher
  • Loading branch information
nam-jaehyun authored Apr 15, 2022
2 parents 4faeb7f + 9f2816d commit 251a133
Show file tree
Hide file tree
Showing 65 changed files with 2,670 additions and 2,965 deletions.
37 changes: 14 additions & 23 deletions KubeArmor/BPF/system_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,14 @@ typedef struct args {
} args_t;

BPF_HASH(args_map, u64, args_t);
BPF_HASH(exec_map, u64, struct path);
BPF_HASH(file_map, u64, struct path);

typedef struct buffers {
u8 buf[MAX_BUFFER_SIZE];
} bufs_t;

BPF_PERCPU_ARRAY(bufs, bufs_t, 2);
BPF_PERCPU_ARRAY(bufs_offset, u32, 2);
BPF_PERCPU_ARRAY(bufs, bufs_t, 3);
BPF_PERCPU_ARRAY(bufs_offset, u32, 3);

BPF_PERF_OUTPUT(sys_events);

Expand Down Expand Up @@ -199,7 +198,7 @@ static __always_inline u32 get_task_ns_pid(struct task_struct *task)

static __always_inline u32 get_task_ppid(struct task_struct *task)
{
return task->real_parent->pid;
return task->parent->pid;
}

// == Pid NS Management == //
Expand Down Expand Up @@ -546,37 +545,29 @@ static __always_inline bool prepend_path(struct path *path, bufs_t *string_p, in
return true;
}

static __always_inline struct path* load_file_p(int buf_type)
static __always_inline struct path* load_file_p()
{
u64 pid_tgid = bpf_get_current_pid_tgid();

if (buf_type == EXEC_BUF_TYPE) {
struct path *p = exec_map.lookup(&pid_tgid);
exec_map.delete(&pid_tgid);
return p;
}

// FILE_BUF_TYPE
struct path *p = file_map.lookup(&pid_tgid);
file_map.delete(&pid_tgid);
return p;
}

static __always_inline int save_file_to_buffer(bufs_t *bufs_p, int buf_type)
static __always_inline int save_file_to_buffer(bufs_t *bufs_p, void *ptr)
{
struct path *path = load_file_p(buf_type);
struct path *path = load_file_p();

bufs_t *string_p = get_buffer(buf_type);
bufs_t *string_p = get_buffer(FILE_BUF_TYPE);
if (string_p == NULL)
return -1;
return save_str_to_buffer(bufs_p, ptr);

if (!prepend_path(path, string_p, buf_type)) {
return -1;
if (!prepend_path(path, string_p, FILE_BUF_TYPE)) {
return save_str_to_buffer(bufs_p, ptr);
}

u32 *off = get_buffer_offset(buf_type);
u32 *off = get_buffer_offset(FILE_BUF_TYPE);
if (off == NULL)
return -1;
return save_str_to_buffer(bufs_p, ptr);

return save_str_to_buffer(bufs_p, (void *)&string_p->buf[*off]);
}
Expand Down Expand Up @@ -673,8 +664,8 @@ static __always_inline int save_args_to_buffer(u64 types, args_t *args)
save_to_buffer(bufs_p, (void*)&(args->args[i]), sizeof(int), OPEN_FLAGS_T);
break;
case FILE_TYPE_T:
if (!save_file_to_buffer(bufs_p, FILE_BUF_TYPE))
break;
save_file_to_buffer(bufs_p, (void *)args->args[i]);
break;
case STR_T:
save_str_to_buffer(bufs_p, (void *)args->args[i]);
break;
Expand Down
10 changes: 6 additions & 4 deletions KubeArmor/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ run: build
cd $(CRDDIR); kubectl apply -f KubeArmorPolicy.yaml
cd $(CRDDIR); kubectl apply -f KubeArmorHostPolicy.yaml
cd $(CURDIR); sudo rm -f /tmp/kubearmor.log
cd $(CURDIR); sudo -E ./kubearmor -logPath=/tmp/kubearmor.log -enableKubeArmorPolicy=true -enableKubeArmorHostPolicy=true
cd $(CURDIR); sudo -E ./kubearmor -logPath=/tmp/kubearmor.log -enableKubeArmorPolicy=true -enableKubeArmorHostPolicy=true -hostVisibility=process,file,network,capabilities

.PHONY: run-host-only
run-host-only: build
cd $(CRDDIR); kubectl apply -f KubeArmorHostPolicy.yaml
cd $(CURDIR); sudo rm -f /tmp/kubearmor.log
cd $(CURDIR); sudo -E ./kubearmor -logPath=/tmp/kubearmor.log -enableKubeArmorPolicy=false -enableKubeArmorHostPolicy=true
cd $(CURDIR); sudo -E ./kubearmor -logPath=/tmp/kubearmor.log -enableKubeArmorPolicy=false -enableKubeArmorHostPolicy=true -hostVisibility=process,file,network,capabilities

.PHONY: test
test:
Expand Down Expand Up @@ -69,7 +69,8 @@ ifeq (, $(shell which golint))
GOLINT_TMP_DIR=$$(mktemp -d) ;\
cd $$GOLINT_TMP_DIR ;\
go mod init tmp ;\
go get -u golang.org/x/lint/golint ;\
go get golang.org/x/lint/golint ;\
go install golang.org/x/lint/golint ;\
rm -rf $$GOLINT_TMP_DIR ;\
}
endif
Expand All @@ -83,7 +84,8 @@ ifeq (, $(shell which gosec))
GOSEC_TMP_DIR=$$(mktemp -d) ;\
cd $$GOSEC_TMP_DIR ;\
go mod init tmp ;\
go get -u github.com/securego/gosec/v2/cmd/gosec ;\
go get github.com/securego/gosec/v2/cmd/gosec ;\
go install github.com/securego/gosec/v2/cmd/gosec ;\
rm -rf $$GOSEC_TMP_DIR ;\
}
endif
Expand Down
2 changes: 1 addition & 1 deletion KubeArmor/build/test_kubearmor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ fi
cd $ARMOR_HOME/tests

# test scenarios
./test-scenarios-local.sh -testAll
./test-scenarios-local.sh

RESULT=$?

Expand Down
47 changes: 24 additions & 23 deletions KubeArmor/core/kubeArmor.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,18 @@ func KubeArmor() {
dm.Node.KernelVersion = kl.GetCommandOutputWithoutErr("uname", []string{"-r"})
dm.Node.KernelVersion = strings.TrimSuffix(dm.Node.KernelVersion, "\n")

dm.Node.PolicyEnabled = tp.KubeArmorPolicyEnabled
kg.Print("Updated the node information")

cfg.GlobalCfg.Policy = false
cfg.GlobalCfg.HostPolicy = true
} else if cfg.GlobalCfg.K8sEnv {
if !K8s.InitK8sClient() {
kg.Err("Failed to initialize Kubernetes client")

kg.Print("Updated the node information")
// destroy the daemon
dm.DestroyKubeArmorDaemon()

return
}

} else if K8s.InitK8sClient() {
kg.Print("Initialized Kubernetes client")

// set the flag
Expand All @@ -360,28 +364,25 @@ func KubeArmor() {
// wait for a while
time.Sleep(time.Second * 1)

if dm.Node.NodeIP == "" {
for timeout := 0; timeout <= 60; timeout++ {
if dm.Node.NodeIP != "" {
break
}
for timeout := 0; timeout <= 60; timeout++ {
if dm.Node.NodeIP != "" {
break
}

if dm.Node.NodeIP == "" && timeout == 60 {
kg.Print("The node information is not available, terminating KubeArmor")
if dm.Node.NodeIP == "" && timeout == 60 {
kg.Print("The node information is not available, terminating KubeArmor")

// destroy the daemon
dm.DestroyKubeArmorDaemon()
// destroy the daemon
dm.DestroyKubeArmorDaemon()

return
}
return
}

kg.Print("The node information is not available")
kg.Print("The node information is not available")

// wait for a while
time.Sleep(time.Second * 1)
}
// wait for a while
time.Sleep(time.Second * 1)
}

}

// == //
Expand Down Expand Up @@ -525,7 +526,7 @@ func KubeArmor() {
dm.Logger.Print("Started to monitor host security policies")
}

if !dm.K8sEnabled && cfg.GlobalCfg.HostPolicy {
if !cfg.GlobalCfg.K8sEnv && cfg.GlobalCfg.HostPolicy {
policyService := &policy.ServiceServer{}
policyService.UpdateHostPolicy = dm.ParseAndUpdateHostSecurityPolicy

Expand All @@ -545,7 +546,7 @@ func KubeArmor() {

// == //

if !cfg.GlobalCfg.K8sEnv && (cfg.GlobalCfg.KVMAgent || cfg.GlobalCfg.HostPolicy) {
if cfg.GlobalCfg.KVMAgent || (!cfg.GlobalCfg.K8sEnv && cfg.GlobalCfg.HostPolicy) {
// Restore and apply all kubearmor host security policies
dm.restoreKubeArmorHostPolicies()
}
Expand Down
83 changes: 47 additions & 36 deletions KubeArmor/core/kubeUpdate.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,13 @@ func (dm *KubeArmorDaemon) WatchK8sPods() {
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"
}
}
}

// == Exception == //
Expand Down Expand Up @@ -1665,21 +1672,6 @@ func (dm *KubeArmorDaemon) WatchHostSecurityPolicies() {
// == HostPolicy Backup & Restore == //
// ================================= //

// removeBackUpPolicy Function
func (dm *KubeArmorDaemon) removeBackUpPolicy(name string) {

fname := cfg.PolicyDir + name + ".yaml"
// Check for "/opt/kubearmor/policies" path. If dir not found, create the same
if _, err := os.Stat(fname); err != nil {
kg.Printf("Backup policy [%v] not exist", fname)
return
}

if err := os.Remove(fname); err != nil {
kg.Errf("unable to delete file:%s err=%s", fname, err.Error())
}
}

// backupKubeArmorHostPolicy Function
func (dm *KubeArmorDaemon) backupKubeArmorHostPolicy(policy tp.HostSecurityPolicy) {
// Check for "/opt/kubearmor/policies" path. If dir not found, create the same
Expand Down Expand Up @@ -1729,31 +1721,25 @@ func (dm *KubeArmorDaemon) restoreKubeArmorHostPolicies() {
}
}

// WatchDefaultPosture Function
func (dm *KubeArmorDaemon) WatchDefaultPosture() {
nsWatcher, err := K8s.K8sClient.CoreV1().Namespaces().Watch(context.Background(), metav1.ListOptions{})
defer nsWatcher.Stop()
if err == nil {
for resp := range nsWatcher.ResultChan() {
if resp.Type == watch.Modified || resp.Type == watch.Added {
if ns, ok := resp.Object.(*corev1.Namespace); ok {
defaultPosture := tp.DefaultPosture{
FileAction: validateDefaultPosture("kubearmor-file-posture", ns, cfg.GlobalCfg.DefaultFilePosture),
NetworkAction: validateDefaultPosture("kubearmor-network-posture", ns, cfg.GlobalCfg.DefaultNetworkPosture),
CapabilitiesAction: validateDefaultPosture("kubearmor-capabilities-posture", ns, cfg.GlobalCfg.DefaultCapabilitiesPosture),
}
dm.UpdateDefaultPosture(string(resp.Type), ns.Name, defaultPosture)
// removeBackUpPolicy Function
func (dm *KubeArmorDaemon) removeBackUpPolicy(name string) {

}
} else if resp.Type == watch.Deleted {
if ns, ok := resp.Object.(*corev1.Namespace); ok {
dm.UpdateDefaultPosture(string(resp.Type), ns.Name, tp.DefaultPosture{})
}
}
}
fname := cfg.PolicyDir + name + ".yaml"
// Check for "/opt/kubearmor/policies" path. If dir not found, create the same
if _, err := os.Stat(fname); err != nil {
kg.Printf("Backup policy [%v] not exist", fname)
return
}

if err := os.Remove(fname); err != nil {
kg.Errf("unable to delete file:%s err=%s", fname, err.Error())
}
}

// ===================== //
// == Default Posture == //
// ===================== //

func validateDefaultPosture(key string, ns *corev1.Namespace, defaultPosture string) string {
if posture, ok := ns.Annotations[key]; ok {
if posture == "audit" || posture == "Audit" {
Expand Down Expand Up @@ -1809,3 +1795,28 @@ func (dm *KubeArmorDaemon) UpdateDefaultPosture(action string, namespace string,
}
}
}

// WatchDefaultPosture Function
func (dm *KubeArmorDaemon) WatchDefaultPosture() {
nsWatcher, err := K8s.K8sClient.CoreV1().Namespaces().Watch(context.Background(), metav1.ListOptions{})
defer nsWatcher.Stop()
if err == nil {
for resp := range nsWatcher.ResultChan() {
if resp.Type == watch.Modified || resp.Type == watch.Added {
if ns, ok := resp.Object.(*corev1.Namespace); ok {
defaultPosture := tp.DefaultPosture{
FileAction: validateDefaultPosture("kubearmor-file-posture", ns, cfg.GlobalCfg.DefaultFilePosture),
NetworkAction: validateDefaultPosture("kubearmor-network-posture", ns, cfg.GlobalCfg.DefaultNetworkPosture),
CapabilitiesAction: validateDefaultPosture("kubearmor-capabilities-posture", ns, cfg.GlobalCfg.DefaultCapabilitiesPosture),
}
dm.UpdateDefaultPosture(string(resp.Type), ns.Name, defaultPosture)

}
} else if resp.Type == watch.Deleted {
if ns, ok := resp.Object.(*corev1.Namespace); ok {
dm.UpdateDefaultPosture(string(resp.Type), ns.Name, tp.DefaultPosture{})
}
}
}
}
}
10 changes: 8 additions & 2 deletions KubeArmor/enforcer/appArmorEnforcer.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ func (ae *AppArmorEnforcer) UnregisterAppArmorHostProfile() bool {

// UpdateAppArmorProfile Function
func (ae *AppArmorEnforcer) UpdateAppArmorProfile(endPoint tp.EndPoint, appArmorProfile string, securityPolicies []tp.SecurityPolicy) {
if policyCount, newProfile, ok := ae.GenerateAppArmorProfile(appArmorProfile, endPoint.DefaultPosture, securityPolicies); ok {
if policyCount, newProfile, ok := ae.GenerateAppArmorProfile(appArmorProfile, securityPolicies, endPoint.DefaultPosture); ok {
newfile, err := os.Create(filepath.Clean("/etc/apparmor.d/" + appArmorProfile))
if err != nil {
ae.Logger.Warnf("Unable to open an AppArmor profile (%s, %s)", appArmorProfile, err.Error())
Expand Down Expand Up @@ -526,7 +526,13 @@ func (ae *AppArmorEnforcer) UpdateSecurityPolicies(endPoint tp.EndPoint) {

// UpdateAppArmorHostProfile Function
func (ae *AppArmorEnforcer) UpdateAppArmorHostProfile(secPolicies []tp.HostSecurityPolicy) {
if policyCount, newProfile, ok := ae.GenerateAppArmorHostProfile(secPolicies); ok {
globalDefaultPosture := tp.DefaultPosture{
FileAction: cfg.GlobalCfg.DefaultFilePosture,
NetworkAction: cfg.GlobalCfg.DefaultNetworkPosture,
CapabilitiesAction: cfg.GlobalCfg.DefaultCapabilitiesPosture,
}

if policyCount, newProfile, ok := ae.GenerateAppArmorHostProfile(secPolicies, globalDefaultPosture); ok {
newfile, err := os.Create(filepath.Clean(appArmorHostFile))
if err != nil {
ae.Logger.Warnf("Unable to open the KubeArmor host profile in %s (%s)", cfg.GlobalCfg.Host, err.Error())
Expand Down
Loading

0 comments on commit 251a133

Please sign in to comment.