k8s: Validate API server excluded admission plugins 20/95820/1
authorPawel Wieczorek <p.wieczorek2@samsung.com>
Mon, 16 Sep 2019 15:51:39 +0000 (17:51 +0200)
committerPawel Wieczorek <p.wieczorek2@samsung.com>
Tue, 17 Sep 2019 13:51:37 +0000 (15:51 +0200)
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>
test/security/k8s/src/check/cmd/check/check.go
test/security/k8s/src/check/validators/master/api.go
test/security/k8s/src/check/validators/master/api_test.go

index 3c005f7..2ea1806 100644 (file)
@@ -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))
 }
index c91b77e..58064ef 100644 (file)
@@ -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
+}
index bee1995..f7c6daa 100644 (file)
@@ -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),
+               )
        })
 })