Skip to content

Commit

Permalink
Add k8s env HSP test suite
Browse files Browse the repository at this point in the history
Signed-off-by: Navin Chandra <[email protected]>
  • Loading branch information
navin772 committed Aug 31, 2024
1 parent 5e79204 commit 4ef501e
Show file tree
Hide file tree
Showing 12 changed files with 545 additions and 0 deletions.
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 2024 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")
}
258 changes: 258 additions & 0 deletions tests/k8s_env/hsp/hsp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2024 Authors of KubeArmor

package hsp

import (
"time"

. "github.com/kubearmor/KubeArmor/tests/util"

Check warning on line 9 in tests/k8s_env/hsp/hsp_test.go

View workflow job for this annotation

GitHub Actions / go-lint-tests

should not use dot imports
. "github.com/onsi/ginkgo/v2"

Check warning on line 10 in tests/k8s_env/hsp/hsp_test.go

View workflow job for this annotation

GitHub Actions / go-lint-tests

should not use dot imports
. "github.com/onsi/gomega"

Check warning on line 11 in tests/k8s_env/hsp/hsp_test.go

View workflow job for this annotation

GitHub Actions / go-lint-tests

should not use dot imports
)

var _ = Describe("Non-k8s HSP tests", func() {

AfterEach(func() {
KarmorLogStop()
err := DeleteAllHsp()
Expect(err).To(BeNil())
})

Describe("HSP file path block", func() {

It("can block access to /etc/hostname on the host", func() {

err := K8sApplyFile("res/hsp-kubearmor-dev-file-path-block.yaml")
Expect(err).To(BeNil())

// Start the karmor logs
err = KarmorLogStart("policy", "", "File", "")
Expect(err).To(BeNil())

// Access the /etc/hostname file
out, err := ExecCommandHost([]string{"bash", "-c", "cat /etc/hostname"})
Expect(err).NotTo(BeNil())
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].Severity).To(Equal("5"))
Expect(alerts[0].Action).To(Equal("Block"))

})
})

Describe("HSP Process path block", func() {

It("can block execution of diff command in host", func() {

err := K8sApplyFile("res/hsp-kubearmor-dev-proc-path-block.yaml")
Expect(err).To(BeNil())

// Start the karmor logs
err = KarmorLogStart("policy", "", "Process", "")
Expect(err).To(BeNil())

// call the diff command
out, err := ExecCommandHost([]string{"bash", "-c", "diff --help"})
Expect(err).NotTo(BeNil())
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].Severity).To(Equal("5"))
Expect(alerts[0].Action).To(Equal("Block"))
})
})

Describe("HSP dir block from source", func() {

It("can allow access to everything except /etc/default/* from head", func() {

err := K8sApplyFile("res/hsp-kubearmor-dev-file-dir-block-fromSource.yaml")
Expect(err).To(BeNil())

// Start the karmor logs
err = KarmorLogStart("policy", "", "File", "")
Expect(err).To(BeNil())

// call the head command
out, err := ExecCommandHost([]string{"bash", "-c", "head /etc/hostname"})
Expect(err).To(BeNil())
Expect(out).NotTo(MatchRegexp(".*Permission denied"))

// check policy violation alert
_, alerts, err := KarmorGetLogs(5*time.Second, 1)
Expect(err).To(BeNil())
Expect(len(alerts)).To(BeNumerically("==", 0))
})

It("can block access to /etc/default/* from head", func() {

err := K8sApplyFile("res/hsp-kubearmor-dev-file-dir-block-fromSource.yaml")
Expect(err).To(BeNil())

// Start the karmor logs
err = KarmorLogStart("policy", "", "File", "")
Expect(err).To(BeNil())

// call the head command
out, err := ExecCommandHost([]string{"bash", "-c", "head /etc/default/useradd"})
Expect(err).NotTo(BeNil())
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-dir-block-fromsource"))
Expect(alerts[0].Severity).To(Equal("5"))
Expect(alerts[0].Action).To(Equal("Block"))
})
})

// Describe("HSP file audit", func() {

// It("can audit access to /etc/passwd", func() {

// err := K8sApplyFile("res/hsp-kubearmor-dev-file-path-audit.yaml")
// Expect(err).To(BeNil())

// // Start the karmor logs
// err = KarmorLogStart("policy", "", "File", "")
// Expect(err).To(BeNil())

// // try to access the /etc/passwd file
// out, err := ExecCommandHost([]string{"bash", "-c", "cat /etc/passwd"})
// Expect(err).To(BeNil())
// Expect(out).ToNot(MatchRegexp(".*Permission denied")) // should not block - ToNot match the regex

// // check audit alerts
// _, alerts, err := KarmorGetLogs(5*time.Second, 1)
// Expect(err).To(BeNil())
// Expect(len(alerts)).To(BeNumerically(">=", 1)) // Not generatting alerts on audit policy k8s hsp
// Expect(alerts[0].PolicyName).To(Equal("hsp-kubearmor-dev-file-path-audit"))
// Expect(alerts[0].Severity).To(Equal("5"))
// Expect(alerts[0].Action).To(Equal("Audit"))
// })
// })

Describe("HSP path block from source", func() {

It("It can block access to /etc/hostname from head", func() {

err := K8sApplyFile("res/hsp-kubearmor-dev-file-path-block-fromSource.yaml")
Expect(err).To(BeNil())

// Start the karmor logs
err = KarmorLogStart("policy", "", "File", "")
Expect(err).To(BeNil())

// try to access the /etc/hostname file from head
out, err := ExecCommandHost([]string{"bash", "-c", "head /etc/hostname"})
Expect(err).NotTo(BeNil())
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-fromsource"))
Expect(alerts[0].Severity).To(Equal("5"))
Expect(alerts[0].Action).To(Equal("Block"))
})
})

// Describe("HSP Process path block from source", func() {

// FIt("can block date command from bash", func() {

// err := K8sApplyFile("res/hsp-kubearmor-dev-proc-path-block-fromSource.yaml")
// Expect(err).To(BeNil())

// // Start the karmor logs
// err = KarmorLogStart("policy", "", "Process", "")
// Expect(err).To(BeNil())

// out, _ := ExecCommandHost([]string{"which", "bash"})
// fmt.Println("Using bash at:", out)

// // call the date command from bash
// out, err = ExecCommandHost([]string{"bash", "-c", "date"})
// Expect(err).NotTo(BeNil())
// Expect(out).To(MatchRegexp(".*Permission denied"))

// // execute ls command from bash
// out2, err := ExecCommandHost([]string{"bash", "-c", "ls"})
// Expect(err).To(BeNil())
// Expect(out2).NotTo(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-fromsource"))
// Expect(alerts[0].Severity).To(Equal("5"))
// Expect(alerts[0].Action).To(Equal("Block"))
// })
// })

Describe("HSP Process path block", func() {

It("can block diff command", func() {

err := K8sApplyFile("res/hsp-kubearmor-dev-proc-path-block.yaml")
Expect(err).To(BeNil())

// Start the karmor logs
err = KarmorLogStart("policy", "", "Process", "")
Expect(err).To(BeNil())

// run diff command
out, err := ExecCommandHost([]string{"bash", "-c", "diff"})
Expect(err).NotTo(BeNil())
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].Severity).To(Equal("5"))
Expect(alerts[0].Action).To(Equal("Block"))
})
})

Describe("HSP Network path block", func() {

It("can block access to UDP protocol from curl", func() {

err := K8sApplyFile("res/hsp-kubearmor-dev-udp-block.yaml")
Expect(err).To(BeNil())

// Start the karmor logs
err = KarmorLogStart("policy", "", "Network", "")
Expect(err).To(BeNil())

// run diff command
out, err := ExecCommandHost([]string{"bash", "-c", "curl google.com"})
Expect(err).NotTo(BeNil())
Expect(out).To(MatchRegexp(".*Could not resolve host: google.com"))

// 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-udp-block-curl"))
Expect(alerts[0].Severity).To(Equal("5"))
Expect(alerts[0].Action).To(Equal("Block"))
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: security.kubearmor.com/v1
kind: KubeArmorHostPolicy
metadata:
name: hsp-kubearmor-dev-file-dir-allow-fromsource
spec:
nodeSelector:
matchLabels:
kubearmor.io/hostname: "*"
severity: 5
file:
matchDirectories:
- dir: /etc/default/
recursive: true
fromSource:
- path: /usr/bin/head
action:
Allow

# kubearmor-dev_test_08

# test
# $ head /etc/default/useradd
# Default values for useradd(8) ...
# $ head /etc/hostname
# head: /etc/hostname: Permission denied

# expectation
# /usr/bin/head can only access /etc/default/*
# /usr/bin/head cannot access any others
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: security.kubearmor.com/v1
kind: KubeArmorHostPolicy
metadata:
name: hsp-kubearmor-dev-file-dir-block-fromsource
spec:
nodeSelector:
matchLabels:
kubearmor.io/hostname: "*"
severity: 5
file:
matchDirectories:
- dir: /etc/default/
fromSource:
- path: /usr/bin/head
action:
Block

# kubearmor-dev_test_09

# test
# $ head /etc/default/useradd
# head: useradd: Permission denied
# $ head /etc/hostname
# kubearmor-dev

# expectation
# /usr/bin/head cannot access /etc/default/*
# /usr/bin/head can access any others
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: security.kubearmor.com/v1
kind: KubeArmorHostPolicy
metadata:
name: hsp-kubearmor-dev-file-path-allow-fromsource
spec:
nodeSelector:
matchLabels:
kubearmor.io/hostname: "*"
severity: 5
file:
matchPaths:
- path: /etc/hostname
fromSource:
- path: /usr/bin/head
action:
Allow

# kubearmor-dev_test_07

# test
# $ head /etc/hostname
# kubearmor-dev
# $ head /etc/hosts
# head: /etc/hosts: Permission denied

# expectation
# /usr/bin/head can only access /etc/hostname
# /usr/bin/head cannot access any others
25 changes: 25 additions & 0 deletions tests/k8s_env/hsp/res/hsp-kubearmor-dev-file-path-audit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: security.kubearmor.com/v1
kind: KubeArmorHostPolicy
metadata:
name: hsp-kubearmor-dev-file-path-audit
spec:
nodeSelector:
matchLabels:
kubearmor.io/hostname: "*"
severity: 5
file:
matchPaths:
- path: /etc/passwd
action:
Audit

# kubearmor-dev_test_02

# test
# $ cat /etc/passwd
# ...
# $ head /etc/passwd
# ...

# expectation
# anyone can access /etc/passwd, but the access would be audited
Loading

0 comments on commit 4ef501e

Please sign in to comment.