From 7fe84999e8e8bb1aaa09df03c7a96ae3030f359d Mon Sep 17 00:00:00 2001 From: Lester Guerzon Date: Sun, 1 Sep 2024 15:53:58 +0800 Subject: [PATCH] feat: yubico and duo as secretkeys (#114) * feat: Yubikey as secrets * feat: Duo settings as secrets * test: minor testing improvement * fix: broken links in chart documentation * fix: outdated SMTP documentation --------- Signed-off-by: Lester Guerzon --- Makefile | 2 +- charts/vaultwarden/Chart.yaml | 2 +- charts/vaultwarden/README.md | 91 +++++++++++++++++---- charts/vaultwarden/ci/test-values.yaml | 26 ++++++ charts/vaultwarden/templates/_podSpec.tpl | 14 ++++ charts/vaultwarden/templates/configmap.yaml | 8 +- charts/vaultwarden/templates/secrets.yaml | 8 +- charts/vaultwarden/values.yaml | 38 +++++++-- 8 files changed, 160 insertions(+), 29 deletions(-) create mode 100644 charts/vaultwarden/ci/test-values.yaml diff --git a/Makefile b/Makefile index b3da8c9..de97ff3 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,6 @@ lint: ct lint --target-branch main test: - ct install --target-branch main --helm-extra-set-args="--set=domain=https://warden.example.com:8443" + ct install --target-branch main .PHONY: lint test diff --git a/charts/vaultwarden/Chart.yaml b/charts/vaultwarden/Chart.yaml index 4d88d20..acf8d6c 100644 --- a/charts/vaultwarden/Chart.yaml +++ b/charts/vaultwarden/Chart.yaml @@ -13,5 +13,5 @@ maintainers: - name: guerzon email: guerzon@proton.me url: https://github.com/guerzon -version: 0.25.2 +version: 0.26.0 kubeVersion: ">=1.12.0-0" diff --git a/charts/vaultwarden/README.md b/charts/vaultwarden/README.md index e300901..a296ae6 100644 --- a/charts/vaultwarden/README.md +++ b/charts/vaultwarden/README.md @@ -46,7 +46,7 @@ image: domain: "https://vaultwarden.contoso.com:9443/" ``` -Detailed configuration options can be found in the [Vaultwarden settings](./charts/vaultwarden/README.md#vaultwarden-settings) section. +Detailed configuration options can be found in the [General settings](#general-settings) section. ## Database options @@ -89,7 +89,7 @@ database: existingSecretKey: "secret-uri" ``` -Detailed configuration options can be found in the [Database Configuration](./charts/vaultwarden/README.md#database-configuration) section. +Detailed configuration options can be found in the [Database Configuration](#database-settings) section. ## SSL and Ingress @@ -148,7 +148,7 @@ ingress: alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:eu-central-1:ACCOUNT:certificate/LONGID" ``` -Detailed configuration options can be found in the [Exposure Parameters](./charts/vaultwarden/README.md#exposure-parameters) section. +Detailed configuration options can be found in the [Exposure Parameters](#exposure-settings) section. ## Security @@ -179,7 +179,47 @@ serviceAccount: name: "vaultwarden-svc" ``` -Detailed configuration options can be found in the [Security settings](./charts/vaultwarden/README.md#security-settings) section. +### MFA/2FA settings + +You can configure YubiKey authentication as described [here](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-Yubikey-OTP-authentication). An example configuration is as follows: + +```yaml +yubico: + clientId: "ABCDE" + secretKey: + value: "12345" +``` + +You could also use an existing Kubernetes secret: + +```yaml +yubico: + clientId: "ABCDE" + existingSecret: "yubisecrets" + secretKey: + existingSecretKey: "YUBI" +``` + +You can configure Duo authentication as described [here](https://help.bitwarden.com/article/setup-two-step-login-duo/#create-a-duo-security-account). An example configuration is as follows: + +```yaml +duo: + hostname: api.duohelp.com + iKey: "999888" + sKey: + value: "HELLO" +``` + +You could also use an existing Kubernetes secret: + +```yaml +duo: + hostname: api.duohelp.com + iKey: "999888" + existingSecret: "duosecrets" + sKey: + existingSecretKey: "DUO" +``` ## Mail settings @@ -190,13 +230,29 @@ smtp: host: mx01.contoso.com from: no-reply@contoso.com fromName: "Vault Administrator" - username: admin - password: password + username: + value: admin + password: + value: password acceptInvalidHostnames: "true" acceptInvalidCerts: "true" ``` -Detailed configuration options can be found in the [SMTP Configuration](./charts/vaultwarden/README.md#smtp-configuration) section. +You could also use an existing Kubernetes secret that contains the SMTP username and password: + +```yaml +smtp: + host: mx01.contoso.com + from: no-reply@contoso.com + fromName: "Vault Administrator" + existingSecret: smtpsecrets + username: + existingSecretKey: SMTP_USERNAME + password: + existingSecretKey: SMTP_PASSWORD +``` + +Detailed configuration options can be found in the [SMTP Configuration](#smtp-configuration) section. ## Persistent storage @@ -409,14 +465,18 @@ helm -n $NAMESPACE uninstall $RELEASE_NAME ### MFA/2FA settings -| Name | Description | Value | -| ------------------ | ------------------------------------------------------------------- | ----- | -| `yubico.clientId` | Yubico client ID | `""` | -| `yubico.secretKey` | Yubico secret key | `""` | -| `yubico.server` | Specify a Yubico server, otherwise the default servers will be used | `""` | -| `duo.ikey` | Duo Integration Key | `""` | -| `duo.secretKey` | Duo Secret Key | `""` | -| `duo.hostname` | Duo API hostname | `""` | +| Name | Description | Value | +| ------------------------------------ | --------------------------------------------------------------------------------------------------------- | ----- | +| `yubico.clientId` | Yubico client ID | `""` | +| `yubico.existingSecret` | Name of an existing secret containing the Yubico secret key. Also set yubico.secretKey.existingSecretKey. | `""` | +| `yubico.secretKey.value` | secretKey plain text | `""` | +| `yubico.secretKey.existingSecretKey` | When using an existing secret, specify the key which contains the secretKey. | `""` | +| `yubico.server` | Specify a Yubico server, otherwise the default servers will be used | `""` | +| `duo.iKey` | Duo Integration Key | `""` | +| `duo.existingSecret` | Name of an existing secret containing the Duo skey. Also set duo.sKey.existingSecretKey. | `""` | +| `duo.sKey.value` | sKey plain text | `""` | +| `duo.sKey.existingSecretKey` | When using an existing secret, specify the key which contains the sKey. | `""` | +| `duo.hostname` | Duo API hostname | `""` | ### SMTP Configuration @@ -460,3 +520,4 @@ helm -n $NAMESPACE uninstall $RELEASE_NAME | `ingress.pathType` | Path type for the ingress | `Prefix` | | `ingress.tlsSecret` | Kubernetes secret containing the SSL certificate when using the "nginx" class. | `""` | | `ingress.nginxAllowList` | Comma-separated list of IP addresses and subnets to allow. | `""` | +| `ingress.customHeadersConfigMap` | ConfigMap containing custom headers to be added to the ingress. | `{}` | diff --git a/charts/vaultwarden/ci/test-values.yaml b/charts/vaultwarden/ci/test-values.yaml new file mode 100644 index 0000000..fc8eaa8 --- /dev/null +++ b/charts/vaultwarden/ci/test-values.yaml @@ -0,0 +1,26 @@ +domain: "https://vaultwarden.contoso.com" + +ingress: + enabled: true + hostname: vaultwarden.contoso.com + class: "nginx" + customHeadersConfigMap: + Request-Id: $req_id + +adminToken: + value: "khit9gYQV6ax9LKTTm+s6QbZi5oiuR+3s1PEn9q3IRmCl9IQn7LmBpmFCOYTb7Mr" + +image: + pullSecrets: + - myRegKey + +yubico: + clientId: "ABCDE" + secretKey: + value: "12345" + +duo: + hostname: api.duohelp.com + iKey: "999888" + sKey: + value: "HELLO" diff --git a/charts/vaultwarden/templates/_podSpec.tpl b/charts/vaultwarden/templates/_podSpec.tpl index 792d3ba..8f60724 100644 --- a/charts/vaultwarden/templates/_podSpec.tpl +++ b/charts/vaultwarden/templates/_podSpec.tpl @@ -44,6 +44,20 @@ containers: key: {{ .key }} {{- end }} {{- end }} + {{- if or (.Values.yubico.secretKey.value) (.Values.yubico.secretKey.existingSecretKey) }} + - name: YUBICO_SECRET_KEY + valueFrom: + secretKeyRef: + name: {{ default (include "vaultwarden.fullname" .) .Values.yubico.existingSecret }} + key: {{ default "YUBICO_SECRET_KEY" .Values.yubico.secretKey.existingSecretKey }} + {{- end }} + {{- if or (.Values.duo.sKey.value) (.Values.duo.sKey.existingSecretKey) }} + - name: DUO_SKEY + valueFrom: + secretKeyRef: + name: {{ default (include "vaultwarden.fullname" .) .Values.duo.existingSecret }} + key: {{ default "DUO_SKEY" .Values.duo.sKey.existingSecretKey }} + {{- end }} {{- if or (.Values.smtp.username.value) (.Values.smtp.username.existingSecretKey )}} - name: SMTP_USERNAME valueFrom: diff --git a/charts/vaultwarden/templates/configmap.yaml b/charts/vaultwarden/templates/configmap.yaml index 6aa80c2..feeb352 100644 --- a/charts/vaultwarden/templates/configmap.yaml +++ b/charts/vaultwarden/templates/configmap.yaml @@ -71,16 +71,14 @@ data: PUSH_IDENTITY_URI: {{ . | quote }} {{- end }} {{- end }} - {{- if and .Values.yubico.clientId .Values.yubico.secretKey }} + {{- if and .Values.yubico.clientId (or .Values.yubico.secretKey.value .Values.yubico.secretKey.existingSecretKey) }} YUBICO_CLIENT_ID: {{ .Values.yubico.clientId | quote }} - YUBICO_SECRET_KEY: {{ .Values.yubico.secretKey | quote }} {{- if .Values.yubico.server }} YUBICO_SERVER: {{ .Values.yubico.server | quote }} {{- end }} {{- end }} - {{- if and .Values.duo.ikey .Values.duo.secretKey .Values.duo.hostname }} - DUO_IKEY: {{ .Values.duo.ikey | quote }} - DUO_SKEY: {{ .Values.duo.secretKey | quote }} + {{- if and .Values.duo.iKey .Values.duo.hostname (or .Values.duo.sKey.value .Values.duo.sKey.existingSecretKey) }} + DUO_IKEY: {{ .Values.duo.iKey | quote }} DUO_HOST: {{ .Values.duo.hostname | quote }} {{- end }} {{- with .Values.experimentalClientFeatureFlags }} diff --git a/charts/vaultwarden/templates/secrets.yaml b/charts/vaultwarden/templates/secrets.yaml index 7b2cd3a..2e52a88 100644 --- a/charts/vaultwarden/templates/secrets.yaml +++ b/charts/vaultwarden/templates/secrets.yaml @@ -1,4 +1,4 @@ -{{ if not (and ( .Values.smtp.existingSecret ) ( .Values.adminToken.existingSecret )) }} +{{ if not (and ( .Values.smtp.existingSecret ) ( .Values.adminToken.existingSecret ) ( .Values.pushNotifications.existingSecret ) ( .Values.yubico.existingSecret ) ( .Values.duo.existingSecret )) }} apiVersion: v1 kind: Secret metadata: @@ -12,6 +12,12 @@ data: {{- range .Values.image.extraSecrets }} {{ .key }}: {{ .value | b64enc | quote }} {{- end }} + {{- if not ( .Values.yubico.existingSecret ) }} + YUBICO_SECRET_KEY: {{ .Values.yubico.secretKey.value | b64enc | quote }} + {{- end }} + {{- if not ( .Values.duo.existingSecret ) }} + DUO_SKEY: {{ .Values.duo.sKey.value | b64enc | quote }} + {{- end }} {{- if not ( .Values.smtp.existingSecret ) }} SMTP_PASSWORD: {{ .Values.smtp.password.value | b64enc | quote }} SMTP_USERNAME: {{ .Values.smtp.username.value | b64enc | quote }} diff --git a/charts/vaultwarden/values.yaml b/charts/vaultwarden/values.yaml index 30d0569..7833d0f 100644 --- a/charts/vaultwarden/values.yaml +++ b/charts/vaultwarden/values.yaml @@ -541,25 +541,51 @@ orgGroupsEnabled: "false" ## ## Yubico (Yubikey) settings +## Reference: https://github.com/dani-garcia/vaultwarden/wiki/Enabling-Yubikey-OTP-authentication +## yubico: ## @param yubico.clientId Yubico client ID ## clientId: "" - ## @param yubico.secretKey Yubico secret key + ## @param yubico.existingSecret Name of an existing secret containing the Yubico secret key. Also set yubico.secretKey.existingSecretKey. ## - secretKey: "" + existingSecret: "" + ## Yubico secret key + ## + secretKey: + ## @param yubico.secretKey.value secretKey plain text + ## Example: ABCDEABCDEABCDEABCDE= + ## + value: "" + ## @param yubico.secretKey.existingSecretKey When using an existing secret, specify the key which contains the secretKey. + ## Example: YUBICO_SECRET_KEY + ## + existingSecretKey: "" ## @param yubico.server Specify a Yubico server, otherwise the default servers will be used ## server: "" ## Duo settings +## Reference: https://help.bitwarden.com/article/setup-two-step-login-duo/#create-a-duo-security-account +## duo: - ## @param duo.ikey Duo Integration Key + ## @param duo.iKey Duo Integration Key ## - ikey: "" - ## @param duo.secretKey Duo Secret Key + iKey: "" + ## @param duo.existingSecret Name of an existing secret containing the Duo skey. Also set duo.sKey.existingSecretKey. ## - secretKey: "" + existingSecret: "" + ## Duo secret key + ## + sKey: + ## @param duo.sKey.value sKey plain text + ## Example: ABCDEABCDEABCDEABCDE= + ## + value: "" + ## @param duo.sKey.existingSecretKey When using an existing secret, specify the key which contains the sKey. + ## Example: DUO_SKEY + ## + existingSecretKey: "" ## @param duo.hostname Duo API hostname ## hostname: ""