From 50825d9fc9c243cce381aa246e2b0e0cb2cd0ba0 Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Mon, 25 Sep 2023 12:06:48 -0700 Subject: [PATCH] Deny production runs of example.org trust domains (#229) --- .../spire-root-server-values.yaml | 6 +++ .github/tests/dependencies/testcert.yaml | 4 +- charts/spire/README.md | 1 + .../templates/configmap.yaml | 2 + .../spire-agent/templates/configmap.yaml | 2 + charts/spire/charts/spire-server/README.md | 2 +- .../spire-server/templates/configmap.yaml | 6 +++ charts/spire/charts/spire-server/values.yaml | 2 +- charts/spire/templates/_spire-lib.tpl | 15 +++++++ charts/spire/values.yaml | 3 ++ examples/external-mysql/run-tests.sh | 2 +- examples/external-postgresql/run-tests.sh | 2 +- examples/nested/run-tests.sh | 4 +- examples/production/example-your-values.yaml | 45 +++++++++++++++++++ examples/production/run-tests.sh | 22 ++++----- examples/production/values.yaml | 2 + 16 files changed, 101 insertions(+), 19 deletions(-) create mode 100644 examples/production/example-your-values.yaml diff --git a/.github/tests/dependencies/spire-root-server-values.yaml b/.github/tests/dependencies/spire-root-server-values.yaml index 02ef8cffc..f58836640 100644 --- a/.github/tests/dependencies/spire-root-server-values.yaml +++ b/.github/tests/dependencies/spire-root-server-values.yaml @@ -1,3 +1,9 @@ +global: + spire: + clusterName: production + trustDomain: production.other + jwtIssuer: oidc-discovery.production.other + spire-server: controllerManager: enabled: false diff --git a/.github/tests/dependencies/testcert.yaml b/.github/tests/dependencies/testcert.yaml index a16b5c9bf..c639cb2cd 100644 --- a/.github/tests/dependencies/testcert.yaml +++ b/.github/tests/dependencies/testcert.yaml @@ -43,8 +43,8 @@ metadata: name: oidc spec: dnsNames: - - oidc-discovery.example.org - - spire-server-federation.example.org + - oidc-discovery.production.other + - spire-server-federation.production.other secretName: tls-cert issuerRef: name: demo-ca diff --git a/charts/spire/README.md b/charts/spire/README.md index 107f98080..0a6d6a393 100644 --- a/charts/spire/README.md +++ b/charts/spire/README.md @@ -98,6 +98,7 @@ Now you can interact with the Spire agent socket from your own application. The | `global.spire.trustDomain` | The trust domain for Spire install | `example.org` | | `global.spire.upstreamServerAddress` | Set what address to use for the upstream server when using nested spire | `""` | | `global.spire.image.registry` | Override all Spire image registries at once | `""` | +| `global.spire.strictMode` | Check values, such as trustDomain, are overridden with a suitable value for production. | `false` | | `global.installAndUpgradeHooks.enabled` | Enable Helm hooks to autofix common install/upgrade issues (should be disabled when using `helm template`) | `true` | | `global.deleteHooks.enabled` | Enable Helm hooks to autofix common delete issues (should be disabled when using `helm template`) | `true` | diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/templates/configmap.yaml b/charts/spire/charts/spiffe-oidc-discovery-provider/templates/configmap.yaml index 5fc7e7051..ed554059b 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/templates/configmap.yaml +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/templates/configmap.yaml @@ -1,3 +1,5 @@ +{{- include "spire-lib.check-strict-mode" (list . "trustDomain must be set" (eq (include "spire-lib.trust-domain" .) "example.org"))}} +{{- include "spire-lib.check-strict-mode" (list . "jwtIssuer must be set" (eq (include "spire-lib.jwt-issuer" .) "https://oidc-discovery.example.org"))}} {{- $oidcSocket := "/run/spire/oidc-sockets/spire-oidc-server.sock" }} {{- define "spiffe-oidc-discovery-provider.yaml-config" -}} {{- $oidcSocket := .oidcSocket }} diff --git a/charts/spire/charts/spire-agent/templates/configmap.yaml b/charts/spire/charts/spire-agent/templates/configmap.yaml index b1662e440..bc4fa4eb5 100644 --- a/charts/spire/charts/spire-agent/templates/configmap.yaml +++ b/charts/spire/charts/spire-agent/templates/configmap.yaml @@ -1,3 +1,5 @@ +{{- include "spire-lib.check-strict-mode" (list . "clusterName must be set" (eq (include "spire-lib.cluster-name" .) "example-cluster"))}} +{{- include "spire-lib.check-strict-mode" (list . "trustDomain must be set" (eq (include "spire-lib.trust-domain" .) "example.org"))}} {{- define "spire-agent.yaml-config" -}} agent: data_dir: "/run/spire" diff --git a/charts/spire/charts/spire-server/README.md b/charts/spire/charts/spire-server/README.md index 80f223cac..bf21975ab 100644 --- a/charts/spire/charts/spire-server/README.md +++ b/charts/spire/charts/spire-server/README.md @@ -153,7 +153,7 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr | `federation.ingress.annotations` | Annotations for the ingress object | `{}` | | `federation.ingress.hosts` | Host paths for ingress object | `[]` | | `federation.ingress.tls` | Secrets containining TLS certs to enable https on ingress | `[]` | -| `ca_subject.country` | Country for Spire server CA | `NL` | +| `ca_subject.country` | Country for Spire server CA | `ARPA` | | `ca_subject.organization` | Organization for Spire server CA | `Example` | | `ca_subject.common_name` | Common Name for Spire server CA | `example.org` | | `keyManager.disk.enabled` | Flag to enable keyManager on disk | `true` | diff --git a/charts/spire/charts/spire-server/templates/configmap.yaml b/charts/spire/charts/spire-server/templates/configmap.yaml index f540c57ff..94e8d1e0e 100644 --- a/charts/spire/charts/spire-server/templates/configmap.yaml +++ b/charts/spire/charts/spire-server/templates/configmap.yaml @@ -1,3 +1,9 @@ +{{- include "spire-lib.check-strict-mode" (list . "clusterName must be set" (eq (include "spire-lib.cluster-name" .) "example-cluster"))}} +{{- include "spire-lib.check-strict-mode" (list . "trustDomain must be set" (eq (include "spire-lib.trust-domain" .) "example.org"))}} +{{- include "spire-lib.check-strict-mode" (list . "jwtIssuer must be set" (eq (include "spire-lib.jwt-issuer" .) "https://oidc-discovery.example.org"))}} +{{- include "spire-lib.check-strict-mode" (list . "ca_subject.county must be set" (eq .Values.ca_subject.country "ARPA"))}} +{{- include "spire-lib.check-strict-mode" (list . "ca_subject.organization must be set" (eq .Values.ca_subject.organization "Example"))}} +{{- include "spire-lib.check-strict-mode" (list . "ca_subject.common_name must be set" (eq .Values.ca_subject.common_name "example.org"))}} {{- range $type, $tvals := .Values.customPlugins }} {{- if not (has $type (list "keyManager" "nodeAttestor" "upstreamAuthority" "notifier")) }} {{- fail (printf "Unknown plugin type specified: %s" $type) }} diff --git a/charts/spire/charts/spire-server/values.yaml b/charts/spire/charts/spire-server/values.yaml index 01cf2ccf5..348e1a750 100644 --- a/charts/spire/charts/spire-server/values.yaml +++ b/charts/spire/charts/spire-server/values.yaml @@ -225,7 +225,7 @@ federation: ca_subject: ## @param ca_subject.country Country for Spire server CA - country: NL + country: ARPA ## @param ca_subject.organization Organization for Spire server CA organization: Example ## @param ca_subject.common_name Common Name for Spire server CA diff --git a/charts/spire/templates/_spire-lib.tpl b/charts/spire/templates/_spire-lib.tpl index 2c7835157..64152ac5a 100644 --- a/charts/spire/templates/_spire-lib.tpl +++ b/charts/spire/templates/_spire-lib.tpl @@ -107,3 +107,18 @@ rules: {{- end }} {{- include "spire-lib.image" $root }} {{- end }} + +{{/* +Take in an array of, '.', a failure string to display, and boolean to to display it, +if strictMode is enabled and the boolean is true +*/}} +{{- define "spire-lib.check-strict-mode" }} +{{ $root := index . 0 }} +{{ $message := index . 1 }} +{{ $condition := index . 2 }} +{{- if (dig "spire" "strictMode" false $root.Values.global) }} +{{- if $condition }} +{{- fail $message }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/spire/values.yaml b/charts/spire/values.yaml index 06493faba..bcb9c45b8 100644 --- a/charts/spire/values.yaml +++ b/charts/spire/values.yaml @@ -24,6 +24,9 @@ global: ## @param global.spire.image.registry Override all Spire image registries at once registry: "" + ## @param global.spire.strictMode Check values, such as trustDomain, are overridden with a suitable value for production. + strictMode: false + installAndUpgradeHooks: ## @param global.installAndUpgradeHooks.enabled Enable Helm hooks to autofix common install/upgrade issues (should be disabled when using `helm template`) enabled: true diff --git a/examples/external-mysql/run-tests.sh b/examples/external-mysql/run-tests.sh index 76d6c1bdd..6815b296d 100755 --- a/examples/external-mysql/run-tests.sh +++ b/examples/external-mysql/run-tests.sh @@ -32,7 +32,7 @@ helm upgrade --install mysql mysql --version "$VERSION_MYSQL" --repo "$HELM_REPO --wait helm upgrade --install --namespace "spire-server" \ - --values "${SCRIPTPATH}/values.yaml,${SCRIPTPATH}/../production/values.yaml,${SCRIPTPATH}/../production/values-node-pod-antiaffinity.yaml" \ + --values "${SCRIPTPATH}/values.yaml,${SCRIPTPATH}/../production/values.yaml,${SCRIPTPATH}/../production/values-node-pod-antiaffinity.yaml,${SCRIPTPATH}/../production/example-your-values.yaml" \ --set 'spire-server.dataStore.sql.password=sp1ff3Test' --wait spire charts/spire helm test --namespace "spire-server" spire diff --git a/examples/external-postgresql/run-tests.sh b/examples/external-postgresql/run-tests.sh index fdb310d2e..388da84ab 100755 --- a/examples/external-postgresql/run-tests.sh +++ b/examples/external-postgresql/run-tests.sh @@ -32,7 +32,7 @@ helm upgrade --install postgresql postgresql --version "$VERSION_POSTGRESQL" --r --wait helm upgrade --install --namespace "spire-server" \ - --values "${SCRIPTPATH}/values.yaml,${SCRIPTPATH}/../production/values.yaml,${SCRIPTPATH}/../production/values-node-pod-antiaffinity.yaml" \ + --values "${SCRIPTPATH}/values.yaml,${SCRIPTPATH}/../production/values.yaml,${SCRIPTPATH}/../production/values-node-pod-antiaffinity.yaml,${SCRIPTPATH}/../production/example-your-values.yaml" \ --set 'spire-server.dataStore.sql.password=sp1ff3Test' --wait spire charts/spire helm test --namespace "spire-server" spire diff --git a/examples/nested/run-tests.sh b/examples/nested/run-tests.sh index a3ae4eb0a..0bace5dbf 100755 --- a/examples/nested/run-tests.sh +++ b/examples/nested/run-tests.sh @@ -34,10 +34,10 @@ helm upgrade --install --create-namespace spire charts/spire \ --wait kubectl get nodes -o go-template='{{range .items}}{{printf "%s\n" .metadata.uid}}{{end}}' | while read -r line; do - kubectl exec -t spire-server-0 -n "spire-root-server" -- spire-server entry create -spiffeID spiffe://example.org/example-cluster/nested-spire -parentID "spiffe://example.org/spire/agent/k8s_psat/example-cluster/$line" -selector k8s:pod-label:app.kubernetes.io/name:server -downstream + kubectl exec -t spire-server-0 -n "spire-root-server" -- spire-server entry create -spiffeID spiffe://production.other/production/nested-spire -parentID "spiffe://production.other/spire/agent/k8s_psat/production/$line" -selector k8s:pod-label:app.kubernetes.io/name:server -downstream done -helm upgrade --install --create-namespace --namespace spire-server --values "${SCRIPTPATH}/values.yaml,${SCRIPTPATH}/../production/values.yaml" \ +helm upgrade --install --create-namespace --namespace spire-server --values "${SCRIPTPATH}/values.yaml,${SCRIPTPATH}/../production/values.yaml,${SCRIPTPATH}/../production/values-node-pod-antiaffinity.yaml,${SCRIPTPATH}/../production/example-your-values.yaml" \ --wait spire charts/spire helm test --namespace spire-server spire diff --git a/examples/production/example-your-values.yaml b/examples/production/example-your-values.yaml new file mode 100644 index 000000000..be5efa32a --- /dev/null +++ b/examples/production/example-your-values.yaml @@ -0,0 +1,45 @@ +global: + spire: + clusterName: production + trustDomain: production.other + jwtIssuer: oidc-discovery.production.other + +spire-server: + ca_subject: + country: US + organization: Production + common_name: production.other + + ingress: + hosts: + - host: spire-server.production.other + paths: + - path: / + pathType: Prefix + tls: + - hosts: + - spire-server.production.other + federation: + ingress: + hosts: + - host: spire-server-federation.production.other + paths: + - path: / + pathType: Prefix + tls: + - hosts: + - spire-server-federation.production.other + secretName: tls-cert + +spiffe-oidc-discovery-provider: + ingress: + hosts: + - host: oidc-discovery.production.other + paths: + - path: / + pathType: Prefix + tls: + - secretName: tls-cert + hosts: + - oidc-discovery.production.other + diff --git a/examples/production/run-tests.sh b/examples/production/run-tests.sh index f47f53a9d..3f28928a0 100755 --- a/examples/production/run-tests.sh +++ b/examples/production/run-tests.sh @@ -48,7 +48,7 @@ kubectl apply -f "${DEPS}/testcert.yaml" -n spire-server --wait ip=$(kubectl get svc -n ingress-nginx ingress-nginx-controller -o go-template='{{ .spec.clusterIP }}') -echo "$ip" oidc-discovery.example.org +echo "$ip" oidc-discovery.production.other cat > /tmp/dummydns <