...
1
16
17 package auth
18
19 import (
20 "context"
21 "fmt"
22 "net"
23 "strconv"
24
25 v1 "k8s.io/api/core/v1"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 "k8s.io/kubernetes/pkg/cluster/ports"
28 "k8s.io/kubernetes/test/e2e/feature"
29 "k8s.io/kubernetes/test/e2e/framework"
30 e2enode "k8s.io/kubernetes/test/e2e/framework/node"
31 e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
32 e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
33 admissionapi "k8s.io/pod-security-admission/api"
34
35 "github.com/onsi/ginkgo/v2"
36 "github.com/onsi/gomega"
37 )
38
39 var _ = SIGDescribe(feature.NodeAuthenticator, func() {
40
41 f := framework.NewDefaultFramework("node-authn")
42 f.NamespacePodSecurityLevel = admissionapi.LevelBaseline
43 var ns string
44 var nodeIPs []string
45 ginkgo.BeforeEach(func(ctx context.Context) {
46 ns = f.Namespace.Name
47
48 nodes, err := e2enode.GetBoundedReadySchedulableNodes(ctx, f.ClientSet, 1)
49 framework.ExpectNoError(err)
50
51 family := v1.IPv4Protocol
52 if framework.TestContext.ClusterIsIPv6() {
53 family = v1.IPv6Protocol
54 }
55
56 nodeIPs := e2enode.GetAddressesByTypeAndFamily(&nodes.Items[0], v1.NodeInternalIP, family)
57 gomega.Expect(nodeIPs).NotTo(gomega.BeEmpty())
58 })
59
60 ginkgo.It("The kubelet's main port 10250 should reject requests with no credentials", func(ctx context.Context) {
61 pod := createNodeAuthTestPod(ctx, f)
62 for _, nodeIP := range nodeIPs {
63
64 host := net.JoinHostPort(nodeIP, strconv.Itoa(ports.KubeletPort))
65 result := e2eoutput.RunHostCmdOrDie(ns, pod.Name, fmt.Sprintf("curl -sIk -o /dev/null -w '%s' https://%s/metrics", "%{http_code}", host))
66 gomega.Expect(result).To(gomega.Or(gomega.Equal("401"), gomega.Equal("403")), "the kubelet's main port 10250 should reject requests with no credentials")
67 }
68 })
69
70 ginkgo.It("The kubelet can delegate ServiceAccount tokens to the API server", func(ctx context.Context) {
71 ginkgo.By("create a new ServiceAccount for authentication")
72 trueValue := true
73 newSA := &v1.ServiceAccount{
74 ObjectMeta: metav1.ObjectMeta{
75 Namespace: ns,
76 Name: "node-auth-newsa",
77 },
78 AutomountServiceAccountToken: &trueValue,
79 }
80 _, err := f.ClientSet.CoreV1().ServiceAccounts(ns).Create(ctx, newSA, metav1.CreateOptions{})
81 framework.ExpectNoError(err, "failed to create service account (%s:%s)", ns, newSA.Name)
82
83 pod := createNodeAuthTestPod(ctx, f)
84
85 for _, nodeIP := range nodeIPs {
86 host := net.JoinHostPort(nodeIP, strconv.Itoa(ports.KubeletPort))
87 result := e2eoutput.RunHostCmdOrDie(ns,
88 pod.Name,
89 fmt.Sprintf("curl -sIk -o /dev/null -w '%s' --header \"Authorization: Bearer `%s`\" https://%s/metrics",
90 "%{http_code}",
91 "cat /var/run/secrets/kubernetes.io/serviceaccount/token",
92 host))
93 gomega.Expect(result).To(gomega.Or(gomega.Equal("401"), gomega.Equal("403")), "the kubelet can delegate ServiceAccount tokens to the API server")
94 }
95 })
96 })
97
98 func createNodeAuthTestPod(ctx context.Context, f *framework.Framework) *v1.Pod {
99 pod := e2epod.NewAgnhostPod(f.Namespace.Name, "agnhost-pod", nil, nil, nil)
100 pod.ObjectMeta.GenerateName = "test-node-authn-"
101 return e2epod.NewPodClient(f).CreateSync(ctx, pod)
102 }
103
View as plain text