guilhem / freeipa-issuer

A cert-manager external issuer for FreeIPA
Apache License 2.0
31 stars 14 forks source link

No commonName in certificate request #5

Closed StefanAbl closed 3 years ago

StefanAbl commented 3 years ago

When using cert-manger and this to secure an Ingress resource no commonName for the certificate request is generated and therefor issuing the certificate fails. Ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: tvh-ingress
  annotations:
    cert-manager.io/issuer: freeipa-issuer
    kubernetes.io/ingress.class: traefik
    cert-manager.io/issuer-group: certmanager.freeipa.org

spec:
  tls:
    - hosts:
      - tvh.i.k3test.dns.navy
      secretName: tvh-cert
  rules:
    - host: tvh.i.k3test.dns.navy
      http:
        paths:
          - path: /
            backend:
              serviceName: tvh
              servicePort: 9981
kubectl describe certificate tvh-cert
Name:         tvh-cert
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  cert-manager.io/v1
Kind:         Certificate
Metadata:
  Creation Timestamp:  2021-04-10T11:13:57Z
  Generation:          2
  Managed Fields:
    API Version:  cert-manager.io/v1
    Fields Type:  FieldsV1
    fieldsV1:
      f:metadata:
        f:ownerReferences:
          .:
          k:{"uid":"384b67ff-3e2d-471d-95dc-f4f66e664342"}:
            .:
            f:apiVersion:
            f:blockOwnerDeletion:
            f:controller:
            f:kind:
            f:name:
            f:uid:
      f:spec:
        .:
        f:dnsNames:
        f:issuerRef:
          .:
          f:group:
          f:kind:
          f:name:
        f:secretName:
        f:usages:
      f:status:
        .:
        f:conditions:
        f:lastFailureTime:
    Manager:    controller
    Operation:  Update
    Time:       2021-04-10T11:15:32Z
  Owner References:
    API Version:           networking.k8s.io/v1beta1
    Block Owner Deletion:  true
    Controller:            true
    Kind:                  Ingress
    Name:                  tvh-ingress
    UID:                   384b67ff-3e2d-471d-95dc-f4f66e664342
  Resource Version:        1912414
  UID:                     8f3b21e8-ad17-4d4c-aa27-a482b0dab99c
Spec:
  Dns Names:
    tvh.i.k3test.dns.navy
  Issuer Ref:
    Group:      certmanager.freeipa.org
    Kind:       Issuer
    Name:       freeipa-issuer
  Secret Name:  tvh-cert
  Usages:
    digital signature
    key encipherment
Status:
  Conditions:
    Last Transition Time:  2021-04-10T11:13:57Z
    Message:               Issuing certificate as Secret does not exist
    Observed Generation:   2
    Reason:                DoesNotExist
    Status:                False
    Type:                  Ready
    Last Transition Time:  2021-04-10T11:15:32Z
    Message:               The certificate request has failed to complete and will be retried: Failed to sign certificate request: Request has no common name
    Observed Generation:   2
    Reason:                Failed
    Status:                False
    Type:                  Issuing
  Last Failure Time:       2021-04-10T11:15:32Z
Events:
  Type     Reason     Age   From          Message
  ----     ------     ----  ----          -------
  Normal   Issuing    41m   cert-manager  Issuing certificate as Secret does not exist
  Normal   Generated  41m   cert-manager  Stored new private key in temporary Secret resource "tvh-cert-bspns"
  Normal   Requested  41m   cert-manager  Created new CertificateRequest resource "tvh-cert-b8442"
  Normal   Requested  40m   cert-manager  Created new CertificateRequest resource "tvh-cert-d7f8b"
  Warning  Failed     40m   cert-manager  The certificate request has failed to complete and will be retried: Failed to sign certificate request: Request has no common name

It fails in provisioners/freeipa.go when it checks for a common Name but there is no commonName.
Maybe a fallback could be added when no commonName is present in the request for example:

    //Maybe just addd a common name from the host name
    if csr.Subject.CommonName == "" {
        if len(csr.DNSNames) > 0 {
            csr.Subject.CommonName = csr.DNSNames[0]
        }else {
            return nil, nil, fmt.Errorf("Request has no common name")
        }
    }
StefanAbl commented 3 years ago

Never mind. I did not see that the common name for a ingress resource could be set using the annotation: cert-manager.io/common-name.

guilhem commented 3 years ago

@StefanAbl commonName was really painful to use with freeipa and library (nothing really work like we can imagine). But your solution is really good, I think.

StefanAbl commented 3 years ago

Thanks, this was sort of hard to find, since it is not in the documentation for securing ingress. I found support for the common-name annotation was added here. I don't think this increases the required version of cert-manager.