From 3e602597b036d29f77485f35c1f81a8cdb6f350b Mon Sep 17 00:00:00 2001 From: Pawel Wieczorek Date: Thu, 19 Sep 2019 15:27:14 +0200 Subject: k8s: Validate API server Certificate Authorities This patch verifies if CIS Kubernetes Benchmark v1.3.0 sections regarding master node configuration are satisfied (1.1.21, 1.1.29 and 1.1.31). Issue-ID: SECCOM-235 Change-Id: Ia2f55f6962885a7aa878c970a406189902cfab10 Signed-off-by: Pawel Wieczorek --- test/security/k8s/src/check/cmd/check/check.go | 4 +++ .../k8s/src/check/validators/master/api.go | 15 +++++++++ .../k8s/src/check/validators/master/api_test.go | 36 ++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/test/security/k8s/src/check/cmd/check/check.go b/test/security/k8s/src/check/cmd/check/check.go index 7468bc443..d124b8708 100644 --- a/test/security/k8s/src/check/cmd/check/check.go +++ b/test/security/k8s/src/check/cmd/check/check.go @@ -70,4 +70,8 @@ func main() { log.Printf("IsAuditLogMaxAgeValid: %t\n", master.IsAuditLogPathSet(k8sParams)) log.Printf("IsAuditLogMaxBackupValid: %t\n", master.IsAuditLogPathSet(k8sParams)) log.Printf("IsAuditLogMaxSizeValid: %t\n", master.IsAuditLogPathSet(k8sParams)) + + log.Printf("IsKubeletCertificateAuthoritySet: %t\n", master.IsKubeletCertificateAuthoritySet(k8sParams)) + log.Printf("IsClientCertificateAuthoritySet: %t\n", master.IsClientCertificateAuthoritySet(k8sParams)) + log.Printf("IsEtcdCertificateAuthoritySet: %t\n", master.IsEtcdCertificateAuthoritySet(k8sParams)) } diff --git a/test/security/k8s/src/check/validators/master/api.go b/test/security/k8s/src/check/validators/master/api.go index ca517c1ec..4a70e5337 100644 --- a/test/security/k8s/src/check/validators/master/api.go +++ b/test/security/k8s/src/check/validators/master/api.go @@ -263,6 +263,21 @@ func IsAuditLogPathSet(params []string) bool { return hasSingleFlagNonemptyArgument("--audit-log-path=", params) } +// IsKubeletCertificateAuthoritySet validates there is single "--kubelet-certificate-authority" flag and has non-empty argument. +func IsKubeletCertificateAuthoritySet(params []string) bool { + return hasSingleFlagNonemptyArgument("--kubelet-certificate-authority", params) +} + +// IsClientCertificateAuthoritySet validates there is single "--client-ca-file" flag and has non-empty argument. +func IsClientCertificateAuthoritySet(params []string) bool { + return hasSingleFlagNonemptyArgument("--client-ca-file", params) +} + +// IsEtcdCertificateAuthoritySet validates there is single "--etcd-cafile" flag and has non-empty argument. +func IsEtcdCertificateAuthoritySet(params []string) bool { + return hasSingleFlagNonemptyArgument("--etcd-cafile", 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) 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 23c2838aa..f0db8b776 100644 --- a/test/security/k8s/src/check/validators/master/api_test.go +++ b/test/security/k8s/src/check/validators/master/api_test.go @@ -28,6 +28,9 @@ var _ = Describe("Api", func() { "--audit-log-maxage=30", "--audit-log-maxbackup=10", "--audit-log-maxsize=100", + "--kubelet-certificate-authority=TrustedCA", + "--client-ca-file=/etc/kubernetes/ssl/ca.pem", + "--etcd-cafile=/etc/kubernetes/etcd/ca.pem", } // kubeApiServerCasablanca was obtained from virtual environment for testing @@ -204,6 +207,39 @@ var _ = Describe("Api", func() { Entry("Is absent on Dublin cluster", kubeApiServerDublin, false), Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true), ) + + DescribeTable("Kubelet certificate authority", + func(params []string, expected bool) { + Expect(IsKubeletCertificateAuthoritySet(params)).To(Equal(expected)) + }, + Entry("Is absent on insecure cluster", []string{}, false), + Entry("Is empty on insecure cluster", []string{"--kubelet-certificate-authority="}, false), + Entry("Is absent on Casablanca cluster", kubeApiServerCasablanca, false), + Entry("Is absent on Dublin cluster", kubeApiServerDublin, false), + Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true), + ) + + DescribeTable("Client certificate authority", + func(params []string, expected bool) { + Expect(IsClientCertificateAuthoritySet(params)).To(Equal(expected)) + }, + Entry("Is absent on insecure cluster", []string{}, false), + Entry("Is empty on insecure cluster", []string{"--client-ca-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), + ) + + DescribeTable("Etcd certificate authority", + func(params []string, expected bool) { + Expect(IsEtcdCertificateAuthoritySet(params)).To(Equal(expected)) + }, + Entry("Is absent on insecure cluster", []string{}, false), + Entry("Is empty on insecure cluster", []string{"-etcd-cafile="}, 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() { -- cgit 1.2.3-korg