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

CI(tests): LFX term 2 Pre-task submission #1

Merged
merged 22 commits into from
May 25, 2024
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
7 changes: 5 additions & 2 deletions .github/workflows/ci-test-ginkgo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: ci-test-ginkgo

on:
push:
branches: [main]
branches: [main, lfx-pretask-submission, test-actions]
paths:
- "KubeArmor/**"
- "tests/**"
Expand All @@ -11,7 +11,7 @@ on:
- "pkg/KubeArmorOperator/**"
- "deployments/helm/**"
pull_request:
branches: [main]
branches: [main, lfx-pretask-submission]
paths:
- "KubeArmor/**"
- "tests/**"
Expand Down Expand Up @@ -91,6 +91,9 @@ jobs:
kubectl wait --timeout=1m --for=condition=ready pod -l kubearmor-app=kubearmor-controller -n kubearmor
kubectl get pods -A

- name: Add KubeArmor host visibility
run: ./.github/workflows/host-visibility.sh

- name: Test KubeArmor using Ginkgo
run: |
go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci-test-systemd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ name: ci-test-systemd

on:
push:
branches: [main]
branches: [main, test-actions, lfx-pretask-submission]
paths:
- "KubeArmor/**"
- "tests/**"
- "protobuf/**"
- ".github/workflows/ci-test-systemd.yml"
pull_request:
branches: [main]
branches: [main, lfx-pretask, lfx-pretask-submission]
paths:
- "KubeArmor/**"
- "tests/**"
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/host-visibility.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

# Edit the daemonset to add the -enableKubeArmorHostPolicy=true flag
# kubectl edit daemonset -n kubearmor <<EOF
# /args:/a \
# - -enableKubeArmorHostPolicy=true
# EOF

kubectl get daemonset -n kubearmor -o yaml > daemonset.yaml
sed -i '/args:/a \ - -enableKubeArmorHostPolicy=true' daemonset.yaml
kubectl apply -f daemonset.yaml

sleep 1m

# Apply annotations to the node
NODE_NAME=$(kubectl get nodes -o=jsonpath='{.items[0].metadata.name}')
kubectl annotate node $NODE_NAME "kubearmorvisibility=process,file,network,capabilities"
kubectl get no -o wide
4 changes: 4 additions & 0 deletions .github/workflows/install-k3s.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
# Copyright 2021 Authors of KubeArmor
# Set the hostname
# sudo hostnamectl set-hostname kubearmor-dev

echo "RUNTIME="$RUNTIME

Expand All @@ -15,3 +17,5 @@ if [ "$RUNTIME" == "crio" ]; then
fi

./contribution/k3s/install_k3s.sh

kubectl get no -o wide
4 changes: 2 additions & 2 deletions tests/k8s_env/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ build:
@go mod tidy
# run in two steps as syscall suite fails if run at the very end
# see - https://github.com/kubearmor/KubeArmor/issues/1269
@ginkgo --vv --flake-attempts=10 --timeout=10m syscalls/
@ginkgo -r --vv --flake-attempts=10 --timeout=30m --skip-package "syscalls"
@ginkgo --vv --flake-attempts=10 --timeout=10m --coverpkg=github.com/kubearmor/KubeArmor/tests/... syscalls/
@ginkgo -r --vv --flake-attempts=10 --timeout=30m --coverpkg=github.com/kubearmor/KubeArmor/tests/... --skip-package "syscalls"
.PHONY: test
test:
@ginkgo -r -v
24 changes: 12 additions & 12 deletions tests/k8s_env/blockposture/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ var _ = Describe("Posture", func() {
MatchRegexp("curl.*Could not resolve host: google.com"), true,
)

out, _, err := K8sExecInPod(wp, "wordpress-mysql", []string{"bash", "-c", "curl 142.250.193.46"})
Expect(err).To(BeNil())
fmt.Printf("---START---\n%s---END---\n", out)
Expect(out).To(MatchRegexp("<HTML>((?:.*\r?\n?)*)</HTML>"))
AssertCommand(
wp, "wordpress-mysql", []string{"bash", "-c", "curl 142.250.193.46"},
MatchRegexp("<HTML>((?:.*\r?\n?)*)</HTML>"), true,
)
// check policy violation alert
_, alerts, err := KarmorGetLogs(5*time.Second, 1)
Expect(err).To(BeNil())
Expand All @@ -101,16 +101,16 @@ var _ = Describe("Posture", func() {
Expect(err).To(BeNil())

//curl needs UDP for DNS resolution
sout, _, err := K8sExecInPod(wp, "wordpress-mysql", []string{"bash", "-c", "cat wp-config.php"})
Expect(err).To(BeNil())
fmt.Printf("---START---\n%s---END---\n", sout)
Expect(sout).To(MatchRegexp("cat.*Permission denied"))
AssertCommand(
wp, "wordpress-mysql", []string{"bash", "-c", "cat wp-config.php"},
MatchRegexp("cat.*Permission denied"), true,
)

//test that tcp is whitelisted
out, _, err := K8sExecInPod(wp, "wordpress-mysql", []string{"bash", "-c", "cat readme.html"})
Expect(err).To(BeNil())
fmt.Printf("---START---\n%s---END---\n", out)
Expect(out).To(MatchRegexp("<!DOCTYPE html>((?:.*\r?\n?)*)</html>"))
AssertCommand(
wp, "wordpress-mysql", []string{"bash", "-c", "cat readme.html"},
MatchRegexp("<!DOCTYPE html>((?:.*\r?\n?)*)</html>"), true,
)
// check policy violation alert
_, alerts, err := KarmorGetLogs(5*time.Second, 1)
Expect(err).To(BeNil())
Expand Down
16 changes: 16 additions & 0 deletions tests/k8s_env/hsp/hsp_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Authors of KubeArmor

package hsp_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestHsp(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Hsp Suite")
}
90 changes: 90 additions & 0 deletions tests/k8s_env/hsp/hsp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package hsp

import (
"fmt"
"time"

. "github.com/kubearmor/KubeArmor/tests/util"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var _ = BeforeSuite(func() {

// delete all HSPs
DeleteAllHsp()
})

var _ = AfterSuite(func() {

// delete all HSPs
DeleteAllHsp()
})

var _ = Describe("HSP", func() {

BeforeEach(func() {
time.Sleep(1 * time.Second)
})

AfterEach(func() {
KarmorLogStop()
err := DeleteAllHsp()
Expect(err).To(BeNil())
// wait for policy deletion
time.Sleep(2 * time.Second)
})

Describe("Policy Apply", func() {
It("can block access to date command", func() {
// Apply the Host Security Policy
err := K8sApplyFile("manifests/hsp-kubearmor-dev-proc-path-block.yaml")
Expect(err).To(BeNil())

// Start Kubearmor Logs
err = KarmorLogStart("policy", "", "Process", "")
Expect(err).To(BeNil())

// Execute the date command
out, err := ExecCommandHost([]string{"bash", "-c", "date"})
Expect(err).NotTo(BeNil())
fmt.Printf("---START---\n%s---END---\n", out)
Expect(out).To(MatchRegexp(".*Permission denied"))

// check policy violation alert
_, alerts, err := KarmorGetLogs(5*time.Second, 1)
Expect(err).To(BeNil())
Expect(len(alerts)).To(BeNumerically(">=", 1))
Expect(alerts[0].PolicyName).To(Equal("hsp-kubearmor-dev-proc-path-block"))
Expect(alerts[0].Action).To(Equal("Block"))

// Execute a command that should not be blocked
out, err = ExecCommandHost([]string{"bash", "-c", "ls"})
Expect(err).To(BeNil())
Expect(out).NotTo(MatchRegexp(".*Permission denied"))
})

It("can block access to /etc/hostname file", func() {
// Apply the Host Security Policy
err := K8sApplyFile("manifests/hsp-kubearmor-dev-file-path-block.yaml")
Expect(err).To(BeNil())

// Start Kubearmor Logs
err = KarmorLogStart("policy", "", "File", "")
Expect(err).To(BeNil())

// Try to access the /etc/hostname file
out, err := ExecCommandHost([]string{"bash", "-c", "cat /etc/hostname"})
Expect(err).NotTo(BeNil())
fmt.Printf("---START---\n%s---END---\n", out)
Expect(out).To(MatchRegexp(".*Permission denied"))

// check policy violation alert
_, alerts, err := KarmorGetLogs(5*time.Second, 1)
Expect(err).To(BeNil())
Expect(len(alerts)).To(BeNumerically(">=", 1))
Expect(alerts[0].PolicyName).To(Equal("hsp-kubearmor-dev-file-path-block"))
Expect(alerts[0].Action).To(Equal("Block"))
})
})
})
19 changes: 19 additions & 0 deletions tests/k8s_env/hsp/manifests/hsp-kubearmor-dev-file-path-block.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: security.kubearmor.com/v1
kind: KubeArmorHostPolicy
metadata:
name: hsp-kubearmor-dev-file-path-block
spec:
nodeSelector:
matchLabels:
kubernetes.io/os: linux
severity: 5
file:
matchPaths:
- path: /etc/hostname
action:
Block


# test
# $ cat /etc/hostname
# cat: /etc/hostname: Permission denied
24 changes: 24 additions & 0 deletions tests/k8s_env/hsp/manifests/hsp-kubearmor-dev-proc-path-block.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: security.kubearmor.com/v1
kind: KubeArmorHostPolicy
metadata:
name: hsp-kubearmor-dev-proc-path-block
spec:
nodeSelector:
matchLabels:
kubernetes.io/os: linux
severity: 5
process:
matchPaths:
- path: /bin/date
- path: /usr/bin/date

action:
Block

# kubearmor-dev_test_04

# test
# $ bash -c date
# bash: 1: date: Permission denied
# $ bash -c ls
# ls ...
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
name: non-existent-container-block-ls
namespace: multicontainer
spec:
severity: 5
selector:
matchLabels:
container: multicontainer
kubearmor.io/container.name: "[container-1, non-existent-container ]"
process:
matchPaths:
- path: /bin/ls
# ls
action:
Block
31 changes: 31 additions & 0 deletions tests/k8s_env/multicontainer/multicontainer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,37 @@ var _ = Describe("Multicontainer", func() {
Expect(sout).NotTo(MatchRegexp(".*Permission denied"))

})

It("Can enforce on container-1 even if non-existent container is present in array", func() {
err := K8sDeploymentCheck("multicontainer-deployment", "multicontainer", 5*time.Minute)
Expect(err).To(BeNil())

err = K8sApply([]string{"manifests/non-existent-container-block-ls.yaml"})
Expect(err).To(BeNil())

err = KarmorLogStart("policy", "multicontainer", "Process", multicontainer)
Expect(err).To(BeNil())

// container-1 should not run ls
sout, _, err := K8sExecInPodWithContainer(multicontainer, "multicontainer", "container-1", []string{"bash", "-c", "ls"})
Expect(err).To(BeNil())
fmt.Printf("---START---\n%s---END---\n", sout)
Expect(sout).To(MatchRegexp(".*Permission denied"))

// check policy violation alert
_, alerts, err := KarmorGetLogs(10*time.Second, 1)
Expect(err).To(BeNil())
Expect(len(alerts)).To(BeNumerically(">=", 1))
Expect(alerts[0].PolicyName).To(Equal("non-existent-container-block-ls"))
Expect(alerts[0].Severity).To(Equal("5"))
Expect(alerts[0].ContainerName).To(Equal("container-1"))

// container-2 should run ls
sout, _, err = K8sExecInPodWithContainer(multicontainer, "multicontainer", "container-2", []string{"bash", "-c", "ls"})
Expect(err).To(BeNil())
fmt.Printf("---START---\n%s---END---\n", sout)
Expect(sout).NotTo(MatchRegexp(".*Permission denied"))
})
})

})
2 changes: 1 addition & 1 deletion tests/nonk8s_env/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
.PHONY: build
build:
@go mod tidy
@ginkgo -r --vv --flake-attempts=10 --timeout=30m
@ginkgo -r --vv --flake-attempts=10 --timeout=30m --coverpkg=github.com/kubearmor/KubeArmor/tests/...

.PHONY: test
test:
Expand Down
16 changes: 16 additions & 0 deletions tests/nonk8s_env/hsp/hsp_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Authors of KubeArmor

package hsp_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestHsp(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Hsp Suite")
}
Loading
Loading