@@ -430,6 +430,33 @@ func Test_scs_0217_sonobuoy_Authentication_Methods(t *testing.T) {
430430 testenv .Test (t , f .Feature ())
431431}
432432
433+ // Test_scs_0217_etcd_tls checks if communication with etcd is secured with TLS for both peer- and cluster-communication.
434+ func Test_scs_0217_etcd_tls_communication (t * testing.T ) {
435+ f := features .New ("etcd security" ).Assess (
436+ "Communication with etcd MUST be secured with TLS for both peer- and cluster-communication" ,
437+ func (ctx context.Context , t * testing.T , cfg * envconf.Config ) context.Context {
438+ restConf , err := rest .InClusterConfig ()
439+ if err != nil {
440+ t .Fatal ("failed to create rest config:" , err )
441+ }
442+
443+ kubeClient , err := kubernetes .NewForConfig (restConf )
444+ if err != nil {
445+ t .Fatal ("failed to create Kubernetes client:" , err )
446+ }
447+
448+ // Check kube-apiserver communication with etcd
449+ checkKubeAPIServerETCDTLS (t , kubeClient )
450+
451+ // Check etcd peer communication for TLS
452+ checkETCDPeerCommunicationTLS (t , kubeClient )
453+
454+ return ctx
455+ })
456+
457+ testenv .Test (t , f .Feature ())
458+ }
459+
433460// checkPortOpen tries to establish a TCP connection to the given IP and port.
434461// It returns true if the port is open and false if the connection is refused or times out.
435462func checkPortOpen (ip , port string , timeout time.Duration ) bool {
@@ -687,3 +714,63 @@ func checkAuthorizationmethods(t *testing.T, kubeClient *kubernetes.Clientset) {
687714 }
688715 }
689716}
717+
718+ // checkKubeAPIServerETCDTLS checks whether the kube-apiserver communicates with etcd over TLS.
719+ func checkKubeAPIServerETCDTLS (t * testing.T , kubeClient * kubernetes.Clientset ) {
720+ // List kube-apiserver pods
721+ podList , err := kubeClient .CoreV1 ().Pods ("kube-system" ).List (context .TODO (), v1.ListOptions {
722+ LabelSelector : "component=kube-apiserver" ,
723+ })
724+ if err != nil {
725+ t .Fatal ("failed to list kube-apiserver pods:" , err )
726+ }
727+
728+ // Check each kube-apiserver pod
729+ for _ , pod := range podList .Items {
730+ for _ , container := range pod .Spec .Containers {
731+ cmdFound := false
732+ for _ , cmd := range container .Command {
733+ // Check for etcd certificates and key flags
734+ if strings .Contains (cmd , "--etcd-certfile" ) && strings .Contains (cmd , "--etcd-keyfile" ) && strings .Contains (cmd , "--etcd-cafile" ) {
735+ t .Logf ("kube-apiserver communicates with etcd using TLS in container: %s of pod: %s" , container .Name , pod .Name )
736+ cmdFound = true
737+ break
738+ }
739+ }
740+
741+ if ! cmdFound {
742+ t .Errorf ("Error: kube-apiserver does not use TLS for etcd communication in container: %s of pod: %s" , container .Name , pod .Name )
743+ }
744+ }
745+ }
746+ }
747+
748+ // checkETCDPeerCommunicationTLS checks whether etcd peer communication is secured with TLS.
749+ func checkETCDPeerCommunicationTLS (t * testing.T , kubeClient * kubernetes.Clientset ) {
750+ // List etcd pods
751+ podList , err := kubeClient .CoreV1 ().Pods ("kube-system" ).List (context .TODO (), v1.ListOptions {
752+ LabelSelector : "component=etcd" ,
753+ })
754+ if err != nil {
755+ t .Fatal ("failed to list etcd pods:" , err )
756+ }
757+
758+ // Check each etcd pod
759+ for _ , pod := range podList .Items {
760+ for _ , container := range pod .Spec .Containers {
761+ cmdFound := false
762+ for _ , cmd := range container .Command {
763+ // Check for etcd peer certificate and key flags
764+ if strings .Contains (cmd , "--peer-cert-file" ) && strings .Contains (cmd , "--peer-key-file" ) && strings .Contains (cmd , "--peer-client-cert-auth" ) {
765+ t .Logf ("Etcd peer communication is secured with TLS in container: %s of pod: %s" , container .Name , pod .Name )
766+ cmdFound = true
767+ break
768+ }
769+ }
770+
771+ if ! cmdFound {
772+ t .Errorf ("Error: etcd peer communication is not secured with TLS in container: %s of pod: %s" , container .Name , pod .Name )
773+ }
774+ }
775+ }
776+ }
0 commit comments