Skip to content

Commit

Permalink
fix cert scraping on newer Linkerd versions (#48)
Browse files Browse the repository at this point in the history
The `_l5d_ns` and `_l5d_trustdomain` were recently removed from the
proxy definitions in Linkerd. This breaks cert scraping functionality. This PR
fixes that by instead relying on the `LINKERD2_PROXY_IDENTITY_LOCAL_NAME`
var whenever possible and filling in the svc account and namespace for the pod. 

close #47

Signed-off-by: Zahari Dichev <[email protected]>
  • Loading branch information
zaharidichev authored Feb 16, 2022
1 parent c71e75c commit 0ffc6eb
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 8 deletions.
42 changes: 36 additions & 6 deletions agent/pkg/k8s/certificates.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/tls"
"fmt"
"net"
"strings"
"time"

pb "github.com/buoyantio/linkerd-buoyant/gen/bcloud"
Expand All @@ -17,11 +18,12 @@ import (
)

const (
identityComponentName = "identity"
linkerdNsEnvVarName = "_l5d_ns"
linkerdTrustDomainEnvVarName = "_l5d_trustdomain"
trustRootsConfigMapName = "linkerd-identity-trust-roots"
trustRootsConfigMapKeyName = "ca-bundle.crt"
identityComponentName = "identity"
linkerdNsEnvVarName = "_l5d_ns"
linkerdTrustDomainEnvVarName = "_l5d_trustdomain"
linkerdProxyIdentityEnvVarName = "LINKERD2_PROXY_IDENTITY_LOCAL_NAME"
trustRootsConfigMapName = "linkerd-identity-trust-roots"
trustRootsConfigMapKeyName = "ca-bundle.crt"
)

func (c *Client) GetControlPlaneCerts(ctx context.Context) (*pb.ControlPlaneCerts, error) {
Expand Down Expand Up @@ -80,13 +82,40 @@ func (c *Client) getControlPlaneComponentPod(component string) (*v1.Pod, error)
func getServerName(podsa string, podns string, container *v1.Container) (string, error) {
var l5dns string
var l5dtrustdomain string
var localName string

for _, env := range container.Env {
if env.Name == linkerdNsEnvVarName {
l5dns = env.Value
}
if env.Name == linkerdTrustDomainEnvVarName {
l5dtrustdomain = env.Value
}

if env.Name == linkerdProxyIdentityEnvVarName {
localName = env.Value
}
}

if l5dns == "" && l5dtrustdomain == "" {
// on newer versions of Linkerd these are not set and the shape of the
// LINKERD2_PROXY_IDENTITY_LOCAL_NAME is different:
//
// edge-21.12.2
// _l5d_ns: linkerd
// _l5d_trustdomain: cluster.local
// LINKERD2_PROXY_IDENTITY_LOCAL_NAME: $(_pod_sa).$(_pod_ns).serviceaccount.identity.$(_l5d_ns).$(_l5d_trustdomain)
//
// edge-21.12.3
// LINKERD2_PROXY_IDENTITY_LOCAL_NAME: $(_pod_sa).$(_pod_ns).serviceaccount.identity.linkerd.cluster.local
if localName == "" {
return "", fmt.Errorf("could not find %s env var on proxy container [%s]", linkerdProxyIdentityEnvVarName, container.Name)
}

withSa := strings.Replace(localName, "$(_pod_sa)", podsa, 1)
withNs := strings.Replace(withSa, "$(_pod_ns)", podns, 1)

return withNs, nil
}

if l5dns == "" {
Expand All @@ -96,6 +125,7 @@ func getServerName(podsa string, podns string, container *v1.Container) (string,
if l5dtrustdomain == "" {
return "", fmt.Errorf("could not find %s env var on proxy container [%s]", linkerdTrustDomainEnvVarName, container.Name)
}

return fmt.Sprintf("%s.%s.serviceaccount.identity.%s.%s", podsa, podns, l5dns, l5dtrustdomain), nil
}

Expand All @@ -114,7 +144,7 @@ func (c *Client) extractRootsCerts(ctx context.Context, container *v1.Container,
cmName := ev.ValueFrom.ConfigMapKeyRef.Name
cm, err := c.k8sClient.CoreV1().ConfigMaps(namespace).Get(ctx, cmName, metav1.GetOptions{})
if err != nil {
return nil, fmt.Errorf("cannot obtain config map %s/%s", namespace, cmName)
return nil, fmt.Errorf("cannot obtain config map %s/%s: %w", namespace, cmName, err)
}

var ok bool
Expand Down
29 changes: 27 additions & 2 deletions agent/pkg/k8s/certificates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func TestGetServerName(t *testing.T) {
expectedErr error
}{
{
"gets correct name",
"gets correct name (_l5d_ns and _l5d_trustdomain env vars)",
&v1.Container{
Name: l5dk8s.ProxyContainerName,
Env: []v1.EnvVar{
Expand All @@ -253,6 +253,31 @@ func TestGetServerName(t *testing.T) {
fmt.Sprintf("%s.%s.serviceaccount.identity.linkerd.cluster.local", podSa, podNs),
nil,
},
{
"gets correct name (LINKERD2_PROXY_IDENTITY_LOCAL_NAME env var)",
&v1.Container{
Name: l5dk8s.ProxyContainerName,
Env: []v1.EnvVar{
{
Name: linkerdProxyIdentityEnvVarName,
Value: "$(_pod_sa).$(_pod_ns).serviceaccount.identity.linkerd.cluster.local",
},
},
},
fmt.Sprintf("%s.%s.serviceaccount.identity.linkerd.cluster.local", podSa, podNs),
nil,
},
{
"no env vars",
&v1.Container{
Name: l5dk8s.ProxyContainerName,
Env: []v1.EnvVar{
{},
},
},
"",
fmt.Errorf("could not find %s env var on proxy container [%s]", linkerdProxyIdentityEnvVarName, l5dk8s.ProxyContainerName),
},
{
"missing ns env var",
&v1.Container{
Expand Down Expand Up @@ -387,7 +412,7 @@ AiAtuoI5XuCtrGVRzSmRTl2ra28aV9MyTU7d5qnTAFHKSgIgRKCvluOSgA5O21p5
},
nil,
expectedRoots,
fmt.Errorf("cannot obtain config map linkerd/%s", trustRootsConfigMapName),
fmt.Errorf("cannot obtain config map linkerd/%s: configmaps \"%s\" not found", trustRootsConfigMapName, trustRootsConfigMapName),
},
{
"errors when config map key not present",
Expand Down

0 comments on commit 0ffc6eb

Please sign in to comment.