From f6266d099abb9754b531806263c774afc4208ee3 Mon Sep 17 00:00:00 2001 From: Dan Fuhry Date: Fri, 25 Oct 2024 11:46:00 -0400 Subject: [PATCH] [mtls] Support service identity from cert-manager-csi-driver-spiffe K8s support, commit 3 of 3. Check the default mount location of `cert-manager-csi-driver-spiffe` for service certificate discovery. Support default and certbot file naming schemes. --- mtls/provider_file.go | 67 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/mtls/provider_file.go b/mtls/provider_file.go index 1f01e49..284b784 100644 --- a/mtls/provider_file.go +++ b/mtls/provider_file.go @@ -49,6 +49,7 @@ const ( var ( mtlsRootPaths = []string{defaultMtlsRootPath} sslCertsBaseDir = "/etc/ssl/private" + k8sSpiffeDir = "/var/run/secrets/spiffe.io" defaultRootCAFile string defaultIntermediateCAFile string @@ -67,6 +68,50 @@ func LoadServiceIdentityFromFilesystem(serviceIdentity string) (*FileBackedCerti return nil, lastErr } +func LoadServiceIdentityFromKubernetesCSIDriverSPIFFE(serviceIdentity string) (*FileBackedCertificate, error) { + type fileNamingConvention struct { + leaf string + key string + ca string + } + + conventionsToTry := []*fileNamingConvention{ + {"tls.crt", "tls.key", "ca.crt"}, + {"fullchain.pem", "privkey.pem", "ca.pem"}, + } + + for _, c := range conventionsToTry { + ok := true + for _, file := range []string{c.leaf, c.key, c.ca} { + if err := fsutil.FileExistsAndIsReadable(path.Join(k8sSpiffeDir, file)); err != nil { + ok = false + } + } + + if !ok { + continue + } + + fbc := &FileBackedCertificate{ + LeafPath: path.Join(k8sSpiffeDir, c.leaf), + IntermediatesPath: path.Join(k8sSpiffeDir, c.leaf), + PrivateKeyPath: path.Join(k8sSpiffeDir, c.key), + RootPath: path.Join(k8sSpiffeDir, c.ca), + } + + if cert, err := fbc.LeafCertificate(); err == nil { + url := certutil.SpiffeUrlFromCertificate(cert) + if url != nil && url.Path == fmt.Sprintf("/service/%s", serviceIdentity) { + return fbc, nil + } + + logger.V(1).Warningf("found certificate from csi-driver-spiffe, but it's for a different identity: %q", url) + } + } + + return nil, fmt.Errorf("cannot find files for service identity %q in %q", serviceIdentity, k8sSpiffeDir) +} + func newFileBackedCertificateFromBaseDir(mtlsRootPath string, serviceIdentity string) (*FileBackedCertificate, error) { certDirectory := path.Join(mtlsRootPath, serviceIdentity) @@ -339,6 +384,9 @@ func (r *fileBackedRoots) tryLoadIntermediates() ([]*x509.Certificate, error) { if !cert.IsCA { continue } + if cert.Subject.String() == cert.Issuer.String() { + continue + } newInts = append(newInts, cert) } @@ -483,6 +531,16 @@ func init() { defaultFileBackedRoots := &fileBackedRoots{} + csiSpiffeRoots := &fileBackedRoots{ + RootPath: k8sSpiffeDir + "/ca.crt", + IntermediatesPath: k8sSpiffeDir + "/tls.crt", + } + + csiSpiffeRootsAltName := &fileBackedRoots{ + RootPath: k8sSpiffeDir + "/ca.pem", + IntermediatesPath: k8sSpiffeDir + "/fullchain.pem", + } + if homeDir := os.Getenv("HOME"); homeDir != "" { userMtlsPath := path.Join(homeDir, ".cache", "mtls") appendMtlsCertificateDir(userMtlsPath) @@ -497,10 +555,19 @@ func init() { registerIdentityDriver("file_service_global", func(serviceName string) (CertificateProvider, error) { return LoadServiceIdentityFromFilesystem(serviceName) }) + registerIdentityDriver("file_service_csi_spiffe", func(serviceName string) (CertificateProvider, error) { + return LoadServiceIdentityFromKubernetesCSIDriverSPIFFE(serviceName) + }) registerIdentityDriver("file_user_home", func(_ string) (CertificateProvider, error) { return LoadUserIdentityFromFilesystem() }) registerRootDriver("file_etc_mtls", func() (rootsPrimitive, error) { return defaultFileBackedRoots, nil }) + registerRootDriver("file_csi_spiffe", func() (rootsPrimitive, error) { + return csiSpiffeRoots, nil + }) + registerRootDriver("file_csi_spiffe_altname", func() (rootsPrimitive, error) { + return csiSpiffeRootsAltName, nil + }) } -- 2.50.1