From 6b496588323c9b10fd5cc1b517cb2ae88ca239c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Nussbaumer?= Date: Wed, 2 Mar 2022 15:18:27 +0100 Subject: [PATCH] feat: start implementing IP whitelist vaildation https://github.com/postfinance/kubelet-csr-approver/issues/28 --- internal/controller/csr_controller.go | 5 ++++- internal/controller/regex_ip_checks.go | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/internal/controller/csr_controller.go b/internal/controller/csr_controller.go index 9dc1939..8cd327f 100644 --- a/internal/controller/csr_controller.go +++ b/internal/controller/csr_controller.go @@ -22,6 +22,7 @@ import ( "fmt" "strings" + "inet.af/netaddr" certificatesv1 "k8s.io/api/certificates/v1" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -45,6 +46,7 @@ type CertificateSigningRequestReconciler struct { client.Client Scheme *runtime.Scheme ProviderRegexp func(string) bool + ProviderIPSet *netaddr.IPSet MaxExpirationSeconds int32 BypassDNSResolution bool Resolver HostResolver @@ -55,7 +57,8 @@ type CertificateSigningRequestReconciler struct { //+kubebuilder:rbac:groups=certificates.k8s.io,resources=signers,resourceNames="kubernetes.io/kubelet-serving",verbs=approve // Reconcile will perform a series of checks before deciding whether the CSR should be approved or denied -//nolint: gocyclo // cyclomatic complexity is high (over 15), but this improves readibility for the programmer, therefore we ignore the linting error +// readibility for the programmer, therefore we ignore the linting error +//nolint: gocyclo // cyclomatic complexity is high (over 15), but this improves func (r *CertificateSigningRequestReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, returnErr error) { l := log.FromContext(ctx) diff --git a/internal/controller/regex_ip_checks.go b/internal/controller/regex_ip_checks.go index cd6cb4b..a628304 100644 --- a/internal/controller/regex_ip_checks.go +++ b/internal/controller/regex_ip_checks.go @@ -83,3 +83,25 @@ func (r *CertificateSigningRequestReconciler) DNSCheck(ctx context.Context, csr return valid, reason, nil } + +// WhitelistedIPCheck verifies that the x509cr IP Addresses are contained in the +// set of ProviderSpecified IP addresses +func (r *CertificateSigningRequestReconciler) WhitelistedIPCheck(csr *certificatesv1.CertificateSigningRequest, x509cr *x509.CertificateRequest) (valid bool, reason string, err error) { + sanIPAddrs := x509cr.IPAddresses + for _, ip := range sanIPAddrs { + ipa, ok := netaddr.FromStdIP(ip) + if !ok { + return false, fmt.Sprintf("Error while parsing x509 CR IP address %s, denying the CSR", ip), nil + } + + if !r.ProviderIPSet.Contains(ipa) { + return false, + fmt.Sprintf( + "One of the SAN IP addresses, %s, is not part"+ + "of the allowed IP Prefixes/Subnets, denying the CSR.", ipa), + nil + } + } + + return valid, reason, nil +}