aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPawel Wieczorek <p.wieczorek2@samsung.com>2019-09-16 17:51:39 +0200
committerPawel Wieczorek <p.wieczorek2@samsung.com>2019-09-17 15:51:37 +0200
commitaeaa5a1f5e57f63dd203db43fb6992ab1728c504 (patch)
tree99eff91cebb8792defa77cee62d5e562b67c2018
parent0dc16f1f0c60625a1637ee1ec106a4df543dab92 (diff)
k8s: Validate API server excluded admission plugins
This patch verifies if CIS Kubernetes Benchmark v1.3.0 section regarding master node configuration is satisfied (1.1.10). However, CIS Kubernetes Benchmark v1.3.0 mismatches official documentation: Kubernetes 1.10+ already provides safe defaults from security standpoint [1] (ONAP Casablanca uses 1.11). Deprecated admission control plugin flag has also been validated since it was still available in Kubernetes provided by Rancher [2]. [1] https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#is-there-a-recommended-set-of-admission-controllers-to-use [2] https://github.com/rancher/rancher/issues/15064 Issue-ID: SECCOM-235 Change-Id: I0e8fe9f885861f155cb8265df085fa93dbdff6d2 Signed-off-by: Pawel Wieczorek <p.wieczorek2@samsung.com>
-rw-r--r--test/security/k8s/src/check/cmd/check/check.go2
-rw-r--r--test/security/k8s/src/check/validators/master/api.go36
-rw-r--r--test/security/k8s/src/check/validators/master/api_test.go15
3 files changed, 53 insertions, 0 deletions
diff --git a/test/security/k8s/src/check/cmd/check/check.go b/test/security/k8s/src/check/cmd/check/check.go
index 3c005f77c..2ea180628 100644
--- a/test/security/k8s/src/check/cmd/check/check.go
+++ b/test/security/k8s/src/check/cmd/check/check.go
@@ -51,4 +51,6 @@ func main() {
log.Printf("IsKubeletHTTPSAbsentOrEnabled: %t\n", master.IsKubeletHTTPSAbsentOrEnabled(k8sParams))
log.Printf("IsInsecureBindAddressAbsentOrLoopback: %t\n", master.IsInsecureBindAddressAbsentOrLoopback(k8sParams))
log.Printf("IsSecurePortAbsentOrValid: %t\n", master.IsSecurePortAbsentOrValid(k8sParams))
+
+ log.Printf("IsAlwaysAdmitAdmissionControlPluginExcluded: %t\n", master.IsAlwaysAdmitAdmissionControlPluginExcluded(k8sParams))
}
diff --git a/test/security/k8s/src/check/validators/master/api.go b/test/security/k8s/src/check/validators/master/api.go
index c91b77e30..58064ef10 100644
--- a/test/security/k8s/src/check/validators/master/api.go
+++ b/test/security/k8s/src/check/validators/master/api.go
@@ -126,3 +126,39 @@ func hasFlagValidPort(flag string, params []string) bool {
}
return true
}
+
+// IsAlwaysAdmitAdmissionControlPluginExcluded validates AlwaysAdmit is excluded from admission control plugins.
+func IsAlwaysAdmitAdmissionControlPluginExcluded(params []string) bool {
+ if isSingleFlagPresent("--enable-admission-plugins=", params) {
+ return !hasFlagArgumentIncluded("--enable-admission-plugins=", "AlwaysAdmit", params)
+ }
+ if isSingleFlagPresent("--admission-control=", params) {
+ return !hasFlagArgumentIncluded("--admission-control=", "AlwaysAdmit", params)
+ }
+ return false
+}
+
+// isSingleFlagPresent checks presence of selected flag and whether it was used once.
+func isSingleFlagPresent(flag string, params []string) bool {
+ found := filterFlags(params, flag)
+ if len(found) != 1 {
+ return false
+ }
+ return true
+}
+
+// hasFlagArgumentIncluded checks whether selected flag includes requested argument.
+func hasFlagArgumentIncluded(flag string, argument string, params []string) bool {
+ found := filterFlags(params, flag)
+ if len(found) != 1 {
+ return false
+ }
+
+ _, values := splitKV(found[0], "=")
+ for _, v := range strings.Split(values, ",") {
+ if v == argument {
+ return true
+ }
+ }
+ return false
+}
diff --git a/test/security/k8s/src/check/validators/master/api_test.go b/test/security/k8s/src/check/validators/master/api_test.go
index bee199519..f7c6daa52 100644
--- a/test/security/k8s/src/check/validators/master/api_test.go
+++ b/test/security/k8s/src/check/validators/master/api_test.go
@@ -18,6 +18,10 @@ var _ = Describe("Api", func() {
"--profiling=false",
"--repair-malformed-updates=false",
"--service-account-lookup=true",
+ "--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount," +
+ "TaintNodesByCondition,Priority,DefaultTolerationSeconds,DefaultStorageClass," +
+ "PersistentVolumeClaimResize,MutatingAdmissionWebhook,ValidatingAdmissionWebhook," +
+ "ResourceQuota",
}
// kubeApiServerCasablanca was obtained from virtual environment for testing
@@ -212,5 +216,16 @@ var _ = Describe("Api", func() {
Entry("Should be set to true on CIS-compliant cluster", kubeApiServerCISCompliant, true),
Entry("Should be set to true on Dublin cluster", kubeApiServerDublin, true),
)
+
+ DescribeTable("AlwaysAdmit admission control plugin",
+ func(params []string, expected bool) {
+ Expect(IsAlwaysAdmitAdmissionControlPluginExcluded(params)).To(Equal(expected))
+ },
+ Entry("Is not absent on insecure cluster", []string{"--enable-admission-plugins=Foo,Bar,AlwaysAdmit,Baz,Quuz"}, false),
+ Entry("Is not absent on insecure deprecated cluster", []string{"--admission-control=Foo,Bar,AlwaysAdmit,Baz,Quuz"}, false),
+ Entry("Should be absent on CIS-compliant cluster", kubeApiServerCISCompliant, true),
+ Entry("Should be absent on Casablanca cluster", kubeApiServerCasablanca, true),
+ Entry("Should be absent on Dublin cluster", kubeApiServerDublin, true),
+ )
})
})