4 . "check/validators/master"
6 . "github.com/onsi/ginkgo/extensions/table"
8 . "github.com/onsi/ginkgo"
9 . "github.com/onsi/gomega"
12 var _ = Describe("Api", func() {
14 // kubeApiServerCISCompliant uses secure defaults or follows CIS guidelines explicitly.
15 kubeApiServerCISCompliant = []string{
16 "--anonymous-auth=false",
19 "--repair-malformed-updates=false",
20 "--service-account-lookup=true",
21 "--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount," +
22 "TaintNodesByCondition,Priority,DefaultTolerationSeconds,DefaultStorageClass," +
23 "PersistentVolumeClaimResize,MutatingAdmissionWebhook,ValidatingAdmissionWebhook," +
24 "ResourceQuota,AlwaysPullImages,DenyEscalatingExec,SecurityContextDeny," +
25 "PodSecurityPolicy,NodeRestriction,EventRateLimit",
28 // kubeApiServerCasablanca was obtained from virtual environment for testing
29 // (introduced in Change-Id: I57f9f3caac0e8b391e9ed480f6bebba98e006882).
30 kubeApiServerCasablanca = []string{
31 "--storage-backend=etcd2",
32 "--storage-media-type=application/json",
33 "--service-cluster-ip-range=10.43.0.0/16",
34 "--etcd-servers=https://etcd.kubernetes.rancher.internal:2379",
35 "--insecure-bind-address=0.0.0.0",
37 "--cloud-provider=rancher",
38 "--allow-privileged=true",
39 "--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount," +
40 "PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota",
41 "--client-ca-file=/etc/kubernetes/ssl/ca.pem",
42 "--tls-cert-file=/etc/kubernetes/ssl/cert.pem",
43 "--tls-private-key-file=/etc/kubernetes/ssl/key.pem",
44 "--kubelet-client-certificate=/etc/kubernetes/ssl/cert.pem",
45 "--kubelet-client-key=/etc/kubernetes/ssl/key.pem",
46 "--runtime-config=batch/v2alpha1",
47 "--anonymous-auth=false",
48 "--authentication-token-webhook-config-file=/etc/kubernetes/authconfig",
49 "--runtime-config=authentication.k8s.io/v1beta1=true",
50 "--external-hostname=kubernetes.kubernetes.rancher.internal",
51 "--etcd-cafile=/etc/kubernetes/etcd/ca.pem",
52 "--etcd-certfile=/etc/kubernetes/etcd/cert.pem",
53 "--etcd-keyfile=/etc/kubernetes/etcd/key.pem",
54 "--tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," +
55 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305," +
56 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384," +
57 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
60 // kubeApiServerCasablanca was obtained from virtual environment for testing
61 // (introduced in Change-Id: I54ada5fade3b984dedd1715f20579e3ce901faa3).
62 kubeApiServerDublin = []string{
63 "--requestheader-group-headers=X-Remote-Group",
64 "--proxy-client-cert-file=/etc/kubernetes/ssl/kube-apiserver-proxy-client.pem",
65 "--bind-address=0.0.0.0",
66 "--tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," +
67 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305," +
68 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384," +
69 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
71 "--etcd-cafile=/etc/kubernetes/ssl/kube-ca.pem",
72 "--etcd-servers=https://172.17.0.100:2379",
73 "--tls-cert-file=/etc/kubernetes/ssl/kube-apiserver.pem",
74 "--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount," +
75 "DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook," +
76 "ValidatingAdmissionWebhook,ResourceQuota,NodeRestriction,PersistentVolumeLabel",
79 "--storage-backend=etcd3",
80 "--kubelet-client-key=/etc/kubernetes/ssl/kube-apiserver-key.pem",
81 "--requestheader-client-ca-file=/etc/kubernetes/ssl/kube-apiserver-requestheader-ca.pem",
82 "--service-account-key-file=/etc/kubernetes/ssl/kube-service-account-token-key.pem",
83 "--service-node-port-range=30000-32767",
84 "--tls-private-key-file=/etc/kubernetes/ssl/kube-apiserver-key.pem",
85 "--requestheader-username-headers=X-Remote-User",
86 "--repair-malformed-updates=false",
87 "--kubelet-client-certificate=/etc/kubernetes/ssl/kube-apiserver.pem",
88 "--service-cluster-ip-range=10.43.0.0/16",
89 "--advertise-address=172.17.0.100",
91 "--requestheader-extra-headers-prefix=X-Remote-Extra-",
92 "--etcd-certfile=/etc/kubernetes/ssl/kube-node.pem",
93 "--anonymous-auth=false",
94 "--etcd-keyfile=/etc/kubernetes/ssl/kube-node-key.pem",
95 "--etcd-prefix=/registry",
96 "--client-ca-file=/etc/kubernetes/ssl/kube-ca.pem",
97 "--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
98 "--requestheader-allowed-names=kube-apiserver-proxy-client",
99 "--service-account-lookup=true",
100 "--proxy-client-key-file=/etc/kubernetes/ssl/kube-apiserver-proxy-client-key.pem",
101 "--authorization-mode=Node,RBAC",
102 "--allow-privileged=true",
106 Describe("Boolean flags", func() {
107 DescribeTable("Basic authentication file",
108 func(params []string, expected bool) {
109 Expect(IsBasicAuthFileAbsent(params)).To(Equal(expected))
111 Entry("Is not absent on insecure cluster", []string{"--basic-auth-file=/path/to/file"}, false),
112 Entry("Should be absent on CIS-compliant cluster", kubeApiServerCISCompliant, true),
113 Entry("Should be absent on Casablanca cluster", kubeApiServerCasablanca, true),
114 Entry("Should be absent on Dublin cluster", kubeApiServerDublin, true),
117 DescribeTable("Token authentication file",
118 func(params []string, expected bool) {
119 Expect(IsTokenAuthFileAbsent(params)).To(Equal(expected))
121 Entry("Is not absent on insecure cluster", []string{"--token-auth-file=/path/to/file"}, false),
122 Entry("Should be absent on CIS-compliant cluster", kubeApiServerCISCompliant, true),
123 Entry("Should be absent on Casablanca cluster", kubeApiServerCasablanca, true),
124 Entry("Should be absent on Dublin cluster", kubeApiServerDublin, true),
127 DescribeTable("Accepting any token",
128 func(params []string, expected bool) {
129 Expect(IsInsecureAllowAnyTokenAbsent(params)).To(Equal(expected))
131 Entry("Is not absent on insecure cluster", []string{"--insecure-allow-any-token"}, false),
132 Entry("Should be absent on CIS-compliant cluster", kubeApiServerCISCompliant, true),
133 Entry("Should be absent on Casablanca cluster", kubeApiServerCasablanca, true),
134 Entry("Should be absent on Dublin cluster", kubeApiServerDublin, true),
137 DescribeTable("Anonymous requests",
138 func(params []string, expected bool) {
139 Expect(IsAnonymousAuthDisabled(params)).To(Equal(expected))
141 Entry("Is not set on insecure cluster", []string{}, false),
142 Entry("Should be set to false on CIS-compliant cluster", kubeApiServerCISCompliant, true),
143 Entry("Should be set to false on Casablanca cluster", kubeApiServerCasablanca, true),
144 Entry("Should be set to false on Dublin cluster", kubeApiServerDublin, true),
147 DescribeTable("HTTPS for kubelet",
148 func(params []string, expected bool) {
149 Expect(IsKubeletHTTPSAbsentOrEnabled(params)).To(Equal(expected))
151 Entry("Is explicitly disabled on insecure cluster", []string{"--kubelet-https=false"}, false),
152 Entry("Should be absent or set to true on CIS-compliant cluster", kubeApiServerCISCompliant, true),
153 Entry("Should be absent or set to true on Casablanca cluster", kubeApiServerCasablanca, true),
154 Entry("Should be absent or set to true on Dublin cluster", kubeApiServerDublin, true),
157 DescribeTable("Bind address",
158 func(params []string, expected bool) {
159 Expect(IsInsecureBindAddressAbsentOrLoopback(params)).To(Equal(expected))
161 Entry("Is not absent on insecure cluster", []string{"--insecure-bind-address=1.2.3.4"}, false),
162 Entry("Is not absent nor set to loopback on Casablanca cluster", kubeApiServerCasablanca, false),
163 Entry("Should be absent or set to loopback on CIS-compliant cluster", kubeApiServerCISCompliant, true),
164 Entry("Should be absent or set to loopback on Dublin cluster", kubeApiServerDublin, true),
167 DescribeTable("Bind port",
168 func(params []string, expected bool) {
169 Expect(IsInsecurePortUnbound(params)).To(Equal(expected))
171 Entry("Is not set on insecure cluster", []string{}, false),
172 Entry("Is explicitly enabled on insecure cluster", []string{"--insecure-port=1234"}, false),
173 Entry("Should be set to 0 on CIS-compliant cluster", kubeApiServerCISCompliant, true),
174 Entry("Should be set to 0 on Casablanca cluster", kubeApiServerCasablanca, true),
175 Entry("Should be set to 0 on Dublin cluster", kubeApiServerDublin, true),
178 DescribeTable("Secure bind port",
179 func(params []string, expected bool) {
180 Expect(IsSecurePortAbsentOrValid(params)).To(Equal(expected))
182 Entry("Is explicitly disabled on insecure cluster", []string{"--secure-port=0"}, false),
183 Entry("Should be absent or set to valid port on CIS-compliant cluster", kubeApiServerCISCompliant, true),
184 Entry("Should be absent or set to valid port on Casablanca cluster", kubeApiServerCasablanca, true),
185 Entry("Should be absent or set to valid port on Dublin cluster", kubeApiServerDublin, true),
188 DescribeTable("Profiling",
189 func(params []string, expected bool) {
190 Expect(IsProfilingDisabled(params)).To(Equal(expected))
192 Entry("Is not set on insecure cluster", []string{}, false),
193 Entry("Is explicitly enabled on insecure cluster", []string{"--profiling=true"}, false),
194 Entry("Is not set on Casablanca cluster", kubeApiServerCasablanca, false),
195 Entry("Should be set to false on CIS-compliant cluster", kubeApiServerCISCompliant, true),
196 Entry("Should be set to false on Dublin cluster", kubeApiServerDublin, true),
199 DescribeTable("Repairing malformed updates",
200 func(params []string, expected bool) {
201 Expect(IsRepairMalformedUpdatesDisabled(params)).To(Equal(expected))
203 Entry("Is not set on insecure cluster", []string{}, false),
204 Entry("Is explicitly enabled on insecure cluster", []string{"--repair-malformed-updates=true"}, false),
205 Entry("Is not set on Casablanca cluster", kubeApiServerCasablanca, false),
206 Entry("Should be set to false on CIS-compliant cluster", kubeApiServerCISCompliant, true),
207 Entry("Should be set to false on Dublin cluster", kubeApiServerDublin, true),
210 DescribeTable("Service account lookup",
211 func(params []string, expected bool) {
212 Expect(IsServiceAccountLookupEnabled(params)).To(Equal(expected))
214 Entry("Is not set on insecure cluster", []string{}, false),
215 Entry("Is explicitly disabled on insecure cluster", []string{"--service-account-lookup=false"}, false),
216 Entry("Is not set on Casablanca cluster", kubeApiServerCasablanca, false),
217 Entry("Should be set to true on CIS-compliant cluster", kubeApiServerCISCompliant, true),
218 Entry("Should be set to true on Dublin cluster", kubeApiServerDublin, true),
221 DescribeTable("AlwaysAdmit admission control plugin",
222 func(params []string, expected bool) {
223 Expect(IsAlwaysAdmitAdmissionControlPluginExcluded(params)).To(Equal(expected))
225 Entry("Is not absent on insecure cluster", []string{"--enable-admission-plugins=Foo,Bar,AlwaysAdmit,Baz,Quuz"}, false),
226 Entry("Is not absent on insecure deprecated cluster", []string{"--admission-control=Foo,Bar,AlwaysAdmit,Baz,Quuz"}, false),
227 Entry("Should be absent on CIS-compliant cluster", kubeApiServerCISCompliant, true),
228 Entry("Should be absent on Casablanca cluster", kubeApiServerCasablanca, true),
229 Entry("Should be absent on Dublin cluster", kubeApiServerDublin, true),
232 DescribeTable("AlwaysPullImages admission control plugin",
233 func(params []string, expected bool) {
234 Expect(IsAlwaysPullImagesAdmissionControlPluginIncluded(params)).To(Equal(expected))
236 Entry("Is not present on insecure cluster", []string{"--enable-admission-plugins=Foo,Bar"}, false),
237 Entry("Is not present on insecure deprecated cluster", []string{"--admission-control=Foo,Bar"}, false),
238 Entry("Is not present on Casablanca cluster", kubeApiServerCasablanca, false),
239 Entry("Is not present on Dublin cluster", kubeApiServerDublin, false),
240 Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true),
243 DescribeTable("DenyEscalatingExec admission control plugin",
244 func(params []string, expected bool) {
245 Expect(IsDenyEscalatingExecAdmissionControlPluginIncluded(params)).To(Equal(expected))
247 Entry("Is not present on insecure cluster", []string{"--enable-admission-plugins=Foo,Bar"}, false),
248 Entry("Is not present on insecure deprecated cluster", []string{"--admission-control=Foo,Bar"}, false),
249 Entry("Is not present on Casablanca cluster", kubeApiServerCasablanca, false),
250 Entry("Is not present on Dublin cluster", kubeApiServerDublin, false),
251 Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true),
254 DescribeTable("SecurityContextDeny admission control plugin",
255 func(params []string, expected bool) {
256 Expect(IsSecurityContextDenyAdmissionControlPluginIncluded(params)).To(Equal(expected))
258 Entry("Is not present on insecure cluster", []string{"--enable-admission-plugins=Foo,Bar"}, false),
259 Entry("Is not present on insecure deprecated cluster", []string{"--admission-control=Foo,Bar"}, false),
260 Entry("Is not present on Casablanca cluster", kubeApiServerCasablanca, false),
261 Entry("Is not present on Dublin cluster", kubeApiServerDublin, false),
262 Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true),
265 DescribeTable("PodSecurityPolicy admission control plugin",
266 func(params []string, expected bool) {
267 Expect(IsPodSecurityPolicyAdmissionControlPluginIncluded(params)).To(Equal(expected))
269 Entry("Is not present on insecure cluster", []string{"--enable-admission-plugins=Foo,Bar"}, false),
270 Entry("Is not present on insecure deprecated cluster", []string{"--admission-control=Foo,Bar"}, false),
271 Entry("Is not present on Casablanca cluster", kubeApiServerCasablanca, false),
272 Entry("Is not present on Dublin cluster", kubeApiServerDublin, false),
273 Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true),
276 DescribeTable("ServiceAccount admission control plugin",
277 func(params []string, expected bool) {
278 Expect(IsServiceAccountAdmissionControlPluginIncluded(params)).To(Equal(expected))
280 Entry("Is not present on insecure cluster", []string{"--enable-admission-plugins=Foo,Bar"}, false),
281 Entry("Is not present on insecure deprecated cluster", []string{"--admission-control=Foo,Bar"}, false),
282 Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true),
283 Entry("Should be present on Casablanca cluster", kubeApiServerCasablanca, true),
284 Entry("Should be present on Dublin cluster", kubeApiServerDublin, true),
287 DescribeTable("NodeRestriction admission control plugin",
288 func(params []string, expected bool) {
289 Expect(IsNodeRestrictionAdmissionControlPluginIncluded(params)).To(Equal(expected))
291 Entry("Is not present on insecure cluster", []string{"--enable-admission-plugins=Foo,Bar"}, false),
292 Entry("Is not present on insecure deprecated cluster", []string{"--admission-control=Foo,Bar"}, false),
293 Entry("Is not present on Casablanca cluster", kubeApiServerCasablanca, false),
294 Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true),
295 Entry("Should be present on Dublin cluster", kubeApiServerDublin, true),
298 DescribeTable("EventRateLimit admission control plugin",
299 func(params []string, expected bool) {
300 Expect(IsEventRateLimitAdmissionControlPluginIncluded(params)).To(Equal(expected))
302 Entry("Is not present on insecure cluster", []string{"--enable-admission-plugins=Foo,Bar"}, false),
303 Entry("Is not present on insecure deprecated cluster", []string{"--admission-control=Foo,Bar"}, false),
304 Entry("Is not present on Casablanca cluster", kubeApiServerCasablanca, false),
305 Entry("Is not present on Dublin cluster", kubeApiServerDublin, false),
306 Entry("Should be present on CIS-compliant cluster", kubeApiServerCISCompliant, true),
309 DescribeTable("NamespaceLifecycle admission control plugin",
310 func(params []string, expected bool) {
311 Expect(IsNamespaceLifecycleAdmissionControlPluginNotExcluded(params)).To(Equal(expected))
313 Entry("Is explicitly disabled on insecure cluster", []string{"--disable-admission-plugins=Foo,Bar,NamespaceLifecycle,Baz,Quuz"}, false),
314 Entry("Should not be disabled on CIS-compliant cluster", kubeApiServerCISCompliant, true),
315 Entry("Should not be disabled on Casablanca cluster", kubeApiServerCasablanca, true),
316 Entry("Should not be disabled on Dublin cluster", kubeApiServerDublin, true),