Linkerd2: cli: identity cert <pod-selection>

Created on 21 May 2020  路  21Comments  路  Source: linkerd/linkerd2

Add an identity cert command that returns the certificates from a selection of pods.

These certificates can be obtained by initializing an SNI TLS session to the proxy's admin port. For example:

:; echo | \
    openssl s_client -servername linkerd-service-mirror.linkerd-multicluster.serviceaccount.identity.linkerd.dev.k3d.example.com -connect localhost:4191 2>/dev/null | \
    openssl x509 -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 10 (0xa)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: CN = identity.linkerd.dev.k3d.example.com
        Validity
            Not Before: May 21 18:23:35 2020 GMT
            Not After : May 22 18:24:15 2020 GMT
        Subject: CN = linkerd-service-mirror.linkerd-multicluster.serviceaccount.identity.linkerd.dev.k3d.example.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:ee:d4:33:af:83:5f:91:75:aa:b4:82:cd:74:21:
                    11:4d:04:86:98:19:49:30:2f:07:25:b1:18:67:a9:
                    ae:8d:9f:ce:d8:23:61:93:d0:c5:3a:98:fd:3b:9b:
                    e7:53:98:0f:0d:7a:21:33:8e:ec:87:a6:9b:68:cb:
                    e7:92:41:a0:eb
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Authority Key Identifier: 
                keyid:97:63:30:F1:04:94:17:50:CB:9F:1D:73:FB:FB:06:DC:D8:5A:0E:FD
            X509v3 Subject Alternative Name: 
                DNS:linkerd-service-mirror.linkerd-multicluster.serviceaccount.identity.linkerd.dev.k3d.example.com
    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:d9:d1:c6:c1:34:79:f9:44:db:7c:9b:82:f3:
         a0:8c:39:b2:aa:c6:3b:d2:1b:9b:d6:2d:06:fa:f6:c2:83:eb:
         b6:02:20:3a:ca:e7:c8:bf:af:91:5d:76:59:da:08:50:83:d9:
         02:2b:81:c0:97:77:5b:83:32:fb:54:59:5b:1c:4f:71:95
-----BEGIN CERTIFICATE-----
MIICSDCCAe6gAwIBAgIBCjAKBggqhkjOPQQDAjAvMS0wKwYDVQQDEyRpZGVudGl0
eS5saW5rZXJkLmRldi5rM2QuZXhhbXBsZS5jb20wHhcNMjAwNTIxMTgyMzM1WhcN
MjAwNTIyMTgyNDE1WjBqMWgwZgYDVQQDE19saW5rZXJkLXNlcnZpY2UtbWlycm9y
LmxpbmtlcmQtbXVsdGljbHVzdGVyLnNlcnZpY2VhY2NvdW50LmlkZW50aXR5Lmxp
bmtlcmQuZGV2LmszZC5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH
A0IABO7UM6+DX5F1qrSCzXQhEU0EhpgZSTAvByWxGGepro2fztgjYZPQxTqY/Tub
51OYDw16ITOO7Iemm2jL55JBoOujgb8wgbwwDgYDVR0PAQH/BAQDAgWgMB0GA1Ud
JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAfBgNVHSMEGDAWgBSXYzDxBJQXUMuf
HXP7+wbc2FoO/TBqBgNVHREEYzBhgl9saW5rZXJkLXNlcnZpY2UtbWlycm9yLmxp
bmtlcmQtbXVsdGljbHVzdGVyLnNlcnZpY2VhY2NvdW50LmlkZW50aXR5Lmxpbmtl
cmQuZGV2LmszZC5leGFtcGxlLmNvbTAKBggqhkjOPQQDAgNIADBFAiEA2dHGwTR5
+UTbfJuC86CMObKqxjvSG5vWLQb69sKD67YCIDrK58i/r5FddlnaCFCD2QIrgcCX
d1uDMvtUWVscT3GV
-----END CERTIFICATE-----

The CLI would probably port-forward to each pod and do this (like the metrics command).

We would ideally support label-selectors.

arecli good first issue help wanted

All 21 comments

Hi, pls can you assign this task to me

So it means, there should be a command

linkerd identity cert <podselection>

to get the correct certificate for the pod. Apart from using the pod names, pod labels can also be used as well?

I'd do linkerd identity get [name], allow linkerd identity get for all pods in a namespace and linkerd identity get -l label=value as a selector.

@sannimichaelse that make sense to you?

Yea makes sense.in case of certificates for several pods, how should it be displayed to avoid cluttering on the terminal

@sannimichaelse For the first pass at this, I think it's fine just to concatenate the output, similarly to the way kubectl describe works when describing multiple resources.

Alright

@olix0r WDYT about making this into YAML? Then we can just concat these and you get the metadata to know what each is.

kind: LinkerdCertificate
metdata:
  name: my-pod-123345-12345
  namespace: default
certificate: |
  Certificate:
  Data:
      Version: 3 (0x2)
      Serial Number: 10 (0xa)
      Signature Algorithm: ecdsa-with-SHA256
      Issuer: CN = identity.linkerd.dev.k3d.example.com
      Validity
          Not Before: May 21 18:23:35 2020 GMT
          Not After : May 22 18:24:15 2020 GMT
      Subject: CN = linkerd-service-mirror.linkerd-multicluster.serviceaccount.identity.linkerd.dev.k3d.example.com
      Subject Public Key Info:
          Public Key Algorithm: id-ecPublicKey
              Public-Key: (256 bit)
              pub:
                  04:ee:d4:33:af:83:5f:91:75:aa:b4:82:cd:74:21:
                  11:4d:04:86:98:19:49:30:2f:07:25:b1:18:67:a9:
                  ae:8d:9f:ce:d8:23:61:93:d0:c5:3a:98:fd:3b:9b:
                  e7:53:98:0f:0d:7a:21:33:8e:ec:87:a6:9b:68:cb:
                  e7:92:41:a0:eb
              ASN1 OID: prime256v1
              NIST CURVE: P-256
      X509v3 extensions:
          X509v3 Key Usage: critical
              Digital Signature, Key Encipherment
          X509v3 Extended Key Usage: 
              TLS Web Server Authentication, TLS Web Client Authentication
          X509v3 Authority Key Identifier: 
              keyid:97:63:30:F1:04:94:17:50:CB:9F:1D:73:FB:FB:06:DC:D8:5A:0E:FD
          X509v3 Subject Alternative Name: 
              DNS:linkerd-service-mirror.linkerd-multicluster.serviceaccount.identity.linkerd.dev.k3d.example.com
  Signature Algorithm: ecdsa-with-SHA256
       30:45:02:21:00:d9:d1:c6:c1:34:79:f9:44:db:7c:9b:82:f3:
       a0:8c:39:b2:aa:c6:3b:d2:1b:9b:d6:2d:06:fa:f6:c2:83:eb:
       b6:02:20:3a:ca:e7:c8:bf:af:91:5d:76:59:da:08:50:83:d9:
       02:2b:81:c0:97:77:5b:83:32:fb:54:59:5b:1c:4f:71:95
pem: |
    -----BEGIN CERTIFICATE-----
    MIICSDCCAe6gAwIBAgIBCjAKBggqhkjOPQQDAjAvMS0wKwYDVQQDEyRpZGVudGl0
    eS5saW5rZXJkLmRldi5rM2QuZXhhbXBsZS5jb20wHhcNMjAwNTIxMTgyMzM1WhcN
    MjAwNTIyMTgyNDE1WjBqMWgwZgYDVQQDE19saW5rZXJkLXNlcnZpY2UtbWlycm9y
    LmxpbmtlcmQtbXVsdGljbHVzdGVyLnNlcnZpY2VhY2NvdW50LmlkZW50aXR5Lmxp
    bmtlcmQuZGV2LmszZC5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH
    A0IABO7UM6+DX5F1qrSCzXQhEU0EhpgZSTAvByWxGGepro2fztgjYZPQxTqY/Tub
    51OYDw16ITOO7Iemm2jL55JBoOujgb8wgbwwDgYDVR0PAQH/BAQDAgWgMB0GA1Ud
    JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAfBgNVHSMEGDAWgBSXYzDxBJQXUMuf
    HXP7+wbc2FoO/TBqBgNVHREEYzBhgl9saW5rZXJkLXNlcnZpY2UtbWlycm9yLmxp
    bmtlcmQtbXVsdGljbHVzdGVyLnNlcnZpY2VhY2NvdW50LmlkZW50aXR5Lmxpbmtl
    cmQuZGV2LmszZC5leGFtcGxlLmNvbTAKBggqhkjOPQQDAgNIADBFAiEA2dHGwTR5
    +UTbfJuC86CMObKqxjvSG5vWLQb69sKD67YCIDrK58i/r5FddlnaCFCD2QIrgcCX
    d1uDMvtUWVscT3GV
    -----END CERTIFICATE-----

@grampelberg It seems a little weird to have pretty-formatted text inside of the yaml. I would expect -o yaml to properly encode all of the actual certificate details as yaml (i.e. with base64-encoded binary blobs. I think the kubectl describe analogy is apt here, but I don't feel too strongly...

TIL describe does multiple outputs. 馃憤 to that format.

I need to clarify somethings

  1. to get certificate with pod = "testPod", how do I pass the pod name or pod label to the TLS SNI command with openssl
echo | \
    openssl s_client -servername linkerd-service-mirror.linkerd-multicluster.serviceaccount.identity.linkerd.dev.k3d.example.com -connect localhost:4191 2>/dev/null | \
    openssl x509 -text
  1. in the cli folder under cmd, can I create a new file called identity and add commands there to separate it since its used for getting certificates or is there an existing file related to certificates in the cli that can be used

@olix0r

@sannimichaelse i'd recommend using slack for this style of questions, we'll be more responsive there =) @Pothulapati can help out with most of these questions!

Thanks @grampelberg

@sannimichaelse @grampelberg I like to work on this

@tharun208 I just confirmed with @olix0r that this is something that we still want.

Instead of introducing a new subcommand identity, I think we can reuse the existing linkerd get command. So something like:

# return the mtls certs of all pods in the ns namespace
linkerd -n [ns] get identity

# return the mtls cert of pod_name
linkerd get identity [pod_name]

# return the mtls certs of all pods selected by the label selector
linkerd get identity -l key=value

We can use the output format that @grampelberg described in https://github.com/linkerd/linkerd2/issues/4459#issuecomment-634216369. Note that when using label selector, a list of the custom resources will be returned.

Following the openssl TLS SNI example above, the server name will need to be constructed from the pod attributes. See the LINKERD2_PROXY_IDENTITY_LOCAL_NAME environment variable of the Linkerd proxy container.

Hi, Is this issue still open? and If anyone is not working on it, I would like to complete this task.

@Shubham8287 Yes. I still think we'd very much like to add this to the CLI.

But I think in the latest release, the CLI no longer supports the get command, so we need to introduce a new identity command for this, right?

@jimil749 that's correct

So I thought of giving this a shot. What I've been able to achieve as of yet is following:

  • Since the get command is no longer supported, I added a identity command, which currently works for a single pod. (linkerd identity pod/<pod-name> gets the certificate for mentioned pod)
  • I used go's X509.Certificate struct type for the certificates, so the output may differ in some aspects compared to what is above.

I had question about getting certificates for all pods in namespace, what command are we looking for that, should I just add command like linkerd identity get which fetches the certificates for all the pods in the namespace? Also, about the output, currently I am just printing the entire struct as it is, which looks a bit ugly. How does the output need to be?

I think ideally the linkerd identity command should support a -L / --selector flag (like many kubectl commands do) which accepts a label selector. The command would then get certificates for all pods which match that selector.

As for printing the cert, take a look at: https://github.com/linkerd/linkerd2/blob/main/pkg/tls/codec.go#L18

Was this page helpful?
0 / 5 - 0 ratings