Enable more forms of kubelet certificate verification (#426)

* Enable kubelet certificate verification by default

Signed-off-by: Kevin Fox <[email protected]>

* Update charts/spire/README.md

Signed-off-by: kfox1111 <[email protected]>

* Update charts/spire/charts/spire-agent/templates/configmap.yaml

Signed-off-by: kfox1111 <[email protected]>

* Apply suggestions from code review

Signed-off-by: kfox1111 <[email protected]>

* Apply suggestions from code review

Signed-off-by: kfox1111 <[email protected]>

* Fix image

Signed-off-by: Kevin Fox <[email protected]>

* Apply suggestions from code review

Signed-off-by: kfox1111 <[email protected]>

* Incorperate feedback

Signed-off-by: Kevin Fox <[email protected]>

* Update charts/spire/charts/spire-agent/templates/configmap.yaml

Signed-off-by: kfox1111 <[email protected]>

---------

Signed-off-by: Kevin Fox <[email protected]>
Signed-off-by: kfox1111 <[email protected]>
Co-authored-by: Faisal Memon <[email protected]>
This commit is contained in:
kfox1111
2024-08-20 22:08:39 -07:00
committed by GitHub
co-authored by Faisal Memon
parent f92d729137
commit b96e07e349
6 changed files with 196 additions and 114 deletions
+5
View File
@@ -17,6 +17,11 @@
"filter": "LATESTSHA",
"sort-flags": []
},
{
"query": "hostCert.image",
"filter": "LATESTSHA",
"sort-flags": []
},
{
"query": "fsGroupFix.image",
"filter": "LATESTSHA",
+6
View File
@@ -88,6 +88,12 @@ kubectl delete crds clusterfederatedtrustdomains.spire.spiffe.io clusterspiffeid
We only support upgrading one major/minor version at a time. Version skipping isn't supported. Please see <https://spiffe.io/docs/latest/spire-helm-charts-hardened-about/upgrading/> for details.
### 0.23.X
In previous versions, the setting spire-agent.workloadAttestors.k8s.skipKubeletVerification was set to true by default. Starting in 0.23.x, we removed that setting and replaced it with
spire-agent.workloadAttestors.k8s.verification.type. It defaults to "skip" which will have the same behavior as before. In a future version, it will be set to "hostCert". Please try
setting it to this with your deployment and let us know if you run into any problems so we can fix it before we change the default for everyone.
### 0.21.X
- In previous versions, spire-server.upstreamAuthority.certManager.issuer_name would incorrectly have '-ca' appended. Starting with this version, that is no longer the case. If you previously set this
+9 -2
View File
@@ -26,7 +26,7 @@ A Helm chart to install the SPIRE agent.
### Chart parameters
| Name | Description | Value |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| `image.registry` | The OCI registry to pull the image from | `ghcr.io` |
| `image.repository` | The repository within the registry | `spiffe/spire-agent` |
| `image.pullPolicy` | The image pull policy | `IfNotPresent` |
@@ -87,7 +87,9 @@ A Helm chart to install the SPIRE agent.
| `nodeAttestor.tpmDirect.pubHash.image.tag` | Overrides the image tag | `v1.8.7` |
| `workloadAttestors.unix.enabled` | Enables the Unix workload attestor | `false` |
| `workloadAttestors.k8s.enabled` | Enables the Kubernetes workload attestor | `true` |
| `workloadAttestors.k8s.skipKubeletVerification` | If true, kubelet certificate verification is skipped | `true` |
| `workloadAttestors.k8s.verification.type` | What kind of verification to do against kubelet. Valid options are [hostCert, apiServerCA, skip] | `skip` |
| `workloadAttestors.k8s.verification.hostCert.basePath` | Path where kubelet places its certificates | `/var/lib/kubelet/pki` |
| `workloadAttestors.k8s.verification.hostCert.fileName` | File name where kubelet places its certificates. If blank, it will be auto detected. | `""` |
| `workloadAttestors.k8s.disableContainerSelectors` | Set to true if using holdApplicationUntilProxyStarts in Istio | `false` |
| `workloadAttestors.k8s.useNewContainerLocator` | If true, enables the new container locator algorithm that has support for cgroups v2. Defaults to false | `false` |
| `workloadAttestors.k8s.verboseContainerLocatorLogs` | If true, enables verbose logging of mountinfo and cgroup information used to locate containers. Defaults to false | `false` |
@@ -109,6 +111,11 @@ A Helm chart to install the SPIRE agent.
| `socketAlternate.image.pullPolicy` | The image pull policy | `Always` |
| `socketAlternate.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:27dc752a2ebacd10571c4045d3e1732f4bbb764446373ac85626602b69132776` |
| `socketAlternate.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` |
| `hostCert.image.registry` | The OCI registry to pull the image from | `cgr.dev` |
| `hostCert.image.repository` | The repository within the registry | `chainguard/min-toolkit-debug` |
| `hostCert.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `hostCert.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:eb1c3f94b5a2303d74a804c1bfd5adc9c98e55e344bbe1adcd6522d6e80d5733` |
| `hostCert.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` |
| `priorityClassName` | Priority class assigned to daemonset pods. Can be auto set with global.recommendations.priorityClassName. | `""` |
| `extraEnvVars` | Extra environment variables to be added to the Spire Agent container | `[]` |
| `extraVolumes` | Extra volumes to be mounted on Spire Agent pods | `[]` |
@@ -106,10 +106,12 @@ plugins:
{{- if .Values.workloadAttestors.k8s.enabled }}
k8s:
plugin_data:
# Defaults to the secure kubelet port by default.
# Minikube does not have a cert in the cluster CA bundle that
# can authenticate the kubelet cert, so skip validation.
skip_kubelet_verification: {{ .Values.workloadAttestors.k8s.skipKubeletVerification }}
{{- if eq .Values.workloadAttestors.k8s.verification.type "hostCert" }}
kubelet_ca_path: /hostCert/kubelet.crt
{{- else if eq .Values.workloadAttestors.k8s.verification.type "apiServerCA" }}
kubelet_ca_path: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
{{- end }}
skip_kubelet_verification: {{ eq .Values.workloadAttestors.k8s.verification.type "skip" }}
disable_container_selectors: {{ .Values.workloadAttestors.k8s.disableContainerSelectors }}
use_new_container_locator: {{ .Values.workloadAttestors.k8s.useNewContainerLocator }}
verbose_container_locator_logs: {{ .Values.workloadAttestors.k8s.verboseContainerLocatorLogs }}
@@ -74,6 +74,35 @@ spec:
{{- toYaml .Values.hostAliases | nindent 8 }}
{{- end }}
initContainers:
{{- if eq .Values.workloadAttestors.k8s.verification.type "hostCert" }}
- name: gather-host-cert
securityContext:
{{- $mainSecurityContext | toYaml | nindent 12 }}
image: {{ template "spire-lib.image" (dict "image" .Values.hostCert.image "global" .Values.global) }}
imagePullPolicy: {{ .Values.hostCert.image.pullPolicy }}
command: ["bash", "-xec"]
args:
- |
{{- if ne .Values.workloadAttestors.k8s.verification.hostCert.fileName "" }}
openssl x509 -in "{{ .Values.workloadAttestors.k8s.verification.hostCert.basePath }}/{{ .Values.workloadAttestors.k8s.verification.hostCert.fileName }}" -out /hostCert/kubelet.crt
{{- else }}
if [ -f "{{ .Values.workloadAttestors.k8s.verification.hostCert.basePath }}/kubelet-server-current.pem" ]; then
openssl x509 -in "{{ .Values.workloadAttestors.k8s.verification.hostCert.basePath }}/kubelet-server-current.pem" -out /hostCert/kubelet.crt
elif [ -f "{{ .Values.workloadAttestors.k8s.verification.hostCert.basePath }}/kubelet.crt" ]; then
openssl x509 -in "{{ .Values.workloadAttestors.k8s.verification.hostCert.basePath }}/kubelet.crt" -out /hostCert/kubelet.crt
else
echo Could not find certificate.
exit 1
fi
{{- end }}
chmod 644 /hostCert/kubelet.crt
volumeMounts:
- name: host-cert-isolated
mountPath: /hostCert
- name: host-cert
mountPath: {{ .Values.workloadAttestors.k8s.verification.hostCert.basePath | quote }}
readOnly: true
{{- end }}
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
{{- if .Values.nodeAttestor.tpmDirect.pubHash.enabled }}
- name: fingerprint-tpm
@@ -220,6 +249,11 @@ spec:
readOnly: false
- name: spire-token
mountPath: /var/run/secrets/tokens
{{- if eq .Values.workloadAttestors.k8s.verification.type "hostCert" }}
- name: host-cert-isolated
mountPath: /hostCert
readOnly: true
{{- end }}
{{- if gt (len .Values.extraVolumeMounts) 0 }}
{{- toYaml .Values.extraVolumeMounts | nindent 12 }}
{{- end }}
@@ -302,6 +336,13 @@ spec:
path: /dev/kmsg
type: CharDevice
{{- end }}
{{- if eq .Values.workloadAttestors.k8s.verification.type "hostCert" }}
- name: host-cert-isolated
emptyDir: {}
- name: host-cert
hostPath:
path: {{ .Values.workloadAttestors.k8s.verification.hostCert.basePath }}
{{- end }}
{{- if gt (len .Values.extraVolumes) 0 }}
{{- toYaml .Values.extraVolumes | nindent 8 }}
{{- end }}
+23 -2
View File
@@ -206,8 +206,14 @@ workloadAttestors:
k8s:
## @param workloadAttestors.k8s.enabled Enables the Kubernetes workload attestor
enabled: true
## @param workloadAttestors.k8s.skipKubeletVerification If true, kubelet certificate verification is skipped
skipKubeletVerification: true
verification:
## @param workloadAttestors.k8s.verification.type What kind of verification to do against kubelet. Valid options are [hostCert, apiServerCA, skip]
type: skip
hostCert:
## @param workloadAttestors.k8s.verification.hostCert.basePath Path where kubelet places its certificates
basePath: /var/lib/kubelet/pki
## @param workloadAttestors.k8s.verification.hostCert.fileName File name where kubelet places its certificates. If blank, it will be auto detected.
fileName: ""
## @param workloadAttestors.k8s.disableContainerSelectors Set to true if using holdApplicationUntilProxyStarts in Istio
disableContainerSelectors: false
## @param workloadAttestors.k8s.useNewContainerLocator If true, enables the new container locator algorithm that has support for cgroups v2. Defaults to false
@@ -268,6 +274,21 @@ socketAlternate:
## @param socketAlternate.resources Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
resources: {}
hostCert:
## @param hostCert.image.registry The OCI registry to pull the image from
## @param hostCert.image.repository The repository within the registry
## @param hostCert.image.pullPolicy The image pull policy
## @param hostCert.image.tag Overrides the image tag whose default is the chart appVersion
##
image:
registry: cgr.dev
repository: chainguard/min-toolkit-debug
pullPolicy: IfNotPresent
tag: latest@sha256:eb1c3f94b5a2303d74a804c1bfd5adc9c98e55e344bbe1adcd6522d6e80d5733
## @param hostCert.resources Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
resources: {}
## @param priorityClassName Priority class assigned to daemonset pods. Can be auto set with global.recommendations.priorityClassName.
priorityClassName: ""