From c1ee4a2a27631f627fe87484abe1126c7565f666 Mon Sep 17 00:00:00 2001 From: Brad Davidson Date: Wed, 21 Feb 2024 21:03:41 +0000 Subject: [PATCH] Add new network policy for ingress controller webhook Unfortunately we can't just add this to the existing netpol, as we document that it is not updated once the namespace annotation has been set. Signed-off-by: Brad Davidson --- pkg/rke2/np.go | 84 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/pkg/rke2/np.go b/pkg/rke2/np.go index 5fb2f05af5..e96342761a 100644 --- a/pkg/rke2/np.go +++ b/pkg/rke2/np.go @@ -24,10 +24,12 @@ const ( namespaceAnnotationNetworkPolicy = "np.rke2.io" namespaceAnnotationNetworkDNSPolicy = "np.rke2.io/dns" namespaceAnnotationNetworkIngressPolicy = "np.rke2.io/ingress" + namespaceAnnotationNetworkWebhookPolicy = "np.rke2.io/ingress-webhook" defaultNetworkPolicyName = "default-network-policy" defaultNetworkDNSPolicyName = "default-network-dns-policy" defaultNetworkIngressPolicyName = "default-network-ingress-policy" + defaultNetworkWebhookPolicyName = "default-network-ingress-webhook-policy" defaultTimeout = 30 cisAnnotationValue = "resolved" @@ -120,13 +122,47 @@ var networkIngressPolicy = v1.NetworkPolicy{ { Protocol: &tcp, Port: &intstr.IntOrString{ - IntVal: int32(80), + Type: intstr.String, + StrVal: "http", }, }, { Protocol: &tcp, Port: &intstr.IntOrString{ - IntVal: int32(443), + Type: intstr.String, + StrVal: "https", + }, + }, + }, + }, + }, + Egress: []v1.NetworkPolicyEgressRule{}, + }, +} + +// networkWebhookPolicy allows for https traffic +// into the kube-system namespace to the ingress controller webhook. +var networkWebhookPolicy = v1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: defaultNetworkWebhookPolicyName, + }, + Spec: v1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/name": "rke2-ingress-nginx", + }, + }, + PolicyTypes: []v1.PolicyType{ + v1.PolicyTypeIngress, + }, + Ingress: []v1.NetworkPolicyIngressRule{ + { + Ports: []v1.NetworkPolicyPort{ + { + Protocol: &tcp, + Port: &intstr.IntOrString{ + Type: intstr.String, + StrVal: "webhook", }, }, }, @@ -258,6 +294,46 @@ func setNetworkIngressPolicy(ctx context.Context, cs *kubernetes.Clientset) erro return nil } +// setNetworkWebhookPolicy sets the default Ingress Webhook policy allowing the +// required webhook traffic to ingress nginx pods. +func setNetworkWebhookPolicy(ctx context.Context, cs *kubernetes.Clientset) error { + ns, err := cs.CoreV1().Namespaces().Get(ctx, metav1.NamespaceSystem, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("networkPolicy: get %s - %w", metav1.NamespaceSystem, err) + } + if ns.Annotations == nil { + ns.Annotations = make(map[string]string) + } + if _, ok := ns.Annotations[namespaceAnnotationNetworkWebhookPolicy]; !ok { + if _, err := cs.NetworkingV1().NetworkPolicies(metav1.NamespaceSystem).Get(ctx, defaultNetworkWebhookPolicyName, metav1.GetOptions{}); err == nil { + if err := cs.NetworkingV1().NetworkPolicies(metav1.NamespaceSystem).Delete(ctx, defaultNetworkWebhookPolicyName, metav1.DeleteOptions{}); err != nil { + if !apierrors.IsNotFound(err) { + return err + } + } + } + if _, err := cs.NetworkingV1().NetworkPolicies(metav1.NamespaceSystem).Create(ctx, &networkWebhookPolicy, metav1.CreateOptions{}); err != nil { + if !apierrors.IsAlreadyExists(err) { + return err + } + } + ns.Annotations[namespaceAnnotationNetworkWebhookPolicy] = cisAnnotationValue + + if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { + if _, err := cs.CoreV1().Namespaces().Update(ctx, ns, metav1.UpdateOptions{}); err != nil { + if apierrors.IsConflict(err) { + return updateNamespaceRef(ctx, cs, ns) + } + return err + } + return nil + }); err != nil { + logrus.Fatalf("networkPolicy: update namespace: %s - %s", ns.Name, err.Error()) + } + } + return nil +} + // setNetworkPolicies applies a default network policy across the 3 primary namespaces. func setNetworkPolicies(cisMode bool, namespaces []string) cmds.StartupHook { return func(ctx context.Context, wg *sync.WaitGroup, args cmds.StartupHookArgs) error { @@ -289,6 +365,10 @@ func setNetworkPolicies(cisMode bool, namespaces []string) cmds.StartupHook { logrus.Fatal(err) } + if err := setNetworkWebhookPolicy(ctx, cs); err != nil { + logrus.Fatal(err) + } + logrus.Info("Applying network policies complete") }()