k8s: Validate API server certificates and keys 23/96023/1
authorPawel Wieczorek <p.wieczorek2@samsung.com>
Thu, 19 Sep 2019 14:06:13 +0000 (16:06 +0200)
committerPawel Wieczorek <p.wieczorek2@samsung.com>
Thu, 19 Sep 2019 16:34:12 +0000 (18:34 +0200)
This patch verifies if CIS Kubernetes Benchmark v1.3.0 sections
regarding master node configuration are satisfied (1.1.22, 1.1.25 -
1.1.26 and 1.1.28).

Issue-ID: SECCOM-235
Change-Id: Ic61a796653dc868d20fe69c3ed508e7fa8ba52db
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 d124b87..0288437 100644 (file)
@@ -74,4 +74,9 @@ func main() {
        log.Printf("IsKubeletCertificateAuthoritySet: %t\n", master.IsKubeletCertificateAuthoritySet(k8sParams))
        log.Printf("IsClientCertificateAuthoritySet: %t\n", master.IsClientCertificateAuthoritySet(k8sParams))
        log.Printf("IsEtcdCertificateAuthoritySet: %t\n", master.IsEtcdCertificateAuthoritySet(k8sParams))
+
+       log.Printf("IsServiceAccountKeySet: %t\n", master.IsServiceAccountKeySet(k8sParams))
+       log.Printf("IsKubeletClientCertificateAndKeySet: %t\n", master.IsKubeletClientCertificateAndKeySet(k8sParams))
+       log.Printf("IsEtcdCertificateAndKeySet: %t\n", master.IsEtcdCertificateAndKeySet(k8sParams))
+       log.Printf("IsTLSCertificateAndKeySet: %t\n", master.IsTLSCertificateAndKeySet(k8sParams))
 }
index 4a70e53..95a02d1 100644 (file)
@@ -278,6 +278,29 @@ func IsEtcdCertificateAuthoritySet(params []string) bool {
        return hasSingleFlagNonemptyArgument("--etcd-cafile", params)
 }
 
+// IsServiceAccountKeySet validates there is single "--service-account-key-file" flag and has non-empty argument.
+func IsServiceAccountKeySet(params []string) bool {
+       return hasSingleFlagNonemptyArgument("--service-account-key-file", params)
+}
+
+// IsKubeletClientCertificateAndKeySet validates there are single "--kubelet-client-certificate" and "--kubelet-client-key" flags and have non-empty arguments.
+func IsKubeletClientCertificateAndKeySet(params []string) bool {
+       return hasSingleFlagNonemptyArgument("--kubelet-client-certificate", params) &&
+               hasSingleFlagNonemptyArgument("--kubelet-client-key", params)
+}
+
+// IsEtcdCertificateAndKeySet validates there are single "--etcd-certfile" and "--etcd-keyfile" flags and have non-empty arguments.
+func IsEtcdCertificateAndKeySet(params []string) bool {
+       return hasSingleFlagNonemptyArgument("--etcd-certfile", params) &&
+               hasSingleFlagNonemptyArgument("--etcd-keyfile", params)
+}
+
+// IsTLSCertificateAndKeySet validates there are single "--tls-cert-file" and "--tls-private-key-file" flags and have non-empty arguments.
+func IsTLSCertificateAndKeySet(params []string) bool {
+       return hasSingleFlagNonemptyArgument("--tls-cert-file", params) &&
+               hasSingleFlagNonemptyArgument("--tls-private-key-file", params)
+}
+
 // hasSingleFlagNonemptyArgument checks whether selected flag was used once and has non-empty argument.
 func hasSingleFlagNonemptyArgument(flag string, params []string) bool {
        found := filterFlags(params, flag)
index f0db8b7..f9eb943 100644 (file)
@@ -31,6 +31,13 @@ var _ = Describe("Api", func() {
                        "--kubelet-certificate-authority=TrustedCA",
                        "--client-ca-file=/etc/kubernetes/ssl/ca.pem",
                        "--etcd-cafile=/etc/kubernetes/etcd/ca.pem",
+                       "--service-account-key-file=/etc/kubernetes/ssl/kube-service-account-token-key.pem",
+                       "--kubelet-client-certificate=/etc/kubernetes/ssl/cert.pem",
+                       "--kubelet-client-key=/etc/kubernetes/ssl/key.pem",
+                       "--etcd-certfile=/etc/kubernetes/etcd/cert.pem",
+                       "--etcd-keyfile=/etc/kubernetes/etcd/key.pem",
+                       "--tls-cert-file=/etc/kubernetes/ssl/cert.pem",
+                       "--tls-private-key-file=/etc/kubernetes/ssl/key.pem",
                }
 
                // kubeApiServerCasablanca was obtained from virtual environment for testing
@@ -240,6 +247,50 @@ var _ = Describe("Api", func() {
                        Entry("Should be present on Casablanca cluster", kubeApiServerCasablanca, true),
                        Entry("Should be present on Dublin cluster", kubeApiServerDublin, true),
                )
+
+               DescribeTable("Service account key",
+                       func(params []string, expected bool) {
+                               Expect(IsServiceAccountKeySet(params)).To(Equal(expected))
+                       },
+                       Entry("Is absent on insecure cluster", []string{}, false),
+                       Entry("Is empty on insecure cluster", []string{"--service-account-key-file="}, false),
+                       Entry("Is absent on Casablanca cluster", kubeApiServerCasablanca, false),
+                       Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true),
+                       Entry("Should be present on Dublin cluster", kubeApiServerDublin, true),
+               )
+
+               DescribeTable("Kubelet client certificate and key",
+                       func(params []string, expected bool) {
+                               Expect(IsKubeletClientCertificateAndKeySet(params)).To(Equal(expected))
+                       },
+                       Entry("Is absent on insecure cluster", []string{}, false),
+                       Entry("Is empty on insecure cluster", []string{"--kubelet-client-certificate= --kubelet-client-key="}, false),
+                       Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true),
+                       Entry("Should be present on Casablanca cluster", kubeApiServerCasablanca, true),
+                       Entry("Should be present on Dublin cluster", kubeApiServerDublin, true),
+               )
+
+               DescribeTable("Etcd certificate and key",
+                       func(params []string, expected bool) {
+                               Expect(IsEtcdCertificateAndKeySet(params)).To(Equal(expected))
+                       },
+                       Entry("Is absent on insecure cluster", []string{}, false),
+                       Entry("Is empty on insecure cluster", []string{"--etcd-certfile= --etcd-keyfile="}, false),
+                       Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true),
+                       Entry("Should be present on Casablanca cluster", kubeApiServerCasablanca, true),
+                       Entry("Should be present on Dublin cluster", kubeApiServerDublin, true),
+               )
+
+               DescribeTable("TLS certificate and key",
+                       func(params []string, expected bool) {
+                               Expect(IsTLSCertificateAndKeySet(params)).To(Equal(expected))
+                       },
+                       Entry("Is absent on insecure cluster", []string{}, false),
+                       Entry("Is empty on insecure cluster", []string{"--tls-cert-file= --tls-private-key-file="}, false),
+                       Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true),
+                       Entry("Should be present on Casablanca cluster", kubeApiServerCasablanca, true),
+                       Entry("Should be present on Dublin cluster", kubeApiServerDublin, true),
+               )
        })
 
        Describe("Address and port flags", func() {