Git Product home page Git Product logo

openshift-acme's Introduction

Donate

openshift-acme

openshift-acme is ACME Controller for OpenShift and Kubernetes clusters. It will automatically provision certificates using ACME v2 protocol and manage their lifecycle including automatic renewals.

The controller is provider independent but to start with we would recommend you to use Let's Encrypt (https://letsencrypt.org). For more information checkout section Deploy.)

Enabling ACME certificates for your object

Once openshift-acme controller is running on your cluster all you have to do is annotate your Route or other supported object like this:

metadata:
  annotations:
    kubernetes.io/tls-acme: "true"

Deploy

openshift-acme provides multiple options to deploy the controller so you can deploy it even as a regular user in a shared cluster only for specific namespaces you have access to. We intentionally avoid using CRDs which require system:admin privileges.

We have created deployments to get you started in just a few seconds. (But feel free to create one that suits your needs.)

Let's encrypt provides two environments: live and staging. The environment is chosen based on the issuer ConfigMap that is created.

Staging

staging is meant for testing the controller or making sure you can try it out without the fear or exhausting your rate limits and it will provide you with certificates signed by Let's Encrypt staging CA making the certs not trusted!

Live

live will provide you with trusted certificates but has lower rate limits. This is what you want when you're done testing/evaluating the controller

Status

openshift-acme now supports only ACME v2 protocol. For the time of the transition the old images using ACME v1 are kept in docker.io/tnozicka/openshift-acme:v0.8.0. There is no plan to support the old version and while you can still use it until the endpoints are turned off, we advise you to try the new version of the controller and migrate.

Supported objects

Routes (OpenShift)

OpenShift Routes are fully supported.

If you annotate your Route with "acme.openshift.io/secret-name": "<secret_name>", the controller will synchronize the Route certificates into a Secret so you can use SSL in the passthrough mode and mount the secret into pods.

Roadmap

  • Advanced rate limiting (there is now support for basic rate limits)
  • Ingress (and Kubernetes) support
  • DNS validation support
  • CertificateRequests objects (when not using http-01 validation you don't need a Route)
  • Operator managing the deployment and upgrades

Mailing list

https://groups.google.com/d/forum/openshift-acme

openshift-acme's People

Contributors

adelton avatar andrewklau avatar dvrkps avatar jfchevrette avatar lukeelten avatar madmatah avatar mohammadkarimi23 avatar openshift-merge-robot avatar patlachance avatar rbo avatar seandilda avatar tnozicka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openshift-acme's Issues

Route secret names can cause issues

Currently openshift acme expects to be able to create a secret containing the keys that is the same name as the route. However I have seen that this plays against the expectations of users, who often call their application, application secret and route by the same name, and thus causes openshift acme to fail. You do get an error in the logs, but obviously this is not exposed to anyone who does not have access to the acme namespace (read all our customers), so the result can be a little confusing.
It would be better, imo, if the secret created appended -acme to the name so it would be less likely to result in secret name collisions.

caCertificate not removed/updated (ExtendedValidationFailed)

I enabled kubernetes.io/tls-acme on a route that so far used a non-ACME certificate. Doing so, however, resulted ExtendedValidationFailed error.

As far as I can tell this is caused by the fact that, for the old cert, spec.tls.caCertificate was set to the certificate authority. When openshift-acme issues a certificate it includes the CA cert in spec.tls.certificate however. This causes, rightfully, a validation error since there are now two CA certs in the chain. I believe openshift-acme should either a) remove spec.tls.caCertificate if it exists or b) move the CA cert from spec.tls.certificate to spec.tls.caCertificate.

Route before enabling ACME:

$ oc get route nice -o yaml    
apiVersion: v1
kind: Route
metadata:
  annotations:
    haproxy.router.openshift.io/timeout: 15m
    kubernetes.io/tls-acme: "false"
  creationTimestamp: 2018-01-30T12:37:52Z
  labels:
    app: nginx
  name: nice
  namespace: toco-nice-k5bs
  resourceVersion: "156537327"
  selfLink: /oapi/v1/namespaces/toco-nice-k5bs/routes/nice
  uid: 63890d86-05ba-11e8-9d6f-fa163ec9e279
spec:
  host: k5bs.tocco.ch
  port:
    targetPort: 80-tcp
  tls:
    caCertificate: |
      -----BEGIN CERTIFICATE-----
      MIIETTCCAzWgAwIBAgILBAAAAAABRE7wNjEwDQYJKoZIhvcNAQELBQAwVzELMAkG
      A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
      b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw
      MDBaFw0yNDAyMjAxMDAwMDBaMEwxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
      YWxTaWduIG52LXNhMSIwIAYDVQQDExlBbHBoYVNTTCBDQSAtIFNIQTI1NiAtIEcy
      MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2gHs5OxzYPt+j2q3xhfj
      kmQy1KwA2aIPue3ua4qGypJn2XTXXUcCPI9A1p5tFM3D2ik5pw8FCmiiZhoexLKL
      dljlq10dj0CzOYvvHoN9ItDjqQAu7FPPYhmFRChMwCfLew7sEGQAEKQFzKByvkFs
      MVtI5LHsuSPrVU3QfWJKpbSlpFmFxSWRpv6mCZ8GEG2PgQxkQF5zAJrgLmWYVBAA
      cJjI4e00X9icxw3A1iNZRfz+VXqG7pRgIvGu0eZVRvaZxRsIdF+ssGSEj4k4HKGn
      kCFPAm694GFn1PhChw8K98kEbSqpL+9Cpd/do1PbmB6B+Zpye1reTz5/olig4het
      ZwIDAQABo4IBIzCCAR8wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C
      AQAwHQYDVR0OBBYEFPXN1TwIUPlqTzq3l9pWg+Zp0mj3MEUGA1UdIAQ+MDwwOgYE
      VR0gADAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3dy5hbHBoYXNzbC5jb20vcmVw
      b3NpdG9yeS8wMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nbG9iYWxzaWdu
      Lm5ldC9yb290LmNybDA9BggrBgEFBQcBAQQxMC8wLQYIKwYBBQUHMAGGIWh0dHA6
      Ly9vY3NwLmdsb2JhbHNpZ24uY29tL3Jvb3RyMTAfBgNVHSMEGDAWgBRge2YaRQ2X
      yolQL30EzTSo//z9SzANBgkqhkiG9w0BAQsFAAOCAQEAYEBoFkfnFo3bXKFWKsv0
      XJuwHqJL9csCP/gLofKnQtS3TOvjZoDzJUN4LhsXVgdSGMvRqOzm+3M+pGKMgLTS
      xRJzo9P6Aji+Yz2EuJnB8br3n8NA0VgYU8Fi3a8YQn80TsVD1XGwMADH45CuP1eG
      l87qDBKOInDjZqdUfy4oy9RU0LMeYmcI+Sfhy+NmuCQbiWqJRGXy2UzSWByMTsCV
      odTvZy84IOgu/5ZR8LrYPZJwR2UcnnNytGAMXOLRc3bgr07i5TelRS+KIz6HxzDm
      MTh89N1SyvNTBCVXVmaU6Avu5gMUTu79bZRknl7OedSyps9AsUSoPocZXun4IRZZUw==
      -----END CERTIFICATE-----
    certificate: |
      -----BEGIN CERTIFICATE-----
      MIIHQjCCBiqgAwIBAgIMNiLPbxmGVkUgGt8qMA0GCSqGSIb3DQEBCwUAMEwxCzAJ
      BgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSIwIAYDVQQDExlB
      bHBoYVNTTCBDQSAtIFNIQTI1NiAtIEcyMB4XDTE2MDkwNzA5MDQ1NloXDTE5MDkw
      ODA5MDQ1NlowODEhMB8GA1UECxMYRG9tYWluIENvbnRyb2wgVmFsaWRhdGVkMRMw
      EQYDVQQDDAoqLnRvY2NvLmNoMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
      AQEAyxzBBSIASSMaALvIv1MSt1CjZs01tCFUSQHPM0auRxFfPaUJrD0xNQbLY6wX
      CQkHV9TKNjmxrXTKj4vJdq7XUGtB445dOKHvAUr5fQw3YVaHRbAUA6LaKGOO8M7o
      mzdBtQnaLFKwZKCAH3VjxGXd51h5LHUNA//0uwDqNq+KeKXrfHbmHw1jF4i8aLcF
      3KIQaSQVV7jdcVNerkFieIglmBhM90KswTIuB3rQ8yyWqAsaXUXsUJQyzQ04lhHh
      OzkbzekNEj2/BTWjh9k/NIoYsDMFlUnJkWwLxhjByuGNIaKqHy1ViaPeZhuVmzLk
      qhwc+p5dxc5kyWFZYaakQW6zUQIDAQABo4IENjCCBDIwDgYDVR0PAQH/BAQDAgWg
      MIGJBggrBgEFBQcBAQR9MHswQgYIKwYBBQUHMAKGNmh0dHA6Ly9zZWN1cmUyLmFs
      cGhhc3NsLmNvbS9jYWNlcnQvZ3NhbHBoYXNoYTJnMnIxLmNydDA1BggrBgEFBQcw
      AYYpaHR0cDovL29jc3AyLmdsb2JhbHNpZ24uY29tL2dzYWxwaGFzaGEyZzIwVwYD
      VR0gBFAwTjBCBgorBgEEAaAyAQoKMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3
      Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMAgGBmeBDAECATAJBgNVHRMEAjAA
      MD4GA1UdHwQ3MDUwM6AxoC+GLWh0dHA6Ly9jcmwyLmFscGhhc3NsLmNvbS9ncy9n
      c2FscGhhc2hhMmcyLmNybDAfBgNVHREEGDAWggoqLnRvY2NvLmNoggh0b2Njby5j
      aDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYDVR0OBBYEFBKfZeVA
      FDywmENZmnN1NNel10aBMB8GA1UdIwQYMBaAFPXN1TwIUPlqTzq3l9pWg+Zp0mj3
      MIICbgYKKwYBBAHWeQIEAgSCAl4EggJaAlgAdgBo9pj4H2SCvjqM7rkoHUz8cVFd
      Z5PURNEKZ6y7T0/7xAAAAVcD5KUPAAAEAwBHMEUCIB0C0PO45BYFp6KbLzWCn7zE
      QQuzRZ8HLAF64GEKTNmVAiEA8ZkJRkIcn7o7p5uWdlRLvuV4WMdXa6sQea67On4q
      zCwAdQCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAVcD5KruAAAE
      AwBGMEQCIChezhVnCHcP2yDy0HKhsIio+fBZDTK5McXGHb0/tY+KAiAOK61xBB/r
      ju3LOddJqSIqQBQTb5U1QspB/863ARuriQB2AO5Lvbd1zmC64UJpH6vhnmajD35f
      sHLYgwDEe4l6qP3LAAABVwPks+QAAAQDAEcwRQIgYp4HFGFgq3trEdm5y0UTICFj
      F5aufsA+1NCPzHH+M8gCIQDAg+iHhhlvPf/U71CVbLUa91qlOw04KjpZbSfUUFcu
      6QB2AN3rHSt6DU+mIIuBrYFocH4ujp0B1VyIjT0RxM227L7MAAABVwPkuJQAAAQD
      AEcwRQIhAKtgtqC5ryNbTKd4g0jVd23nu6/SfdYpSeQqEKi6lXDBAiBVk96zfXPA
      sjuH74sBJ/7EICHILu0O1ekyI3li+c79mwB3AFYUBpov18Ls0/XhvUSyPsdGdrm8
      mRFcwO+UmFXWidDdAAABVwPkvGQAAAQDAEgwRgIhAPnGQy0lMxa9zBq+uWaN0oL3
      sLJTCMfIdxiIzwKTH2alAiEA04vYgYP1hazfGsZ5nt24XpGpKnem/Vf+jj/JmHIG
      q10wDQYJKoZIhvcNAQELBQADggEBAG3v7ptCmQUvMfcY5v2sFE6vOsZPw0DJ9xFH
      MwEbXRkMq8iGEPNdB8Aqnrz1KzwbosFNIGXA78TW6Zkw6M3ZJkQAdc1JrGDcosgz
      eieVzslUBoJ6fqN5NGUDLhIHYQaHKa2fzg8kppNbKTx5wGxooa5Vqlv7sLYVCjMB
      FFVbfa2PHCaVOX9PxZbzp7pcWVtpJ8YtgyH8XbY6weXp9NBUaOy5WNbO4XTU9PqQ
      4PYvKk+p8Lf4sCPATKmv2FOSKoSBkj77kBCiGYpEMBHvry1qZG8VDFAFgO2kvx8L
      tJnklfzEwjpklyzZCnx/DeayZE3fmQ0l3INoV4Wvjv5LgS6s+Hg=
      -----END CERTIFICATE-----
    insecureEdgeTerminationPolicy: Redirect
    key: |
      -----BEGIN PRIVATE KEY-----
      …
      -----END PRIVATE KEY-----
    termination: edge
  to:
    kind: Service
    name: nice
    weight: 100
  wildcardPolicy: None
status:
  ingress:
  - conditions:
    - lastTransitionTime: 2018-01-30T12:37:52Z
      status: "True"
      type: Admitted
    host: k5bs.tocco.ch
    routerName: router
    wildcardPolicy: None

Route after enabling ACME:

$ oc get route nice -o yaml
apiVersion: v1
kind: Route
metadata:
  annotations:
    haproxy.router.openshift.io/timeout: 15m
    kubernetes.io/tls-acme: "true"
    kubernetes.io/tls-acme-awaiting-authorization-owner: https://acme-v01.api.letsencrypt.org/acme/reg/31528540
  creationTimestamp: 2018-01-30T12:37:52Z
  labels:
    app: nginx
  name: nice
  namespace: toco-nice-k5bs
  resourceVersion: "164578257"
  selfLink: /oapi/v1/namespaces/toco-nice-k5bs/routes/nice
  uid: 63890d86-05ba-11e8-9d6f-fa163ec9e279
spec:
  host: k5bs.tocco.ch
  port:
    targetPort: 80-tcp
  tls:
    caCertificate: |
      -----BEGIN CERTIFICATE-----
      MIIETTCCAzWgAwIBAgILBAAAAAABRE7wNjEwDQYJKoZIhvcNAQELBQAwVzELMAkG
      A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
      b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw
      MDBaFw0yNDAyMjAxMDAwMDBaMEwxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
      YWxTaWduIG52LXNhMSIwIAYDVQQDExlBbHBoYVNTTCBDQSAtIFNIQTI1NiAtIEcy
      MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2gHs5OxzYPt+j2q3xhfj
      kmQy1KwA2aIPue3ua4qGypJn2XTXXUcCPI9A1p5tFM3D2ik5pw8FCmiiZhoexLKL
      dljlq10dj0CzOYvvHoN9ItDjqQAu7FPPYhmFRChMwCfLew7sEGQAEKQFzKByvkFs
      MVtI5LHsuSPrVU3QfWJKpbSlpFmFxSWRpv6mCZ8GEG2PgQxkQF5zAJrgLmWYVBAA
      cJjI4e00X9icxw3A1iNZRfz+VXqG7pRgIvGu0eZVRvaZxRsIdF+ssGSEj4k4HKGn
      kCFPAm694GFn1PhChw8K98kEbSqpL+9Cpd/do1PbmB6B+Zpye1reTz5/olig4het
      ZwIDAQABo4IBIzCCAR8wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C
      AQAwHQYDVR0OBBYEFPXN1TwIUPlqTzq3l9pWg+Zp0mj3MEUGA1UdIAQ+MDwwOgYE
      VR0gADAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3dy5hbHBoYXNzbC5jb20vcmVw
      b3NpdG9yeS8wMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nbG9iYWxzaWdu
      Lm5ldC9yb290LmNybDA9BggrBgEFBQcBAQQxMC8wLQYIKwYBBQUHMAGGIWh0dHA6
      Ly9vY3NwLmdsb2JhbHNpZ24uY29tL3Jvb3RyMTAfBgNVHSMEGDAWgBRge2YaRQ2X
      yolQL30EzTSo//z9SzANBgkqhkiG9w0BAQsFAAOCAQEAYEBoFkfnFo3bXKFWKsv0
      XJuwHqJL9csCP/gLofKnQtS3TOvjZoDzJUN4LhsXVgdSGMvRqOzm+3M+pGKMgLTS
      xRJzo9P6Aji+Yz2EuJnB8br3n8NA0VgYU8Fi3a8YQn80TsVD1XGwMADH45CuP1eG
      l87qDBKOInDjZqdUfy4oy9RU0LMeYmcI+Sfhy+NmuCQbiWqJRGXy2UzSWByMTsCV
      odTvZy84IOgu/5ZR8LrYPZJwR2UcnnNytGAMXOLRc3bgr07i5TelRS+KIz6HxzDm
      MTh89N1SyvNTBCVXVmaU6Avu5gMUTu79bZRknl7OedSyps9AsUSoPocZXun4IRZZUw==
      -----END CERTIFICATE-----
    certificate: |
      -----BEGIN CERTIFICATE-----
      MIIHBjCCBe6gAwIBAgISA1Vc/rWFC4cKKyIJ2Y/PHFJwMA0GCSqGSIb3DQEBCwUA
      MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
      ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xODA0MjQxMTA5NDFaFw0x
      ODA3MjMxMTA5NDFaMBgxFjAUBgNVBAMTDWs1YnMudG9jY28uY2gwggIiMA0GCSqG
      SIb3DQEBAQUAA4ICDwAwggIKAoICAQC6t/xTGDeaqtM+2EDBRNo4ypfGw56IMIae
      CzgUuoKanXhFX6W8YfATG73L7AjwKS32s/SuBrfSTBOgLJkLTXzb+Nc4Wli8usrI
      fkaEcOOS949BDvIzTkGnQeba0t7xiwr991JFq4xlu/OKO588npHLdmb2IBuvDr7H
      GPSEuTocjdsTW0TrzwPJjH6ulH/XxthWYQP2ZCBg1n9kn/Bp7YcpkIZMGfqR0ix1
      bPvwosioNNv/KbmSFjA7o0biKZBaTdKO6UuQHbNlIs1gLlyJjnG6MiABM6TZaHBK
      pruH84rD5H5S7BVXkHOyVKNBaO+yQ8WDRioTOICpcCJl9v76a65Ep8dTefnxYGZV
      CiKotRuQc+gd90btWxwtIpOGFpEKe7azTTpmqv3ZNQpnxtfQrewI69+V1RY3rOIl
      zIx4cSHnJFn0MTrwhNfzoUL//o/djSg+4CuN6clKU2v1dq5VUpP21i2Pw7lBr8ZE
      m4o7ZIE10WWMD/S8Lc7bBEIZA8+gLJWIuI9l/tFGrCqA+SI+WaES93YVMbK0sPCm
      SxuKzYrkaR9F+wNsdr4PiEp3XmsV+YVWx+fJe89OfCbreylOZLmVX7IqNoWYzBlo
      N7WTOy5g3NFwL8pBoiIVHCh1ketywo0wVJrX+Po8yabWDEFeCiWGdcOu2QAPshO1
      cjvSPMqQIwIDAQABo4IDFjCCAxIwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQG
      CCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBR85T26
      UoNeNo2jtB8mQO6ON0mltTAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86js
      oTBvBggrBgEFBQcBAQRjMGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14
      My5sZXRzZW5jcnlwdC5vcmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14
      My5sZXRzZW5jcnlwdC5vcmcvMBgGA1UdEQQRMA+CDWs1YnMudG9jY28uY2gwgf4G
      A1UdIASB9jCB8zAIBgZngQwBAgEwgeYGCysGAQQBgt8TAQEBMIHWMCYGCCsGAQUF
      BwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCBqwYIKwYBBQUHAgIwgZ4M
      gZtUaGlzIENlcnRpZmljYXRlIG1heSBvbmx5IGJlIHJlbGllZCB1cG9uIGJ5IFJl
      bHlpbmcgUGFydGllcyBhbmQgb25seSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIENl
      cnRpZmljYXRlIFBvbGljeSBmb3VuZCBhdCBodHRwczovL2xldHNlbmNyeXB0Lm9y
      Zy9yZXBvc2l0b3J5LzCCAQUGCisGAQQB1nkCBAIEgfYEgfMA8QB3ANt0r+7LKeyx
      /so+cW0s5bmquzb3hHGDx12dTze2H79kAAABYvePOegAAAQDAEgwRgIhAIB3wPid
      0RXxrCcKSxMWNTyoB42O/P06ZBj1jVLQ89hhAiEA9W3u+5Ns2vLrl5lCDDebbsm6
      g89CRY4gGUunGMnpIaIAdgApPFGWVMg5ZbqqUPxYB9S3b79Yeily3KTDDPTlRUf0
      eAAAAWL3jzoNAAAEAwBHMEUCIHdcLMGAEIqaaE6pHP0GXHvKg4B3HuuqXTQ6xS7d
      M+l0AiEAjsY+2+8i7XlcEEnrPX3hKaCRYoEdOShnqqkGSNz2RyEwDQYJKoZIhvcN
      AQELBQADggEBAFvevOxb3gRar3XpMOip+0muXP7O5rd30M1DPoHa0CVzndQNbIfg
      rC7BmYOd+m0LZM+TBM7OPxfUVYT5n2DA9LBfyHmLudnkVhQjnErPMfGlD7R6bZkt
      dNvjFiiAAbzLlMaUnZSSfjjFKijLZk1ALix5sNL/Ogamxf9Se7IfesdKeEHzpULb
      WPFQuv/OWwGlRFUtQ3ZAfg8MxpDJ4b0HOPpxAzGn84hjOSK1xJMwT5n637+82Xby
      cjQR3rrj1egveeLYBpendaVb89h/IX2LjYyreRqm8AX+1JHvFojHmZDi6qXOhjTS
      +GAMI8D01lmtRloV1+2Hynh8+0+jPDMiSsk=
      -----END CERTIFICATE-----
      -----BEGIN CERTIFICATE-----
      MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
      MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
      DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
      SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
      GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
      AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
      q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
      SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
      Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
      a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
      /PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
      AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
      CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
      bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
      c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
      VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
      ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
      MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
      Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
      AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
      uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
      wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
      X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
      PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
      KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
      -----END CERTIFICATE-----
    insecureEdgeTerminationPolicy: Redirect
    key: |
      -----BEGIN RSA PRIVATE KEY-----
      …
      -----END RSA PRIVATE KEY-----
    termination: edge
  to:
    kind: Service
    name: nice
    weight: 100
  wildcardPolicy: None
status:
  ingress:
  - conditions:
    - lastTransitionTime: 2018-04-24T12:09:42Z
      message: |2-

          - spec.tls.certificate: Invalid value: "redacted certificate data": error verifying certificate: x509: certificate signed by unknown authority
      reason: ExtendedValidationFailed
      status: "False"
      type: Admitted
    host: k5bs.tocco.ch
    routerName: router
    wildcardPolicy: None

Renew date never updated

When a certificate is renewed the next renew date is never updated and certificates get generated all time.

If i restart openshift-acme container, i see this:

2017-07-03T20:06:15.167145114Z DEBUG acme.go:146 notBefore=2017-04-10 14:41:00 +0000 UTC, notAfter=2017-07-09 14:41:00 +0000 UTC, renewTime=2017-06-09 14:41:00 +0000 UTC; renew=true
2017-07-03T20:06:15.167158793Z DEBUG acme.go:148 renewLoop: renewing certificate for: '[geoip.servicios.cmd.com.ar]'

The domain geoip.servicios.cmd.com.ar was updated few days ago, but continues generating new certificates.

After some renews, i get this error:
2017-07-03T20:11:26.216399682Z ERROR dbcertentry.go:84 429 urn:acme:error:rateLimited: Error creating new cert :: too many certificates already issued for exact set of domains: geoip.servicios.cmd.com.ar

In the annotations of the route i see:

  annotations:
    kubernetes.io/tls-acme: 'true'
    kubernetes.io/tls-acme.hash: usswMS7taGDLj0mV91f+1PFYqQZmORB2J9feJv8c+oQ=
    kubernetes.io/tls-acme.last-update-time: '2017-07-03T20:01:15Z'

And in the annotations of the secret:

  annotations:
    kubernetes.io/tls-acme.last-update-time: '2017-07-03T20:01:15Z'
    kubernetes.io/tls-acme.valid-not-after: '2017-07-03T20:01:15Z'
    kubernetes.io/tls-acme.valid-not-before: '2017-07-03T20:01:15Z'

Certificate creation error only on certain project.

Hi,
i got some weird behaviour when trying to use the acme controller on our openshift v 3.6.

  • it successfully generate the certificate for some project (either already existing project or newly created project)
  • it got the following error on a certain project
2017-10-05T06:11:38.148164248Z   INFO finished validating domains
2017-10-05T06:11:37.700152663Z  TRACE acme.Client ObtainCertificate duration=448.030325ms start=2017-10-05T06:11:37.700152794Z end=2017-10-05T06:11:38.148183119Z
2017-10-05T06:11:38.148239952Z  ERROR dbcertentry.go:79 [domain: domain.company.us, error: 403 urn:acme:error:unauthorized: No registration exists matching provided key]
  • it doesn't even caught the annotation and wont't start the request for project "default" and some other project.

we're using same deployment config & same service to expose on every project to test. And i think there shouldn't be any difference on all that project (except of the "default" project maybe ) as we don't do any special configuration for all the project we created.

Do you have any idea how do we begin to trace this different behaviour ?

Thank you in advance

Route not updating with TLS information

After getting the certificate via ACME, I'm seeing some errors when openshift-acme tries to update the route configuration.

I0316 20:13:18.882025   1 route.go:385] Started syncing Route "candlepin/external" (2018-03-16 20:13:18.882011441 +0000 UTC m=+635.609929176)                                                    
I0316 20:13:18.999077   1 route.go:483] Route "candlepin/external": authorization state is "valid"                                                                                           
I0316 20:13:18.999101   1 route.go:515] Authorization "https://acme-staging.api.letsencrypt.org/acme/authz/[...]" for Route candlepin/external successfully validated                                                                                                                                                                                           
I0316 20:13:33.905383   1 route.go:539] Route "candlepin/external" - created certificate available at https://acme-staging.api.letsencrypt.org/acme/cert/[...]    
I0316 20:13:33.917429   1 route.go:387] Finished syncing Route "candlepin/external" (15.035409245s)                                                                                              
I0316 20:13:33.917513   1 route.go:716] Error syncing Route candlepin/external: failed to update route candlepin/external with new certificates: Route "external" is invalid: spec.tls: Invalid val
ue: route.TLSConfig{...}: field is immutable

I'm sure I've got something misconfigured, but I'm not sure what.

cannot unmarshal number into Go value of type string

Seeing this issue with the most recent image. Was not seeing this error previously with the same configuration in the same cluster

2017-09-06T01:30:17.028605154Z   INFO Starting controller
  | 2017-09-06T01:30:17.028756809Z   INFO ACME server url is 'https://acme-v01.api.letsencrypt.org/directory'
  | ERROR: logging before flag.Parse: W0906 01:30:17.028786       1 client_config.go:481] Neither --kubeconfig nor --master was specified.  Using the inClusterConfig.  This might not work.
  | 2017-09-06T01:30:17.032524381Z   INFO AcmeController bootstraping DB
  | 2017-09-06T01:30:17.032552688Z  TRACE AcmeController bootstraping DB finished duration=40.403775ms start=2017-09-06T01:30:17.032552956Z end=2017-09-06T01:30:17.072956731Z
  | 2017-09-06T01:30:17.073004363Z   INFO AcmeController initializing
  | 2017-09-06T01:30:17.073057872Z   INFO AcmeController started
  | 2017-09-06T01:30:17.073306846Z   INFO Http-01: server listening on http://[::]:5000/
  | 2017-09-06T01:30:17.076501091Z   INFO RouteController initializing
  | 2017-09-06T01:30:17.076537988Z   INFO RouteController started
  | 2017-09-06T01:30:17.076562431Z   INFO RouteController: watching namespace ''
  | 2017-09-06T01:30:17.079674842Z  ERROR route.go:115 json: cannot unmarshal number into Go value of type string
  | 2017-09-06T01:30:17.079733483Z  ERROR route.go:192 RouteController: doWatchIteration failed: RouteController: failed to unmarshal Route: 'json: cannot unmarshal number into Go value of type string'
  | 2017-09-06T01:30:27.082780726Z   WARN route.go:98 RouteController: resetting resourceVersion: caused by 'ERROR' (unversioned.Status{TypeMeta:unversioned.TypeMeta{Kind:"Status", APIVersion:"v1"}, ListMeta:unversioned.ListMeta{SelfLink:"", ResourceVersion:""}, Status:"Failure", Message:"too old resource version: 2366 (10997)", Reason:"Gone", Details:(*unversioned.StatusDetails)(nil), Code:410})
  | 2017-09-06T01:30:27.082814043Z  ERROR route.go:192 RouteController: doWatchIteration failed: RouteController ResultChannel closed
 ```

Same symptoms in OpenShift Container Platform 3.5 and 3.6

ELI5 instructions

Hello

I have installed the controller (appuio/ansible-role-openshift-acme)

On the Readme it says:

Enabling ACME certificates for your object

metadata:
annotations:
kubernetes.io/tls-acme: "true"

I added this to my openshift route yml and service yml, but I still get the Your connection is not private error.

Specifically, where should I add this annotation?

acme-controller loops if project is being removed during registration

What I did

  • Create new Project, deploy app
  • annotate route with kubernetes.io/tls-acme
  • remove project before acme-controller finished his work

What I expected
acme-controller would stop after getting an error

What happened
The first time around, acme-controller failed to save the new LetsEncrypt account because the Project was already removed. acme-controller then retried to create LE-accounts again and again, always erroring because it could not save the account.

After 10 times, we hit the 10 accounts/3h rate limit (and acme-controller loops forever)


During tests I created a new project to test the acme-controller. I was a bit too hastly and removed the project before acme-controller finished his job. This lead to the following situation:

INFO Creating new account in namespace mhu-test
TRACE Creating new account in namespace mhu-test finished
ERROR route.go:192 RouteController: doWatchIteration failed: acme.Done failed: secrets "acme-account" is forbidden: unable to create new content in namespace mhu-test because it is being terminated.
 INFO Creating new account in namespace mhu-test
TRACE Creating new account in namespace mhu-test finished
ERROR route.go:192 RouteController: doWatchIteration failed: acme.Done failed: namespaces "mhu-test" not found
 INFO Creating new account in namespace mhu-test
... repeated a couple of times ...
ERROR route.go:192 RouteController: doWatchIteration failed: acme.Done failed: 429 urn:acme:error:rateLimited: Error creating new registration :: too many registrations for this IP
 INFO Creating new account in namespace mhu-test
... repeated over and over again ...

Support running on OpenShift with ovs-multitenant plugin

At this point we redirect traffic from the namespace where the Route is to the controller that is running usually in separate namespace. This design won't work by default with ovs-multitenant plugin.

I see 2 options:

  1. The controller would join acme-controller and the project namespaces for a while
  2. Run a pod exposing the secret directly in the namespace where the Route is

I am in favor of 2. as 1. would be complicated and we already do some magic with endpoints and treat same namespace differently to avoid the need for elevating permissions.

I was trying to avoid running pods as that is always complicated to manage and prone to suffer from kubelet bugs. But considering the need for joining networks and the fact that we can drop the endpoints magic I think this is the cleanest path.

support http/https proxies

Hello
In my setup, the openshift cluster is not directly attached to internet and need to use a squid proxy to reach internet. Standard linux environment variables are not used by the exposer.go component.

Add support for route labels (router sharding)

I'm running two OS3 routers: one "internal", one "public". The public router and routes exposed therein are accessible from the internet, the internal one is for LAN-only.

The public router only exposes routes that are labelled with (router=public (ENV ROUTE_LABELS=router=public)).

When openshift-acme creates the temporary .well-known route, it will be created without the router label and hence exposed on the local router. LetsEncrypt tries to verify the challenge, but gets a 404 response and fails.

Is there any way to work around this and tell openshift-acme the default labels the challenge route should get? Currently, I'm forced to disable ROUTE_LABELS and expose all routes to the Interwebs.

no route to host

Updating Route from test/gohellouniverse UID=9e16ea55-94cd-11e8-9d8c-901b0efe13b8 RV=957432 to test/gohellouniverse UID=9e16ea55-94cd-11e8-9d8c-901b0efe13b8,RV=957432
-- I0731 14:37:31.162076 1 reflector.go:286] github.com/tnozicka/openshift-acme/pkg/cmd/cmd.go:261:

forcing resync| W0731 14:39:32.589212 1 exposer.go:354] Failed to GET "http://test1.os.xxxxx.com/.well-known/acme-challenge/1E_AcMtAAtOTvtr4UZ4lgPKwsdPFlGrho3kacFoTAE": Get http://test1.os.xxxxx.com/.well-known/acme-challenge/1E_AcMtAAtOTvtr4UZ4lgPKwsdPFlGrho3kacFoTAE: dial tcp xxx.xxx.xxx.xx:80: connect: no route to host

first : github.com/tnozicka/openshift-acme/pkg/cmd/cmd.go does not exist

second: Get http://test1.os.xxxxx.com/.well-known/acme-challenge/1E_Ac MtAAtOTvtr4UZ4lgPKwsdPFlGrho3kacFoTAE: the colon is a part of the url which shouldn't be

allow multiple hostnames in certificate

That would not only help in not getting rate limited, but also when deploying non-http services that listen on different hosts. They could share a certificate that way.

Run on OpenShift Online

Updated with a deployable solution. WIP.

In order to run on OpenShift Online, do the following:

Replace acme-example with your project name (namespace):

oc project acme-example
oc policy add-role-to-group edit system:serviceaccounts:acme-example -n acme-example

Then deploy the following template, specify your project name in OPENSHIFT_ACME_SELFSERVICENAMESPACE and OPENSHIFT_ACME_WATCH_NAMESPACE (or add default values for them to the template)

apiVersion: v1
kind: Template
metadata:
  name: acme-controller
parameters:
- description: ACME Endpoint URL
  name: OPENSHIFT_ACME_ACMEURL
  value: https://acme-staging.api.letsencrypt.org/directory
- description: Controller loglevel
  name: OPENSHIFT_ACME_LOGLEVEL
  value: "8"
- description: Name of the service pointing to ACME controller
  name: OPENSHIFT_ACME_SELFSERVICENAME
  value: acme-controller
- description: Namespace of the service pointing to a pod with this program. Defaults to current or default namespace
  name: OPENSHIFT_ACME_SELFSERVICENAMESPACE
- description: Restrics controller to namespace. If not specified controller watches for routes accross namespaces.
  name: OPENSHIFT_ACME_WATCH_NAMESPACE
- description: Docker Image of ACME controller
  name: DOCKER_IMAGE
  value: docker.io/appuio/openshift-acme
- description: Docker Image Tag of ACME controller
  name: DOCKER_IMAGE_TAG
  value: latest
objects:
- apiVersion: v1
  kind: ServiceAccount
  metadata:
    name: acme-controller
- apiVersion: v1
  kind: ImageStream
  metadata:
    name: acme-controller
    labels:
      type: acme-controller
  spec:
    lookupPolicy:
      local: false
    tags:
    - annotations:
        openshift.io/imported-from: ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG}
      from:
        kind: DockerImage
        name: ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG}
      importPolicy:
        scheduled: true
      name: latest
      referencePolicy:
        type: Source
- apiVersion: v1
  kind: DeploymentConfig
  metadata:
    labels:
      app: acme-controller
    name: acme-controller
  spec:
    replicas: 1
    selector:
      app: acme-controller
    strategy:
      activeDeadlineSeconds: 21600
      recreateParams:
        timeoutSeconds: 600
      resources: {}
      type: Recreate
    template:
      metadata:
        labels:
          app: acme-controller
      spec:
        containers:
        - env:
          - name: OPENSHIFT_ACME_ACMEURL
            value: ${OPENSHIFT_ACME_ACMEURL}
          - name: OPENSHIFT_ACME_LOGLEVEL
            value: ${OPENSHIFT_ACME_LOGLEVEL}
          - name: OPENSHIFT_ACME_SELFSERVICENAME
            value: ${OPENSHIFT_ACME_SELFSERVICENAME}
          - name: OPENSHIFT_ACME_SELFSERVICENAMESPACE
            value: ${OPENSHIFT_ACME_SELFSERVICENAMESPACE}
          - name: OPENSHIFT_ACME_WATCH_NAMESPACE
            value: ${OPENSHIFT_ACME_WATCH_NAMESPACE}
          image: acme-controller:latest
          imagePullPolicy: IfNotPresent
          name: acme-controller
          ports:
          - containerPort: 80
            protocol: TCP
          resources:
            limits:
              cpu: '500m'
              memory: '512Mi'
            requests:
              cpu: '500m'
              memory: '512Mi'
          livenessProbe:
            tcpSocket:
              port: 5000
            initialDelaySeconds: 10
            timeoutSeconds: 2
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          readinessProbe:
            tcpSocket:
              port: 5000
            initialDelaySeconds: 10
            timeoutSeconds: 2
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
        dnsPolicy: ClusterFirst
        restartPolicy: Always
        schedulerName: default-scheduler
        securityContext: {}
        terminationGracePeriodSeconds: 30
        serviceAccountName: acme-controller
    test: false
    triggers:
    - type: ImageChange
      imageChangeParams:
        automatic: true
        containerNames:
        - acme-controller
        from:
          kind: ImageStreamTag
          name: acme-controller:latest
    - type: ConfigChange
- apiVersion: v1
  kind: Service
  metadata:
    name: acme-controller
  spec:
    ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: 5000
    selector:
      app: acme-controller

refactor assistance

Hi,
Firstly thanks for the great project its really cool to see acme in Openshift! Secondly I see you are in the middle of a rewrite of the code, some of the features (retry limiting, global account etc.....) are things that would be really useful to us, so I'd like to offer my help in the refactoring process.-However I don't see a clear outline of how to help with the refactoring on here to just jump in, so 1) are you open to some help? 2) if so what can I help with? :)

Can't Renew Certificates

I have an issue when certificate renew runs, the route created for well-known challenge doesn't work if the main route allow insecure traffic or redirects insecure traffic, in that case, the well-known route is ignored and all traffic goes to the main route. I think this is an issue with openshift, but, we can do something to workaround this?

I am using openshift 1.5.0

Unable to bootstrap certificate database

I ran the following:

oc create -f https://github.com/tnozicka/openshift-acme/raw/master/deploy/{clusterrole,deploymentconfig-letsencrypt-live,service}.yaml and

oc adm policy add-cluster-role-to-user acme-controller system:serviceaccount:acme:default

But the acme-controller pod failed to start. There was the following error:


2017-10-05T01:59:27.724869956Z   INFO Starting controller
--
  | 2017-10-05T01:59:27.725009808Z   INFO ACME server url is 'https://acme-v01.api.letsencrypt.org/directory'
  | ERROR: logging before flag.Parse: W1005 01:59:27.725056       1 client_config.go:481] Neither --kubeconfig nor --master was specified.  Using the inClusterConfig.  This might not work.
  | 2017-10-05T01:59:27.726332163Z   INFO AcmeController bootstraping DB
  | 2017-10-05T01:59:28.049386505Z  ERROR cmd.go:138 Unable to bootstrap certificate database: 'User "system:serviceaccount:openshift:default" cannot list all secrets in the cluster'
  | 2017-10-05T01:59:27.726351984Z  TRACE AcmeController bootstraping DB finished duration=323.078223ms start=2017-10-05T01:59:27.726352023Z end=2017-10-05T01:59:28.049430246Z
  | 2017-10-05T01:59:28.049462636Z   INFO AcmeController initializing
  | 2017-10-05T01:59:28.049484161Z   INFO AcmeController started
  | 2017-10-05T01:59:28.049560988Z   INFO Http-01: server listening on http://[::]:5000/
  | 2017-10-05T01:59:28.125209899Z  ERROR cmd.go:173 Couln't initialize RouteController: 'RouteController could not find its own service: 'User "system:serviceaccount:openshift:default" cannot get services in project "openshift"''
  | 2017-10-05T01:59:28.125253155Z   INFO AcmeController - retryLoop - finished
  | 2017-10-05T01:59:28.125255259Z   INFO Http-01: stopping server listening on http://[::]:5000/
  | 2017-10-05T01:59:28.125267349Z   INFO AcmeController - renewLoop - finished
  | 2017-10-05T01:59:27.724868444Z  TRACE Controller finished duration=400.407081ms start=2017-10-05T01:59:27.724868605Z end=2017-10-05T01:59:28.125275686Z
  | Error: RouteController could not find its own service: 'User "system:serviceaccount:openshift:default" cannot get services in project "openshift"'

I then triedoc adm policy add-cluster-role-to-user cluster-admin system:serviceaccount:acme:default but again got the same error as above.

Any help is greatly appreciated.

Deployment Updates

As we're slowly moving APPUiO to the openshift-acme controller we've built an automated deployment process. It's based on Ansible and can be found here: https://github.com/appuio/ansible-role-openshift-acme. We're also currently building our own Docker image as it seems that the used S2I builder is not maintained: https://github.com/appuio/openshift-acme-docker and https://hub.docker.com/r/appuio/openshift-acme/.

If you want you can link it in the README and probably remove the files under deploy/. The linked Ansible role contains a proper OpenShift template: https://github.com/appuio/ansible-role-openshift-acme/blob/master/files/acme-controller-template.yml. This can also be used standalone without the Ansible role.

Fake LE Intermediate X1 root authority

Hi,
This is a really cool project, thank you! I am missing something really basic with the LE account and API key. I have run the live deployment but all me certificates are being issued on the Fake LE Intermediate X1 authority. I think this is because my account and key are not being used?

Is there a way of providing these details to the pod or am I doing something else wrong?

Thanks!
Ray

challenge-service get created with invalid name when route name contains .

Hi,

I just updated from an old version and noticed, that routes with . in their name are not supported anymore. Is that expected?

Error syncing Route my_namespace/a.route.com: failed to accept ACME authorization: failed to create exposing Service /a.route.com-acme-r75ks: Service "a.route.com-acme-r75ks" is invalid: metadata.name: Invalid value: "a.route.com-acme-r75ks": a DNS-1035 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name',  or 'abc-123', regex used for validation is '[a-z]([-a-z0-9]*[a-z0-9])?')

failed to accept ACME authorization

Hello

I recently re-installed the openshift-acme controller.

Some routes were successfully secured, however others were not.

There error I see in the controller log is:

failed to accept ACME authorization: failed to create watcher for Route myproject/myapp: the server rejected our request for an unknown reason (get routes.route.openshift.io)

Does anyone know how to further debug or understand this?

failed to unmarshal Route: 'json: cannot unmarshal number into Go value of type string'

I keep getting the following error.

2017-07-27T20:53:25.651168581Z  ERROR route.go:192 RouteController: doWatchIteration failed: RouteController: failed to unmarshal Route: 'json: cannot unmarshal number into Go value of type string'
--

This is on openshift v1.5.1 . I used the exact steps from this repo. Is this some compatibility with the api version that was used when building this go code vs the version of the api in openshift?

Global ACME account

The current implementation - as far as I understand - creates an ACME account per project. When having many projects this could lead into rate-limit issues. Would it be possible to have one cluster-level ACME account for all projects?

Error getting validation data

Hello

I am now getting an error when I try to setup an SSL cert. The log is:

2017-10-04T20:03:13.399307059Z   INFO Starting controller
2017-10-04T20:03:13.400773589Z   INFO ACME server url is 'https://acme-v01.api.letsencrypt.org/directory'
ERROR: logging before flag.Parse: W1004 20:03:13.400870       1 client_config.go:481] Neither --kubeconfig nor --master was specified.  Using the inClusterConfig.  This might not work.
2017-10-04T20:03:13.402338598Z   INFO AcmeController bootstraping DB
2017-10-04T20:03:13.402373824Z  TRACE AcmeController bootstraping DB finished duration=1.899276981s start=2017-10-04T20:03:13.402373990Z end=2017-10-04T20:03:15.301650971Z
2017-10-04T20:03:15.301698361Z   INFO AcmeController initializing
2017-10-04T20:03:15.301713447Z   INFO AcmeController started
2017-10-04T20:03:15.301826960Z   INFO Http-01: server listening on http://[::]:5000/
2017-10-04T20:03:15.316153418Z   INFO RouteController initializing
2017-10-04T20:03:15.316190141Z   INFO RouteController started
2017-10-04T20:03:15.316206584Z   INFO RouteController: watching namespace ''
2017-10-04T20:03:15.398653884Z   INFO Obtaining certificate start
2017-10-04T20:03:15.398696164Z   INFO Obtaining certificate
2017-10-04T20:03:27.523900313Z  ERROR client.go:161 Authorization failed: acme: authorization error for mydomain.mycompany.com: 400 urn:acme:error:connection: Fetching https://mydomain.mycompany.com/.well-known/acme-challenge/S8Gf_b4iA4LBHfXHKXyFaaCsZmxdFzY9CI9In-XaO7k: Error getting validation data
2017-10-04T20:03:27.523966509Z   INFO finished validating domains
2017-10-04T20:03:15.398715077Z  TRACE acme.Client ObtainCertificate duration=12.125264569s start=2017-10-04T20:03:15.398715235Z end=2017-10-04T20:03:27.523979804Z
2017-10-04T20:03:27.524076167Z  ERROR dbcertentry.go:79 [domain: mydomain.mycompany.com, error: acme: authorization error for mydomain.mycompany.com: 400 urn:acme:error:connection: Fetching https://mydomain.mycompany.com/.well-known/acme-challenge/S8Gf_b4iA4LBHfXHKXyFaaCsZmxdFzY9CI9In-XaO7k: Error getting validation data]

Can anyone advise on what might be causing this error?

Thanks

Domain validation doesn't work with insecureEdgeTerminationPolicy: Redirect

When my route had "insecureEdgeTerminationPolicy: Redirect" defined the controller was unable to validate the domain because the router tries to redirect when the .well-known challenge URL is requested. After I removed "insecureEdgeTerminationPolicy: Redirect" from the route definition the challenge URL responded correctly and the certificate was installed.

The server rejected our request due to an error in our request

Looks good but I'm not having much luck getting my certs generated. My doamin [substituted below] is publicly accessible via HTTP only and HTTP with default cert but the openshift-acme request is always rejected. Thoughts?

2017-06-06T21:21:52.326634766Z   INFO Starting controller
2017-06-06T21:21:52.326843725Z   INFO ACME server url is 'https://acme-staging.api.letsencrypt.org/directory'
2017-06-06T21:21:52.355212261Z  DEBUG cmd.go:132 namespaces: []string{""}
2017-06-06T21:21:52.355326627Z   INFO AcmeController bootstraping DB
2017-06-06T21:21:52.356061874Z  DEBUG acme.go:266 AcmeCotroller: Bootstraping namespace ''
2017-06-06T21:21:52.866800846Z  DEBUG certdb.go:234 Updating account 'mydomain/acme-account' (https://acme-staging.api.letsencrypt.org/acme/reg/2493400)
2017-06-06T21:21:53.814638343Z  DEBUG certdb.go:243 Loading certificates and authorizations for account 'mydomain/acme-account' (https://acme-staging.api.letsencrypt.org/acme/reg/2493400)
2017-06-06T21:21:52.356051586Z  TRACE AcmeController bootstraping DB finished duration=1.458644064s start=2017-06-06T21:21:52.356054022Z end=2017-06-06T21:21:53.814698086Z
2017-06-06T21:21:53.814726564Z   INFO AcmeController initializing
2017-06-06T21:21:53.814743066Z   INFO AcmeController started
2017-06-06T21:21:53.814989223Z   INFO Http-01: server listening on http://[::]:5000/
2017-06-06T21:21:53.984720524Z  DEBUG route.go:259 Detected subsets for selfService: '[{Addresses:[{IP:172.30.113.234 Hostname: NodeName:<nil> TargetRef:nil}] NotReadyAddresses:[] Ports:[{Name: Port:80 Protocol:}]}]'
2017-06-06T21:21:53.984848902Z   INFO RouteController initializing
2017-06-06T21:21:53.984879387Z   INFO RouteController started
2017-06-06T21:21:53.984922918Z   INFO RouteController: watching namespace ''
2017-06-06T21:21:54.027052247Z  DEBUG route.go:124 Type: ADDED
2017-06-06T21:21:54.027128445Z  DEBUG route.go:147 RouteController: processing route 'mydomain.com'
2017-06-06T21:21:54.148218090Z  DEBUG dbcertentry.go:129 Adding object
2017-06-06T21:21:54.148306077Z  DEBUG dbcertentry.go:138 AddObject starting new certificate request
2017-06-06T21:21:54.148460040Z   INFO Obtaining certificate start
2017-06-06T21:21:54.148486248Z   INFO Obtaining certificate
2017-06-06T21:21:54.481939754Z  DEBUG client.go:80 Authorization: &{URI:https://acme-staging.api.letsencrypt.org/acme/authz/FA71cRDOT8p9rvcAv-qInHT8611L0ic2NSnZzGJ2Dz4 Status:pending Identifier:{Type:dns Value:mydomain.com} Challenges:[0xc4203f9340 0xc4203f9380 0xc4203f93c0] Combinations:[[0] [2] [1]]}
2017-06-06T21:21:54.482119977Z  DEBUG route.go:197 Creating Route mydomain/acme-e0k7aupjh7 for exposing (1/10)
2017-06-06T21:21:54.482568928Z  DEBUG route.go:60 Creating Endpoints mydomain/acme-e0k7aupjh7 for exposing (1/10)
2017-06-06T21:21:54.482871406Z  DEBUG route.go:127 Creating Service mydomain/acme-e0k7aupjh7 for exposing (1/10)
2017-06-06T21:21:54.887303319Z  ERROR route.go:225 route challenge exposer: creating route acme-e0k7aupjh7/mydomain failed: the server rejected our request due to an error in our request
2017-06-06T21:22:06.088081132Z  ERROR client.go:161 Authorization failed: acme: identifier authorization failed
2017-06-06T21:22:06.088581180Z   INFO finished validating domains
2017-06-06T21:21:54.148526340Z  TRACE acme.Client ObtainCertificate duration=11.940091015s start=2017-06-06T21:21:54.148526869Z end=2017-06-06T21:22:06.088617884Z
2017-06-06T21:22:06.088819056Z  ERROR dbcertentry.go:79 [domain: mydomain.com, error: acme: identifier authorization failed]
2017-06-06T21:22:06.133780973Z  ERROR route.go:303 route challenge exposer: deleting route 'mydomain/acme-e0k7aupjh7': the server could not find the requested resource; "{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"routes.route.openshift.io \\\"acme-e0k7aupjh7\\\" not found\",\"reason\":\"NotFound\",\"details\":{\"name\":\"acme-e0k7aupjh7\",\"group\":\"route.openshift.io\",\"kind\":\"routes\"},\"code\":404}\n"

Support DNS validation method

Hi,

I have an openshift deployment where the routes are not internet accessible, so I need to use dns to do domain verification instead.

Does openshift-acme support the dns method? I saw some passing references, but I have no idea how to actually configure it.

I'd be using Route 53 in the first case.

Thanks

Random Segfaults

At the moment, our acme-controller pod is in a crash loop due to:

/opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:72
/opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:65
/opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:51
/usr/local/go/src/runtime/asm_amd64.s:573
/usr/local/go/src/runtime/panic.go:505
/usr/local/go/src/runtime/panic.go:63
/usr/local/go/src/runtime/signal_unix.go:388
/opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/acme/client/client.go:130
/opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:573
/opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:742
/opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:749
/opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:770
/opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:133
/opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:134
/opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88
/usr/local/go/src/runtime/asm_amd64.s:2361
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0xe9796d]

goroutine 103 [running]:
github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/runtime.HandleCrash(0x0, 0x0, 0x0)
    /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:58 +0x107
panic(0xfc9c80, 0x18e9260)
    /usr/local/go/src/runtime/panic.go:505 +0x229
github.com/tnozicka/openshift-acme/pkg/acme/client.GetAuthorizationErrors(0xc4239eccb0, 0x7, 0x1103a77)
    /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/acme/client/client.go:130 +0xed
github.com/tnozicka/openshift-acme/pkg/controllers/route.(*RouteController).handle(0xc4200e6000, 0xc421d0f680, 0x25, 0x0, 0x0)
    /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:573 +0x25ff
github.com/tnozicka/openshift-acme/pkg/controllers/route.(*RouteController).processNextItem(0xc4200e6000, 0xc4200c6600)
    /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:742 +0xde
github.com/tnozicka/openshift-acme/pkg/controllers/route.(*RouteController).runWorker(0xc4200e6000)
    /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:749 +0x2b
github.com/tnozicka/openshift-acme/pkg/controllers/route.(*RouteController).(github.com/tnozicka/openshift-acme/pkg/controllers/route.runWorker)-fm()
    /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:770 +0x2a
github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1(0xc421d53000)
    /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:133 +0x54
github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil(0xc421d53000, 0x3b9aca00, 0x0, 0x1, 0xc42056e240)
    /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:134 +0xbd
github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait.Until(0xc421d53000, 0x3b9aca00, 0xc42056e240)
    /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88 +0x4d
created by github.com/tnozicka/openshift-acme/pkg/controllers/route.(*RouteController).Run
    /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:770 +0x1b3

I am unsure which route exactly triggers this error, we have 469 routes on our Cluster :-( I try to narrow down which route causes the issue ASAP.

Any Idea during what step the segfault actually happens?

Authorization status "invalid" leads to routes being paused indefinitely

The RouteController.handle function sets a kubernetes.io/tls-acme-paused annotation if the API returned a status of invalid:

case acme.StatusInvalid:
rc.recorder.Eventf(routeReadOnly, corev1.EventTypeWarning, "AcmeFailedAuthorization", "Acme provider failed to validate domain %q: %s", routeReadOnly.Spec.Host, acmeclient.GetAuthorizationErrors(authorization))
route := routeReadOnly.DeepCopy()
delete(route.Annotations, api.AcmeAwaitingAuthzUrlAnnotation)
// TODO: remove force pausing when we have ACME rate limiter
route.Annotations[api.TlsAcmePausedAnnotation] = "true"
route, err = rc.routeClientset.RouteV1().Routes(route.Namespace).Update(route)
if err != nil {
return fmt.Errorf("failed to pause Route: %v", err)
}

Once that annotation is set the route is skipped indefinitely. There is no code removing the annotation. Instead a manual intervention is necessary.

One would expect that such routes are retried after a reasonable timeframe, i.e. a day.

how to trigger renew manually

Project works great - adds LE certificates to all tagged routes.

I'd like to trigger a renew manually somehow so I don't have to wait 3 months to see if this works.

I looked at the code and saw that it uses the certificate date which I likely can't backdate to test renewals.

Any way to "fake" trigger a renewal for testing?

Crash

I0316 07:52:04.886094 1 route.go:483] Route "develop/origin": authorization state is "pending"
I0316 07:52:04.886148 1 client.go:83] Found 2 possible combinations for authorization
I0316 07:52:04.886157 1 client.go:90] Found 1 valid combinations for authorization
I0316 07:52:05.028449 1 exposer.go:283] Waiting for exposing route develop/origin-acme-sh4hx to be admitted.
I0316 07:52:05.071428 1 route.go:387] Finished syncing Route "develop/origin" (410.782748ms)
E0316 07:52:05.071889 1 runtime.go:66] Observed a panic: "invalid memory address or nil pointer dereference" (runtime error: invalid memory address or nil pointer dereference) /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:72 /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:65 /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:51 /usr/local/go/src/runtime/asm_amd64.s:573 /usr/local/go/src/runtime/panic.go:505 /usr/local/go/src/runtime/panic.go:63 /usr/local/go/src/runtime/signal_unix.go:388 /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/watch/until.go:41 /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/exposer.go:288 /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/acme/client/client.go:104 /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:489 /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:742 /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:749 /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:770 /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:133 /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:134 /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88 /usr/local/go/src/runtime/asm_amd64.s:2361 panic: runtime error: invalid memory address or nil pointer dereference [recovered] panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x827fc1] goroutine 83 [running]: github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/runtime.HandleCrash(0x0, 0x0, 0x0) /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:58 +0x107 panic(0xfc8c80, 0x18e8260) /usr/local/go/src/runtime/panic.go:505 +0x229 github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/watch.Until(0x6fc23ac00, 0x0, 0x0, 0xc42137b1c0, 0x1, 0x1, 0x0, 0x0, 0x0) /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/watch/until.go:41 +0x51 github.com/tnozicka/openshift-acme/pkg/controllers/route.(*Exposer).Expose(0xc42051dc80, 0xc4200d8dc0, 0xc42037ae00, 0x12, 0xc4210b6cc0, 0x2b, 0x1210b00, 0xc42051a240) /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/exposer.go:288 +0x18f6 github.com/tnozicka/openshift-acme/pkg/acme/client.(*Client).AcceptAuthorization(0xc4203f4c00, 0x1211f00, 0xc42009a6c0, 0xc42105d500, 0xc42037ae00, 0x12, 0xc4211b5920, 0x0, 0xf, 0x54426c5446465754) /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/acme/client/client.go:104 +0x2ae github.com/tnozicka/openshift-acme/pkg/controllers/route.(*RouteController).handle(0xc4204c60f0, 0xc42042a100, 0xe, 0x0, 0x0) /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:489 +0x21d0 github.com/tnozicka/openshift-acme/pkg/controllers/route.(*RouteController).processNextItem(0xc4204c60f0, 0xc420080400) /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:742 +0xde github.com/tnozicka/openshift-acme/pkg/controllers/route.(*RouteController).runWorker(0xc4204c60f0) /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:749 +0x2b github.com/tnozicka/openshift-acme/pkg/controllers/route.(*RouteController).(github.com/tnozicka/openshift-acme/pkg/controllers/route.runWorker)-fm() /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:770 +0x2a github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1(0xc420014090) /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:133 +0x54 github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil(0xc420014090, 0x3b9aca00, 0x0, 0x4d4a706d54336c01, 0xc4200aa240) /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:134 +0xbd github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait.Until(0xc420014090, 0x3b9aca00, 0xc4200aa240) /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88 +0x4d created by github.com/tnozicka/openshift-acme/pkg/controllers/route.(*RouteController).Run /opt/app-root/src/go/src/github.com/tnozicka/openshift-acme/pkg/controllers/route/route.go:770 +0x1b3

Annotate route with error

It'll be helpful to have the annotations added on the error status.

eg when a cert is added we get.

    kubernetes.io/tls-acme.last-update-time: '2017-06-16T05:51:36Z'

If a renew fails or we can't authorise the domain, it would be nice to have a log of the error in the annotation so a user who doesn't have access to openshift-acme logs can at least see what could be wrong.

Error: "exposer-ip" can't be empty string

Hello

I have been using openshift-acme for several months without issues.

Today however, I started getting the following error:


I0625 03:53:03.773719       1 cmd.go:147] ACME server url is "https://acme-v01.api.letsencrypt.org/directory"
--
  | I0625 03:53:03.774132       1 cmd.go:154] ACME server loglevel == 8
  | I0625 03:53:03.774144       1 cmd.go:119] No kubeconfig specified, using InClusterConfig.
  | I0625 03:53:03.775687       1 cmd.go:170] Watching all namespaces.
  | I0625 03:53:03.775724       1 cmd.go:190] "selfnamespace" is unspecified, trying inCluster
  | Error: "exposer-ip" can't be empty string


Do you have any ideas as to what might cause this?

Thanks

During the controller bootup the oldest certificate is being stored

When the acme-controller starts a renew loop it's loading an old expired cert back into the current route:

2017-08-12T01:41:20.174649501Z  DEBUG acme.go:148 renewLoop: renewing certificate for: '[www.example.com]'
--
  | 2017-08-12T01:41:20.174685892Z  DEBUG acme.go:146 notBefore=2017-07-25 03:06:00 +0000 UTC, notAfter=2017-10-23 03:06:00 +0000 UTC, renewTime=2017-09-23 03:06:00 +0000 UTC; renew=false
  | 2017-08-12T01:41:20.174710376Z  DEBUG acme.go:146 notBefore=2017-07-26 15:51:00 +0000 UTC, notAfter=2017-10-24 15:51:00 +0000 UTC, renewTime=2017-09-24 15:51:00 +0000 UTC; renew=false

Here it has an already valid cert and renew=false however it still goes and runs a renew request. While it's trying to renew, it loaded up the cert from the previous 3 month cycle (ie. expired on 2017-07-25)

This means for about 3-4 minutes routes are getting an invalid cert NET::ERR_CERT_DATE_INVALID

No certs generated for Route

Steps to recteate:

oc new-project acme
oc create -fhttps://github.com/tnozicka/openshift-acme/raw/master/deploy/{clusterrole,deploymentconfig-letsencrypt-staging,service}.yaml
oc adm policy add-cluster-role-to-user acme-controller system:serviceaccount:acme:default

In another namespace annotate a Route:

oc get route nexus -o yaml -n fabric8-system
apiVersion: v1
kind: Route
metadata:
  annotations:
    fabric8.io/app-menu: development
    fabric8.io/iconUrl: https://cdn.rawgit.com/fabric8io/fabric8-devops/master/nexus/src/main/fabric8/icon.png
    kubernetes.io/tls-acme: "true"
    openshift.io/host.generated: "true"
  labels:
    expose: "true"
    generator: exposecontroller
    group: io.fabric8.devops.apps
    project: nexus
    provider: fabric8
    version: 2.2.334
  name: nexus
  namespace: fabric8-system
spec:
  host: nexus-fabric8-system.badger.fabric8.io
  port:
    targetPort: 8081
  to:
    kind: Service
    name: nexus
    weight: 100
  wildcardPolicy: None

Logs:

2017-07-10T13:23:07.812224261Z   INFO Starting controller
2017-07-10T13:23:07.812350715Z   INFO ACME server url is 'https://acme-staging.api.letsencrypt.org/directory'
2017-07-10T13:23:07.815694337Z   INFO AcmeController bootstraping DB
2017-07-10T13:23:07.815712498Z  TRACE AcmeController bootstraping DB finished duration=198.653899ms start=2017-07-10T13:23:07.815712541Z end=2017-07-10T13:23:08.014366440Z
2017-07-10T13:23:08.014431143Z   INFO AcmeController initializing
2017-07-10T13:23:08.014460717Z   INFO AcmeController started
2017-07-10T13:23:08.014952228Z   INFO Http-01: server listening on http://[::]:5000/
2017-07-10T13:23:08.021386111Z   INFO RouteController initializing
2017-07-10T13:23:08.021426488Z   INFO RouteController started
2017-07-10T13:23:08.021437254Z   INFO RouteController: watching namespace ''
2017-07-10T13:23:08.028369836Z  ERROR route.go:115 json: cannot unmarshal number into Go value of type string
2017-07-10T13:23:08.028487244Z  ERROR route.go:192 RouteController: doWatchIteration failed: RouteController: failed to unmarshal Route: 'json: cannot unmarshal number into Go value of type string'
2017-07-10T13:23:18.034619220Z   WARN route.go:98 RouteController: resetting resourceVersion: caused by 'ERROR' (unversioned.Status{TypeMeta:unversioned.TypeMeta{Kind:"Status", APIVersion:"v1"}, ListMeta:unversioned.ListMeta{SelfLink:"", ResourceVersion:""}, Status:"Failure", Message:"too old resource version: 14859814 (14885952)", Reason:"Gone", Details:(*unversioned.StatusDetails)(nil), Code:410})
2017-07-10T13:23:18.034654432Z  ERROR route.go:192 RouteController: doWatchIteration failed: RouteController ResultChannel closed
2017-07-10T13:23:28.040839440Z  ERROR route.go:115 json: cannot unmarshal number into Go value of type string
2017-07-10T13:23:28.040918637Z  ERROR route.go:192 RouteController: doWatchIteration failed: RouteController: failed to unmarshal Route: 'json: cannot unmarshal number into Go value of type string'
2017-07-10T13:23:38.050380178Z  ERROR route.go:115 json: cannot unmarshal number into Go value of type string
2017-07-10T13:23:38.050470174Z  ERROR route.go:192 RouteController: doWatchIteration failed: RouteController: failed to unmarshal Route: 'json: cannot unmarshal number into Go value of type string'
oc v1.5.1+7b451fc
kubernetes v1.5.2+43a9be4
features: Basic-Auth

Server 
openshift v1.5.1
kubernetes v1.5.2+43a9be4

Prometheus Endpoint

Hi, would you have any interest in a prometheus endpoint being added to openshift-acme app where we can count the number of fails for getting certs (rate limits etc....), which would allow for better monitoring?
I saw that basically you just parse the errors in one place pkg/acme/client/client.go func GetAuthorizationErrors so it seems like we could target something around that function, maybe a general error counter and then specific switches for the type of error that increments individual counters.
If you have a better idea of where to implement it or you don't want this please shout, otherwise i will get started on it.

Image versioning?

Would it be possible to publish official releases of this project (applying to code and also to the docker image at https://hub.docker.com/r/tnozicka/openshift-acme), so that I can deploy your project without worrying about incompatible changes to environment variables, cluster roles etc?

I ask because I deployed your project many times in the past 8 months without any problems (after patching the openshift router to support updating the let's encrypt certificate when the route is secured with redirect insecure edge termination policy); on my latest deployment the acme controller fails to boot because of missing OPENSHIFT_ACME_EXPOSER_IP environment variable. I checked and since the cluster role has also changed I now have to retest my deployment to be compatible with the new image.

Being issued Fake LE Intermediate X1 certificate?

Hi,

Something is amiss with openshift-acme for me, it appears to be working ok:

2017-10-21T11:55:47.982801573Z   INFO Obtaining certificate start
2017-10-21T11:55:47.982930239Z   INFO Obtaining certificate
2017-10-21T11:56:01.667609458Z   INFO finished validating domains
2017-10-21T11:55:47.982979048Z  TRACE acme.Client ObtainCertificate duration=16.278289918s start=2017-10-21T11:55:47.982979460Z end=2017-10-21T11:56:04.261269378Z
2017-10-21T11:56:04.270296477Z   INFO Creating new secret 'acme.test' in namespace '' for route 'test'
2017-10-21T11:56:04.283463058Z   INFO Updating route 'test' in namespace 'jenkins'
2017-10-21T11:56:04.302450819Z   INFO Route 'test' in namespace 'jenkins' UPDATED.

You can see from the certificate that something is dodgy.
image

Apparently, that means I'm using staging settings somehow?
https://community.letsencrypt.org/t/certbot-always-issues-bad-certificate-with-fake-le-intermediate-x1/36600

json: cannot unmarshal number into Go value of type string

The controller works as expected, but I'm getting the following message every 10 seconds:

2017-05-27T12:44:55.714179762Z  ERROR route.go:115 json: cannot unmarshal number into Go value of type string
2017-05-27T12:44:55.714291924Z  ERROR route.go:192 RouteController: doWatchIteration failed: RouteController: failed to unmarshal Route: 'json: cannot unmarshal number into Go value of type string'
  • OpenShift version: v3.6.0-alpha.1
  • Controller commit: ea5433a

Scale / failover with multiple replica's

This is a great project. Thanks for developing this and making it opensource. I'm running it on a new Openshift cluster and it works great.

A question, is it possible to run more openshift-acme pods? We're running multiple nodes on different servers (geo separated) and failover is interesting here.

E-Mail for account creation

When creating an account for Let's Encrypt you normally pass an E-Mail address which then f.e. gets notifications when a certificate hasn't been renewed. How is this done in openshift-acme? What E-Mail address is used and would I be able to chose which one? A short look into the code didn't reveal aynthing.

Unauthorized error obtaining certificate

I am receiving the following error when trying to get a cert.

2017-04-29T06:16:31.221098755Z   INFO Starting controller
2017-04-29T06:16:31.221240059Z   INFO ACME server url is 'https://acme-v01.api.letsencrypt.org/directory'
2017-04-29T06:16:31.225572058Z   INFO AcmeController bootstraping DB
2017-04-29T06:16:31.225610060Z  TRACE AcmeController bootstraping DB finished duration=833.136957ms start=2017-04-29T06:16:31.225610265Z end=2017-04-29T06:16:32.058747222Z
2017-04-29T06:16:32.058838319Z   INFO AcmeController initializing
2017-04-29T06:16:32.058981681Z   INFO AcmeController started
2017-04-29T06:16:32.059752714Z   INFO Http-01: server listening on http://[::]:5000/
2017-04-29T06:16:32.063979333Z   INFO RouteController initializing
2017-04-29T06:16:32.064020514Z   INFO RouteController started
2017-04-29T06:16:32.064052366Z   INFO RouteController: watching namespace ''
2017-04-29T06:16:32.078055173Z   INFO Obtaining certificate start
2017-04-29T06:16:32.078139507Z   INFO Obtaining certificate
2017-04-29T06:16:32.506245476Z   INFO finished validating domains
2017-04-29T06:16:32.078163956Z  TRACE acme.Client ObtainCertificate duration=428.277981ms start=2017-04-29T06:16:32.078164184Z end=2017-04-29T06:16:32.506442165Z
2017-04-29T06:16:32.506626700Z  ERROR dbcertentry.go:79 [domain: sonarqube-ci.apps.DOMAIN.IO, error: 403 urn:acme:error:unauthorized: No registration exists matching provided key]

Im guessing that I have to create an account with letsencrypt using something like (https://github.com/lukas2511/dehydrated)[https://github.com/lukas2511/dehydrated]?

If so where would I mount the secret or pass it in as en env variable?

Or am I completely off the mark 😄

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.