helm-charts icon indicating copy to clipboard operation
helm-charts copied to clipboard

Setting port via ca.address variable for ACME provisioner deployed on K8s

Open mbag opened this issue 6 years ago • 10 comments

I'm using step-certificates chart to deploy Smallstep CA to k8s and use it to issue certificates using ACME protocol. Once deployed, I can find ACME directory listing at the address: https://ca.example.com/acme/acme/directory and the ACME endpoints there look like this:

{
  "newNonce": "https://ca.example.com:9000/acme/acme/new-nonce",
  "newAccount": "https://ca.example.com:9000/acme/acme/new-account",
  "newOrder": "https://ca.example.com:9000/acme/acme/new-order",
  "revokeCert": "https://ca.example.com:9000/acme/acme/revoke-cert",
  "keyChange": "https://ca.example.com:9000/acme/acme/key-change"
}

As you can see the URLs have the port number :9000. This causes a connection problem, since clients can't access this service at port ca.example.com:9000 on k8s Ingress. Chart sets ingress to point to 443 port of the smallstep Service object, and Service is set to map 443 to 9000 (https://github.com/smallstep/helm-charts/blob/master/step-certificates/values.yaml#L25-L28)

I have tried changing ca.address (https://github.com/smallstep/helm-charts/blob/master/step-certificates/values.yaml#L35) to :443, but with this value Pod creation fails, since it is unable to bind to port 443 because step user doesn't have permission to bind to ports less than 1024. Solution would be to add CAP_NET_BIND_SERVICE but I would like to avoid that.

Is there an option in Chart to control how ACME directory endpoints/links are constructed?

My ca.json looks like this:

   "root": "/home/step/certs/root_ca.crt",
   "federatedRoots": [],
   "crt": "/home/step/certs/intermediate_ca.crt",
   "key": "/home/step/secrets/intermediate_ca_key",
   "address": ":9000",
   "dnsNames": [
      "ca.example.com"
   ],
   "logger": {
      "format": "text"
   },
   "db": {
      "type": "badger",
      "dataSource": "/home/step/db"
   },
   "authority": {
      "provisioners": [
         {
            "type": "jwk",
            "name": "admin",
            "key": {
                "deliberatly": "removed"
            },
            "encryptedKey": "secret"
         },
         {  
            "type": "ACME",
            "name": "acme"
         }
      ]
   },
   "tls": {
      "cipherSuites": [
         "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
         "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
      ],
      "minVersion": 1.2,
      "maxVersion": 1.2,
      "renegotiation": false
   }     
}

mbag avatar Nov 11 '19 15:11 mbag

Just a guess, but would overriding ca.url work?

kfox1111 avatar Dec 14 '19 01:12 kfox1111

Same problem here.

hostops avatar Apr 03 '20 09:04 hostops

Overriding ca-url does not work. Temporary solution is to set runAsAdmin: true. Also it would be nice to enable provisioners - like ACME directly in chart.

hostops avatar Apr 03 '20 10:04 hostops

I have the same problem as well

viralpoetry avatar Apr 06 '20 10:04 viralpoetry

Has anyone tried changing ca.dns and/or ca.url in the helm values? The CA has two different settings to support this use case already: one specified where it listens, the other specifies the name & port clients connect to. They end up as address and dnsNames in ca.json, respectively. But maybe somethings not being passed through correctly in helm?

mmalone avatar Apr 07 '20 16:04 mmalone

@mmalone unfortunately, neither of those settings work as it is a problem of port. I think the problem is not related to a Helm chart itself but the fact that it's not possible to configure step-ca to serve another port in directory listing.

For example, docker container with step-ca is set to listen on :9000, but due to K8S ingress & service deployment this fact is hidden and we expect ACME clients to visit default 443 instead.

However REST API discovery will list ACME directory:

{
  "newNonce": "https://127.0.0.1:443:9000/acme/acme/new-nonce",
  "newAccount": "https://127.0.0.1:443:9000/acme/acme/new-account",
  "newOrder": "https://127.0.0.1:443:9000/acme/acme/new-order",
  "revokeCert": "https://127.0.0.1:443:9000/acme/acme/revoke-cert",
  "keyChange": "https://127.0.0.1:443:9000/acme/acme/key-change"
}

where all subsequent requests fail due to 9000 port used.
I didn't find the solution to this, maybe only patching step-ca source code will help with the current version.

Should I open issue on the code base?

viralpoetry avatar Apr 27 '20 12:04 viralpoetry

FYI, I have found the similar issue exist in certificates repo already:
https://github.com/smallstep/certificates/issues/193

viralpoetry avatar Apr 27 '20 12:04 viralpoetry

I've hit this issue as well. My current attempt at a workaround is to set the k8s Service being created to listen on :9000 instead of :443. My use case is using the step-ca cluster-internal to issue certificates for istio gateways (at least, that's my goal - still working on the complete setup). So the ACME URL is then step-certificates.security.svc.cluster.local:9000 (I've deployed the chart into the 'security' namespace in my k8s cluster).

What I've done is to render the helm chart out into a YAML locally and then tweak the Service definition manually and then using kubectl to apply it.

Not pretty, but at least now my ClusterIssuer for cert-manager is able to successfully register with the step-ca acme API.

A clean solution would definitely be to provide a way to better configure the URLs which step-ca uses in building the URLs used in building the acme directory response payload (e.g. override which port is used in those, or allowing a while-sale override of the host used therein).

clive-jevons avatar Apr 27 '20 15:04 clive-jevons

We can try to make the port configurable, but this PR from @clive-jevons will probably fix this https://github.com/smallstep/certificates/pull/236

maraino avatar Apr 28 '20 22:04 maraino

Another option is the way boulder does this, as explained here https://github.com/smallstep/certificates/issues/193#issuecomment-588454293

maraino avatar Apr 28 '20 22:04 maraino