From 3ccdb5e4c1efa97515a2de0ccaa6030552bf286d Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Wed, 17 Jan 2024 00:17:15 -0800 Subject: [PATCH] Add tls section to federation bundle endpoint and fix up annotations (#173) * Add cert-manager support to the federation bundle endpoint and fix up bundle endpoint ingress annotations Signed-off-by: Kevin Fox * Add external secret too Signed-off-by: Kevin Fox * Add forgotten files Signed-off-by: Kevin Fox * Apply suggestions from code review Signed-off-by: kfox1111 --------- Signed-off-by: Kevin Fox Signed-off-by: kfox1111 --- charts/spire/charts/spire-server/README.md | 12 ++++++ .../spire-server/templates/configmap.yaml | 13 +++++++ .../templates/federation-certificate.yaml | 27 +++++++++++++ .../templates/federation-ingress.yaml | 24 ++++++++++-- .../templates/federation-issuer.yaml | 22 +++++++++++ charts/spire/charts/spire-server/values.yaml | 39 +++++++++++++++++++ 6 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 charts/spire/charts/spire-server/templates/federation-certificate.yaml create mode 100644 charts/spire/charts/spire-server/templates/federation-issuer.yaml diff --git a/charts/spire/charts/spire-server/README.md b/charts/spire/charts/spire-server/README.md index a61bd43..4d02528 100644 --- a/charts/spire/charts/spire-server/README.md +++ b/charts/spire/charts/spire-server/README.md @@ -141,6 +141,18 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr | `federation.enabled` | Flag to enable federation | `false` | | `federation.bundleEndpoint.port` | Port value for trust bundle federation | `8443` | | `federation.bundleEndpoint.address` | Address for trust bundle federation | `0.0.0.0` | +| `federation.tls.spire.enabled` | Use spire to secure the federation bundle endpoint | `true` | +| `federation.tls.externalSecret.enabled` | Provide your own certificate/key via tls style Kubernetes Secret | `false` | +| `federation.tls.externalSecret.secretName` | Specify which Secret to use | `""` | +| `federation.tls.certManager.enabled` | Use certificateManager to create the certificate | `false` | +| `federation.tls.certManager.issuer.create` | Create an issuer to use to issue the certificate | `true` | +| `federation.tls.certManager.issuer.acme.email` | Must be set in order to register with LetsEncrypt. By setting, you agree to their Terms of Service | `""` | +| `federation.tls.certManager.issuer.acme.server` | Server to use to get certificate. Defaults to LetsEncrypt | `https://acme-v02.api.letsencrypt.org/directory` | +| `federation.tls.certManager.issuer.acme.solvers` | Configure the issuer solvers. Defaults to http01 via ingress. | `{}` | +| `federation.tls.certManager.certificate.dnsNames` | Override the dnsNames on the certificate request. Defaults to the same settings as Ingress | `[]` | +| `federation.tls.certManager.certificate.issuerRef.group` | If you are using an external plugin, specify the group for it here | `""` | +| `federation.tls.certManager.certificate.issuerRef.kind` | Kind of the issuer reference. Override if you want to use a ClusterIssuer | `Issuer` | +| `federation.tls.certManager.certificate.issuerRef.name` | Name of the issuer to use. If unset, it will use the name of the built in issuer | `""` | | `federation.ingress.enabled` | Flag to enable ingress for federation | `false` | | `federation.ingress.className` | Ingress class name for federation | `""` | | `federation.ingress.controllerType` | Specify what type of ingress controller you're using to add the necessary annotations accordingly. If blank, autodetection is attempted. If other, no annotations will be added. Must be one of [ingress-nginx, openshift, other, ""]. | `""` | diff --git a/charts/spire/charts/spire-server/templates/configmap.yaml b/charts/spire/charts/spire-server/templates/configmap.yaml index a0aca75..eea9d3a 100644 --- a/charts/spire/charts/spire-server/templates/configmap.yaml +++ b/charts/spire/charts/spire-server/templates/configmap.yaml @@ -22,6 +22,19 @@ {{- end }} {{- end }} {{- end }} +{{- $tlsFederationCount := 0 }} +{{- if .Values.federation.tls.spire.enabled }} +{{- $tlsFederationCount = add $tlsFederationCount 1 }} +{{- end }} +{{- if .Values.federation.tls.externalSecret.enabled }} +{{- $tlsFederationCount = add $tlsFederationCount 1 }} +{{- end }} +{{- if .Values.federation.tls.certManager.enabled }} +{{- $tlsFederationCount = add $tlsFederationCount 1 }} +{{- end }} +{{- if ne $tlsFederationCount 1 }} +{{- fail "You must enable one and only one federation TLS configuration" }} +{{- end }} {{- define "spire-server.yaml-config" -}} {{- $upstreamAuthorityUsed := 0 }} {{- $keyManagerUsed := 0 }} diff --git a/charts/spire/charts/spire-server/templates/federation-certificate.yaml b/charts/spire/charts/spire-server/templates/federation-certificate.yaml new file mode 100644 index 0000000..013d302 --- /dev/null +++ b/charts/spire/charts/spire-server/templates/federation-certificate.yaml @@ -0,0 +1,27 @@ +{{- define "spire-server.federation-cert-manager-default-cert" }} +{{- $fullName := include "spire-server.fullname" . }} +{{- $issuerFullName := printf "%s-federation" $fullName }} +dnsNames: + {{- if ne (len .Values.federation.tls.certManager.certificate.dnsNames) 0 }} + {{- toYaml .Values.federation.tls.certManager.certificate.dnsNames | nindent 4 }} + {{- else }} + - {{ include "spire-lib.ingress-calculated-name" (dict "ingress" .Values.federation.ingress "Values" .Values) }} + {{- end }} +issuerRef: + {{- with .Values.federation.tls.certManager.certificate.issuerRef.group }} + group: {{ . }} + {{- end }} + kind: {{ default "Issuer" .Values.federation.tls.certManager.certificate.issuerRef.kind }} + name: {{ default $issuerFullName .Values.federation.tls.certManager.certificate.issuerRef.name }} +secretName: {{ $issuerFullName }}-cert +{{- end }} +{{- if .Values.federation.tls.certManager.enabled }} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "spire-server.fullname" . }} + namespace: {{ include "spire-server.namespace" . }} +spec: + {{ merge (include "spire-server.federation-cert-manager-default-cert" . | fromYaml) .Values.federation.tls.certManager.certificate | toYaml | nindent 2 }} +{{- end }} diff --git a/charts/spire/charts/spire-server/templates/federation-ingress.yaml b/charts/spire/charts/spire-server/templates/federation-ingress.yaml index 009deaa..c61bb88 100644 --- a/charts/spire/charts/spire-server/templates/federation-ingress.yaml +++ b/charts/spire/charts/spire-server/templates/federation-ingress.yaml @@ -1,16 +1,34 @@ {{- if .Values.federation.enabled }} {{- if .Values.federation.ingress.enabled -}} -{{- $ingressControllerType := include "spire-lib.ingress-controller-type" (dict "global" .Values.global "ingress" .Values.federation.ingress) }} {{- $svcName := include "spire-server.fullname" . }} +{{/* Until https://github.com/spiffe/spire/issues/2202 is resolved, use ingress to implement cert-manager and externalSecret support. */}} +{{- $federationIngress := deepCopy .Values.federation.ingress }} +{{- if .Values.federation.tls.certManager.enabled }} +{{- $secret := printf "%s-federation-cert" $svcName }} +{{- $_ := set $federationIngress "tlsSecret" $secret }} +{{- end }} +{{- if .Values.federation.tls.externalSecret.enabled }} +{{- $_ := set $federationIngress "tlsSecret" .Values.federation.tls.externalSecret.secretName }} +{{- end }} +{{- $ingressControllerType := include "spire-lib.ingress-controller-type" (dict "global" .Values.global "ingress" .Values.federation.ingress) }} {{- $tlsSection := true }} {{- $annotations := deepCopy .Values.federation.ingress.annotations }} {{- if eq $ingressControllerType "ingress-nginx" }} {{- $_ := set $annotations "nginx.ingress.kubernetes.io/ssl-redirect" "true" }} {{- $_ := set $annotations "nginx.ingress.kubernetes.io/force-ssl-redirect" "true" }} {{- $_ := set $annotations "nginx.ingress.kubernetes.io/backend-protocol" "HTTPS" }} +{{- if not .Values.federation.ingress.tlsSecret }} +{{- $_ := set $annotations "nginx.ingress.kubernetes.io/ssl-passthrough" "true" }} +{{- end }} {{- else if eq $ingressControllerType "openshift" }} -{{- $_ := set $annotations "route.openshift.io/termination" "edge" }} +{{- if $federationIngress.tlsSecret }} +{{- $_ := set $annotations "route.openshift.io/termination" "reencrypt" }} +{{- else }} +{{- $_ := set $annotations "route.openshift.io/termination" "passthrough" }} +{{- $path = "" }} +{{- $pathType = "ImplementationSpecific" }} {{- $tlsSection = false }} +{{- end }} {{- end }} apiVersion: networking.k8s.io/v1 kind: Ingress @@ -24,6 +42,6 @@ metadata: {{- toYaml . | nindent 4 }} {{- end }} spec: - {{ include "spire-lib.ingress-spec" (dict "ingress" .Values.federation.ingress "svcName" $svcName "port" .Values.federation.bundleEndpoint.port "path" "/" "pathType" "Prefix" "tlsSection" $tlsSection "Values" .Values) | nindent 2 }} + {{ include "spire-lib.ingress-spec" (dict "ingress" $federationIngress "svcName" $svcName "port" .Values.federation.bundleEndpoint.port "path" "/" "pathType" "Prefix" "tlsSection" $tlsSection "Values" .Values) | nindent 2 }} {{- end }} {{- end }} diff --git a/charts/spire/charts/spire-server/templates/federation-issuer.yaml b/charts/spire/charts/spire-server/templates/federation-issuer.yaml new file mode 100644 index 0000000..2a159f5 --- /dev/null +++ b/charts/spire/charts/spire-server/templates/federation-issuer.yaml @@ -0,0 +1,22 @@ +{{- define "spire-server.federation-cert-manager-default-issuer" }} +{{- if not .Values.federation.tls.certManager.issuer.acme.email }} +{{- fail "You must specify an email address via certManager.issuer.acme.email" }} +{{- end }} +email: {{ .Values.federation.tls.certManager.issuer.acme.email | quote}} +server: {{ .Values.federation.tls.certManager.issuer.acme.server | quote}} +privateKeySecretRef: + name: {{ include "spire-server.fullname" . }}-federation-issuer +solvers: +- http01: + ingress: {} +{{- end }} +{{- if and .Values.federation.tls.certManager.enabled .Values.federation.tls.certManager.issuer.create }} +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ include "spire-server.fullname" . }}-federation + namespace: {{ include "spire-server.namespace" . }} +spec: + acme: + {{ mergeOverwrite (include "spire-server.federation-cert-manager-default-issuer" . | fromYaml) .Values.federation.tls.certManager.issuer.acme | toYaml | nindent 4 }} +{{- end }} diff --git a/charts/spire/charts/spire-server/values.yaml b/charts/spire/charts/spire-server/values.yaml index 8ec0c5e..e9e5a1c 100644 --- a/charts/spire/charts/spire-server/values.yaml +++ b/charts/spire/charts/spire-server/values.yaml @@ -195,6 +195,45 @@ federation: ## @param federation.bundleEndpoint.address Address for trust bundle federation address: "0.0.0.0" + tls: + spire: + ## @param federation.tls.spire.enabled Use spire to secure the federation bundle endpoint + enabled: true + + externalSecret: + ## @param federation.tls.externalSecret.enabled Provide your own certificate/key via tls style Kubernetes Secret + enabled: false + ## @param federation.tls.externalSecret.secretName Specify which Secret to use + secretName: "" + + certManager: + ## @param federation.tls.certManager.enabled Use certificateManager to create the certificate + enabled: false + issuer: + ## @param federation.tls.certManager.issuer.create Create an issuer to use to issue the certificate + create: true + acme: + ## @param federation.tls.certManager.issuer.acme.email Must be set in order to register with LetsEncrypt. By setting, you agree to their Terms of Service + email: "" + ## @param federation.tls.certManager.issuer.acme.server Server to use to get certificate. Defaults to LetsEncrypt + server: https://acme-v02.api.letsencrypt.org/directory + # Testing server: https://acme-staging-v02.api.letsencrypt.org/directory + ## @param federation.tls.certManager.issuer.acme.solvers [object] Configure the issuer solvers. Defaults to http01 via ingress. + solvers: {} + # - http01: + # ingress: + # ingressClassName: nginx + certificate: + ## @param federation.tls.certManager.certificate.dnsNames Override the dnsNames on the certificate request. Defaults to the same settings as Ingress + dnsNames: [] + ## @param federation.tls.certManager.certificate.issuerRef.group If you are using an external plugin, specify the group for it here + ## @param federation.tls.certManager.certificate.issuerRef.kind Kind of the issuer reference. Override if you want to use a ClusterIssuer + ## @param federation.tls.certManager.certificate.issuerRef.name Name of the issuer to use. If unset, it will use the name of the built in issuer + issuerRef: + group: "" + kind: Issuer + name: "" + ingress: ## @param federation.ingress.enabled Flag to enable ingress for federation enabled: false