helm: Add support for mounting existing TLS root CA (#13671)

* helm: Add support for mounting existing TLS root CA #12594
* Document per-database CA trust
This commit is contained in:
Hugo Shaka
2022-08-03 16:23:40 +00:00
committed by GitHub
parent 7d23afed48
commit f8be9cb6be
10 changed files with 546 additions and 2 deletions
@@ -364,6 +364,34 @@ You can specify multiple databases by adding additional list elements.
You can see a list of all the supported [values which can be used in a Teleport database service configuration here](../../database-access/reference/configuration.mdx).
</Admonition>
<Admonition type="tip" title="Trusting Database CA">
Database CAs can be trusted on a per-database basis.
You must create a secret containing the database CA certificate in the same namespace as Teleport using a command like:
```code
$ kubectl create secret generic my-postgres-ca --from-file=ca.pem=/path/to/database-ca.pem
```
Then, deploy the Helm chart with the following values:
```yaml
databases:
- name: my-postgres
uri: postgres.example.com:5432
protocol: postgres
tls:
ca_cert_file: "/etc/teleport-tls-db/my-postgres/ca.pem"
extraVolumes:
- name: my-postgres-ca
secret:
secretName: my-postgres-ca
extraVolumeMounts:
- name: my-postgres-ca
mountPath: /etc/teleport-tls-db/my-postgres
readOnly: true
```
</Admonition>
## `dbResources`
| Type | Default value | Required? |
@@ -497,6 +525,47 @@ This can be used for joining a Teleport instance to a Teleport cluster which doe
One option might be to use Teleport's built-in [ACME support](./teleport-cluster.mdx#acme) or enable [cert-manager support](./teleport-cluster.mdx#highavailabilitycertmanager).
</Admonition>
## `tls`
### `existingCASecretName`
| Type | Default value |
| - | - |
| `string` | `""` |
`tls.existingCASecretName` sets the `SSL_CERT_FILE` environment variable to load a trusted CA or bundle in PEM format into Teleport pods.
This can be set to inject a root and/or intermediate CA so that Teleport can build a full trust chain on startup.
The injected CA will be used to validate TLS communications, with the Proxy Service, with upstream applications or databases.
<Admonition type="note">
The recommended way to trust a database CA is to do it per-database instead of adding the CA to the global Teleport trust store.
It allows to trust multiple CAs while limiting the trust scope to their specific databases. See [the `databases` section](#databases).
</Admonition>
You must create a secret containing the CA certs in the same namespace as Teleport using a command like:
```code
$ kubectl create secret generic my-root-ca --from-file=ca.pem=/path/to/root-ca.pem
```
<Notice type="warning" title="Root CA filename">
The key containing the root CA in the secret must be `ca.pem`.
</Notice>
<Tabs>
<TabItem label="values.yaml">
```yaml
tls:
existingCASecretName: my-root-ca
```
</TabItem>
<TabItem label="--set">
```shell
--set tls.existingSecretName=my-root-ca
```
</TabItem>
</Tabs>
## `existingDataVolume`
| Type | Default value |
@@ -0,0 +1,6 @@
authToken: auth-token
proxyAddr: proxy.example.com:3080
roles: kube
kubeClusterName: test-kube-cluster
tls:
existingCASecretName: "helm-lint-existing-tls-secret-ca"
@@ -100,6 +100,11 @@ spec:
readOnly: true
- mountPath: /var/lib/teleport
name: "data"
{{- if .Values.tls.existingCASecretName }}
- mountPath: /etc/teleport-tls-ca
name: "teleport-tls-ca"
readOnly: true
{{- end }}
{{- if .Values.extraVolumeMounts }}
{{- toYaml .Values.extraVolumeMounts | nindent 8 }}
{{- end }}
@@ -114,10 +119,16 @@ spec:
{{- if .Values.imagePullPolicy }}
imagePullPolicy: {{ toYaml .Values.imagePullPolicy }}
{{- end }}
{{- if .Values.extraEnv }}
{{- if or .Values.extraEnv .Values.tls.existingCASecretName }}
env:
{{- if (gt (len .Values.extraEnv) 0) }}
{{- toYaml .Values.extraEnv | nindent 8 }}
{{- end }}
{{- if .Values.tls.existingCASecretName }}
- name: SSL_CERT_FILE
value: /etc/teleport-tls-ca/ca.pem
{{- end }}
{{- end }}
args:
- "--diag-addr=0.0.0.0:3000"
{{- if .Values.insecureSkipProxyTLSVerify }}
@@ -167,6 +178,11 @@ spec:
readOnly: true
- mountPath: /var/lib/teleport
name: {{ default "data" .Values.existingDataVolume }}
{{- if .Values.tls.existingCASecretName }}
- mountPath: /etc/teleport-tls-ca
name: "teleport-tls-ca"
readOnly: true
{{- end }}
{{- if .Values.extraVolumeMounts }}
{{- toYaml .Values.extraVolumeMounts | nindent 8 }}
{{- end }}
@@ -181,6 +197,11 @@ spec:
- name: "data"
emptyDir: {}
{{- end }}
{{- if .Values.tls.existingCASecretName }}
- name: "teleport-tls-ca"
secret:
secretName: {{ .Values.tls.existingCASecretName }}
{{- end }}
{{- if .Values.extraVolumes }}
{{- toYaml .Values.extraVolumes | nindent 6 }}
{{- end }}
@@ -94,6 +94,11 @@ spec:
readOnly: true
- mountPath: /var/lib/teleport
name: "{{ .Release.Name }}-teleport-data"
{{- if .Values.tls.existingCASecretName }}
- mountPath: /etc/teleport-tls-ca
name: "teleport-tls-ca"
readOnly: true
{{- end }}
{{- if .Values.extraVolumeMounts }}
{{- toYaml .Values.extraVolumeMounts | nindent 8 }}
{{- end }}
@@ -123,6 +128,10 @@ spec:
fieldPath: metadata.namespace
- name: RELEASE_NAME
value: {{ .Release.Name }}
{{- if .Values.tls.existingCASecretName }}
- name: SSL_CERT_FILE
value: /etc/teleport-tls-ca/ca.pem
{{- end }}
{{- if .Values.extraEnv }}
{{- toYaml .Values.extraEnv | nindent 10 }}
{{- end }}
@@ -180,6 +189,11 @@ spec:
- mountPath: /var/lib/teleport
name: "data"
{{- end }}
{{- if .Values.tls.existingCASecretName }}
- mountPath: /etc/teleport-tls-ca
name: "teleport-tls-ca"
readOnly: true
{{- end }}
{{- if .Values.extraVolumeMounts }}
{{- toYaml .Values.extraVolumeMounts | nindent 8 }}
{{- end }}
@@ -194,6 +208,11 @@ spec:
- name: "data"
emptyDir: {}
{{- end}}
{{- if .Values.tls.existingCASecretName }}
- name: "teleport-tls-ca"
secret:
secretName: {{ .Values.tls.existingCASecretName }}
{{- end }}
{{- if .Values.extraVolumes }}
{{- toYaml .Values.extraVolumes | nindent 6 }}
{{- end }}
@@ -207,4 +226,4 @@ spec:
resources:
requests:
storage: {{ .Values.storage.requests }}
{{- end }}
{{- end }}
@@ -723,6 +723,136 @@ should mount extraVolumes and extraVolumeMounts if action is Upgrade:
- name: my-mount
secret:
secretName: mySecret
should mount tls.existingCASecretName and set environment when set in values if action is Upgrade:
1: |
containers:
- args:
- --diag-addr=0.0.0.0:3000
env:
- name: SSL_CERT_FILE
value: /etc/teleport-tls-ca/ca.pem
image: quay.io/gravitational/teleport:11.0.0-dev
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 6
httpGet:
path: /healthz
port: diag
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 1
name: teleport
ports:
- containerPort: 3000
name: diag
protocol: TCP
readinessProbe:
failureThreshold: 12
httpGet:
path: /readyz
port: diag
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- all
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 9807
volumeMounts:
- mountPath: /etc/teleport
name: config
readOnly: true
- mountPath: /etc/teleport-secrets
name: auth-token
readOnly: true
- mountPath: /var/lib/teleport
name: data
- mountPath: /etc/teleport-tls-ca
name: teleport-tls-ca
readOnly: true
serviceAccountName: RELEASE-NAME
volumes:
- configMap:
name: RELEASE-NAME
name: config
- name: auth-token
secret:
secretName: teleport-kube-agent-join-token
- emptyDir: {}
name: data
- name: teleport-tls-ca
secret:
secretName: helm-lint-existing-tls-secret-ca
should mount tls.existingCASecretName and set extra environment when set in values if action is Upgrade:
1: |
containers:
- args:
- --diag-addr=0.0.0.0:3000
env:
- name: HTTPS_PROXY
value: http://username:password@my.proxy.host:3128
- name: SSL_CERT_FILE
value: /etc/teleport-tls-ca/ca.pem
image: quay.io/gravitational/teleport:11.0.0-dev
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 6
httpGet:
path: /healthz
port: diag
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 1
name: teleport
ports:
- containerPort: 3000
name: diag
protocol: TCP
readinessProbe:
failureThreshold: 12
httpGet:
path: /readyz
port: diag
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- all
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 9807
volumeMounts:
- mountPath: /etc/teleport
name: config
readOnly: true
- mountPath: /etc/teleport-secrets
name: auth-token
readOnly: true
- mountPath: /var/lib/teleport
name: data
- mountPath: /etc/teleport-tls-ca
name: teleport-tls-ca
readOnly: true
serviceAccountName: RELEASE-NAME
volumes:
- configMap:
name: RELEASE-NAME
name: config
- name: auth-token
secret:
secretName: teleport-kube-agent-join-token
- emptyDir: {}
name: data
- name: teleport-tls-ca
secret:
secretName: helm-lint-existing-tls-secret-ca
should provision initContainer correctly when set in values if action is Upgrade:
1: |
containers:
@@ -1020,6 +1020,160 @@ should mount extraVolumes and extraVolumeMounts:
- name: my-mount
secret:
secretName: mySecret
should mount tls.existingCASecretName and set environment when set in values:
1: |
containers:
- args:
- --diag-addr=0.0.0.0:3000
env:
- name: TELEPORT_REPLICA_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: KUBE_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: RELEASE_NAME
value: RELEASE-NAME
- name: SSL_CERT_FILE
value: /etc/teleport-tls-ca/ca.pem
image: quay.io/gravitational/teleport:11.0.0-dev
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 6
httpGet:
path: /healthz
port: diag
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 1
name: teleport
ports:
- containerPort: 3000
name: diag
protocol: TCP
readinessProbe:
failureThreshold: 12
httpGet:
path: /readyz
port: diag
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- all
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 9807
volumeMounts:
- mountPath: /etc/teleport
name: config
readOnly: true
- mountPath: /etc/teleport-secrets
name: auth-token
readOnly: true
- mountPath: /var/lib/teleport
name: data
- mountPath: /etc/teleport-tls-ca
name: teleport-tls-ca
readOnly: true
securityContext:
fsGroup: 9807
serviceAccountName: RELEASE-NAME
volumes:
- configMap:
name: RELEASE-NAME
name: config
- name: auth-token
secret:
secretName: teleport-kube-agent-join-token
- emptyDir: {}
name: data
- name: teleport-tls-ca
secret:
secretName: helm-lint-existing-tls-secret-ca
should mount tls.existingCASecretName and set extra environment when set in values:
1: |
containers:
- args:
- --diag-addr=0.0.0.0:3000
env:
- name: TELEPORT_REPLICA_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: KUBE_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: RELEASE_NAME
value: RELEASE-NAME
- name: SSL_CERT_FILE
value: /etc/teleport-tls-ca/ca.pem
- name: HTTPS_PROXY
value: http://username:password@my.proxy.host:3128
image: quay.io/gravitational/teleport:11.0.0-dev
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 6
httpGet:
path: /healthz
port: diag
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 1
name: teleport
ports:
- containerPort: 3000
name: diag
protocol: TCP
readinessProbe:
failureThreshold: 12
httpGet:
path: /readyz
port: diag
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 1
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- all
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 9807
volumeMounts:
- mountPath: /etc/teleport
name: config
readOnly: true
- mountPath: /etc/teleport-secrets
name: auth-token
readOnly: true
- mountPath: /var/lib/teleport
name: data
- mountPath: /etc/teleport-tls-ca
name: teleport-tls-ca
readOnly: true
securityContext:
fsGroup: 9807
serviceAccountName: RELEASE-NAME
volumes:
- configMap:
name: RELEASE-NAME
name: config
- name: auth-token
secret:
secretName: teleport-kube-agent-join-token
- emptyDir: {}
name: data
- name: teleport-tls-ca
secret:
secretName: helm-lint-existing-tls-secret-ca
should not add emptyDir for data when using StatefulSet:
1: |
containers:
@@ -499,6 +499,72 @@ tests:
- matchSnapshot:
path: spec.template.spec
- it: should mount tls.existingCASecretName and set environment when set in values if action is Upgrade
release:
isupgrade: true
set:
# unit test does not support lookup functions, so to test the behavior we use this undoc value
# https://github.com/helm/helm/issues/8137
unitTestUpgrade: true
values:
- ../.lint/existing-tls-secret-with-ca.yaml
asserts:
- contains:
path: spec.template.spec.volumes
content:
name: teleport-tls-ca
secret:
secretName: helm-lint-existing-tls-secret-ca
- contains:
path: spec.template.spec.containers[0].volumeMounts
content:
mountPath: /etc/teleport-tls-ca
name: teleport-tls-ca
readOnly: true
- contains:
path: spec.template.spec.containers[0].env
content:
name: SSL_CERT_FILE
value: /etc/teleport-tls-ca/ca.pem
- matchSnapshot:
path: spec.template.spec
- it: should mount tls.existingCASecretName and set extra environment when set in values if action is Upgrade
release:
isupgrade: true
set:
# unit test does not support lookup functions, so to test the behavior we use this undoc value
# https://github.com/helm/helm/issues/8137
unitTestUpgrade: true
values:
- ../.lint/existing-tls-secret-with-ca.yaml
- ../.lint/extra-env.yaml
asserts:
- contains:
path: spec.template.spec.volumes
content:
name: teleport-tls-ca
secret:
secretName: helm-lint-existing-tls-secret-ca
- contains:
path: spec.template.spec.containers[0].volumeMounts
content:
mountPath: /etc/teleport-tls-ca
name: teleport-tls-ca
readOnly: true
- contains:
path: spec.template.spec.containers[0].env
content:
name: SSL_CERT_FILE
value: /etc/teleport-tls-ca/ca.pem
- contains:
path: spec.template.spec.containers[0].env
content:
name: HTTPS_PROXY
value: http://username:password@my.proxy.host:3128
- matchSnapshot:
path: spec.template.spec
- it: should set priorityClassName when set in values if action is Upgrade
release:
isupgrade: true
@@ -424,6 +424,61 @@ tests:
- matchSnapshot:
path: spec.template.spec
- it: should mount tls.existingCASecretName and set environment when set in values
values:
- ../.lint/existing-tls-secret-with-ca.yaml
asserts:
- contains:
path: spec.template.spec.volumes
content:
name: teleport-tls-ca
secret:
secretName: helm-lint-existing-tls-secret-ca
- contains:
path: spec.template.spec.containers[0].volumeMounts
content:
mountPath: /etc/teleport-tls-ca
name: teleport-tls-ca
readOnly: true
- contains:
path: spec.template.spec.containers[0].env
content:
name: SSL_CERT_FILE
value: /etc/teleport-tls-ca/ca.pem
- matchSnapshot:
path: spec.template.spec
- it: should mount tls.existingCASecretName and set extra environment when set in values
values:
- ../.lint/existing-tls-secret-with-ca.yaml
- ../.lint/extra-env.yaml
asserts:
- contains:
path: spec.template.spec.volumes
content:
name: teleport-tls-ca
secret:
secretName: helm-lint-existing-tls-secret-ca
- contains:
path: spec.template.spec.containers[0].volumeMounts
content:
mountPath: /etc/teleport-tls-ca
name: teleport-tls-ca
readOnly: true
- contains:
path: spec.template.spec.containers[0].env
content:
name: SSL_CERT_FILE
value: /etc/teleport-tls-ca/ca.pem
- contains:
path: spec.template.spec.containers[0].env
content:
name: HTTPS_PROXY
value: http://username:password@my.proxy.host:3128
- matchSnapshot:
path: spec.template.spec
- it: should set serviceAccountName when set in values
values:
- ../.lint/stateful.yaml
@@ -158,6 +158,20 @@
"type": "boolean",
"default": false
},
"tls": {
"$id": "#/properties/tls",
"type": "object",
"required": [
"existingCASecretName"
],
"properties": {
"existingCASecretName": {
"$id": "#/properties/tls/properties/existingCASecretName",
"type": "string",
"default": ""
}
}
},
"existingDataVolume": {
"$id": "#/properties/existingDataVolume",
"type": "string",
@@ -89,6 +89,16 @@ caPin: []
# certificate.
insecureSkipProxyTLSVerify: false
# Settings for mounting your own TLS material in the agent pod.
# The agent does not expose a TLS server, so this is only used to trust CAs.
tls:
# Name of an existing secret to use which contains a CA or trust bundle in x509 PEM format.
# This is useful to trust private CAs.
# This will automatically set the SSL_CERT_FILE environment variable to trust the CA.
# Create the secret with `kubectl create secret generic --from-file=ca.pem=/path/to/root-ca.pem`
# The filename inside the secret is important - it _must_ be ca.pem
existingCASecretName: ""
# If set, will use an existing volume mounted via extraVolumes
# as the Teleport data directory.
# If anything is set under the "storage" key, this will be ignored.