cloudfoundry / korifi

Cloud Foundry on Kubernetes
Apache License 2.0
318 stars 64 forks source link

[Feature]: Platform operator can configure Korifi components to trust a self-signed/internal CA when interacting with the container registry #1192

Closed tcdowney closed 2 years ago

tcdowney commented 2 years ago

Blockers/Dependencies

No response

Background

Self-hosted container registries may use self-signed certificates or certs that were issued by an internal CA for various reasons (dev envs, air-gapped envs, compliance, etc.). Some of the Korifi components talk directly to the container registry (korifi-api does during package upload and kpack-image-builder does to fetch image metadata) and need to be able to trust these internal registries.

As a Platform Operator I want to be able to configure Korifi with a secret containing a CA to trust for registry interactions So that the Korifi components (korifi-api, kpack-image-builder) can interact with an internal registry


Acceptance Criteria

I think we should draw inspiration from how Knative and Cartographer Convention Controller support this:

I think both of these approaches take a Secret and mount it at either a well-known path or provide the path via an env var to the codebase. We should make this Secret optional and operators should be able to use the certs in their regular trust store by default.

GIVEN I have deployed an internal registry that is using a cert signed by an internal CA AND I have configured a Secret with the additional CAs I want to trust WHEN I update the korifi-api and kpack-image-builder Deployments with that secret volume mounted at some path THEN I see that I am able to cf push --no-start an app AND somehow test that the kpack reconciler can read metadata (we may need to use the cert-injection-webhook to get kpack to trust the registry -- if we do this then we can use a regular cf push)


Dev Notes

akrishna90 commented 2 years ago

We spent sometime over getting the dockerregistry to deploy locally and serve over tls, unfortunately the changes we were passing to helm weren't working like we expected. We instead switched plans and decided to deploy dockerregistry to a gke cluster, and configure korifi (deployed on local kind) to use it as container registry

Installation instruction for setting up docker-registry with tls on gke

openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem


- Generate server certs
    - create a `san.cnf` file with contents as below (make sure you update the DNS and CN values)
  [ req ]
  default_bits       = 2048
  distinguished_name = req_distinguished_name
  req_extensions     = req_ext
  prompt = no
  [ req_distinguished_name ]
  countryName                 = US
  stateOrProvinceName         = california
  localityName               = sf
  organizationName           = cf
  commonName                 = docker.beatable-spacesuit.k8s-dev.relint.rocks
  [ req_ext ]
  subjectAltName = @alt_names
  [alt_names]
  DNS.1   = docker.beatable-spacesuit.k8s-dev.relint.rocks
```
- create the CSR
```
openssl req -out sslcert.csr -newkey rsa:2048 -nodes -keyout private.key -config san.cnf
```
- create a `v3.ext` file (we couldn't get the SAN on the server cert, a googling lead us to using this approach. Maybe there is a better way of doing this) - plz update the `subjectAltName` value
```
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always,issuer:always
basicConstraints       = CA:TRUE
keyUsage               = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign
subjectAltName         = DNS:docker.beatable-spacesuit.k8s-dev.relint.rocks
```
- create the server cert
```
 openssl x509 -req -days 365000 -set_serial 01    -in sslcert.csr    -out server-cert.pem    -CA ca-cert.pem    -CAkey ca-key.pem -extfile v3.ext
```
kubectl create secret tls dockerregistry-tls   --cert=server-cert.pem   --key=private.key
ingress:
  annotations:
    kubernetes.io/ingress.class: "gce"
  className: gce
  enabled: true
  hosts:
    - docker.beatable-spacesuit.k8s-dev.relint.rocks
  tls:
  - hosts:
    - docker.beatable-spacesuit.k8s-dev.relint.rocks
    secretName: dockerregistry-tls