From 393d869976b31c8fd201c2d16e06645776e781d0 Mon Sep 17 00:00:00 2001 From: Cosmin Cojocar Date: Thu, 26 Jul 2018 21:49:56 +0200 Subject: [PATCH] dex: configure gRPC and generate the certificates (CA/server/client) during deployment (#6679) * dex: configure gRPC and generate the certificates (CA/server/client) during deployment In addition, the web cert values were refatored to be consistent with gRPC values. * dex: base resources name on the fullname template * dex: comment out the default values for resources * Bump dex chart version to 0.2.0 * Restore some of the original values of dex chart * Fix indent in the values files * Fix lint warnings --- stable/dex/Chart.yaml | 2 +- stable/dex/config/openssl.conf | 82 ++++++++++++++++ stable/dex/templates/config-openssl.yaml | 18 ++++ stable/dex/templates/deployment.yaml | 33 +++++-- stable/dex/templates/job-grpc-certs.yaml | 98 +++++++++++++++++++ .../{job.yaml => job-web-certs.yaml} | 23 ++--- stable/dex/templates/service.yaml | 7 +- stable/dex/values.yaml | 80 +++++++++------ 8 files changed, 290 insertions(+), 53 deletions(-) create mode 100644 stable/dex/config/openssl.conf create mode 100644 stable/dex/templates/config-openssl.yaml create mode 100644 stable/dex/templates/job-grpc-certs.yaml rename stable/dex/templates/{job.yaml => job-web-certs.yaml} (79%) diff --git a/stable/dex/Chart.yaml b/stable/dex/Chart.yaml index d6e8511cee..724623eda5 100644 --- a/stable/dex/Chart.yaml +++ b/stable/dex/Chart.yaml @@ -1,5 +1,5 @@ name: dex -version: 0.1.0 +version: 0.2.0 appVersion: 2.10.0 description: CoreOS Dex keywords: diff --git a/stable/dex/config/openssl.conf b/stable/dex/config/openssl.conf new file mode 100644 index 0000000000..e44be0eb5a --- /dev/null +++ b/stable/dex/config/openssl.conf @@ -0,0 +1,82 @@ +# OpenSSL configuration file. +# Adapted from https://github.com/coreos/matchbox/blob/master/examples/etc/matchbox/openssl.conf + +# default environment variable values +SAN = + +[ ca ] +# `man ca` +default_ca = CA_default + +[ CA_default ] +# Directory and file locations. +dir = . +certs = $dir/certs +crl_dir = $dir/crl +new_certs_dir = $dir/newcerts +database = $dir/index.txt +serial = $dir/serial +# certificate revocation lists. +crlnumber = $dir/crlnumber +crl = $dir/crl/intermediate-ca.crl +crl_extensions = crl_ext +default_crl_days = 30 +default_md = sha256 + +name_opt = ca_default +cert_opt = ca_default +default_days = 375 +preserve = no +policy = policy_loose + +[ policy_loose ] +# Allow the CA to sign a range of certificates. +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ req ] +# `man req` +default_bits = 4096 +distinguished_name = req_distinguished_name +string_mask = utf8only +default_md = sha256 + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +stateOrProvinceName = State or Province Name +localityName = Locality Name +0.organizationName = Organization Name +organizationalUnitName = Organizational Unit Name +commonName = Common Name + +# Certificate extensions (`man x509v3_config`) + +[ v3_ca ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +[ usr_cert ] +basicConstraints = CA:FALSE +nsCertType = client +nsComment = "OpenSSL Generated Client Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer +keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth + +[ server_cert ] +basicConstraints = CA:FALSE +nsCertType = server +nsComment = "OpenSSL Generated Server Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +keyUsage = critical, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth +subjectAltName = $ENV::SAN diff --git a/stable/dex/templates/config-openssl.yaml b/stable/dex/templates/config-openssl.yaml new file mode 100644 index 0000000000..280018e95f --- /dev/null +++ b/stable/dex/templates/config-openssl.yaml @@ -0,0 +1,18 @@ +{{- if .Values.certs.grpc.create }} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app: {{ template "dex.name" . }} + chart: {{ template "dex.chart" . }} + heritage: "{{ .Release.Service }}" + release: "{{ .Release.Name }}" + name: {{ template "dex.fullname" . }}-openssl-config + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": hook-succeeded +data: + openssl.conf: | +{{ .Files.Get "config/openssl.conf" | indent 4 }} +{{- end }} diff --git a/stable/dex/templates/deployment.yaml b/stable/dex/templates/deployment.yaml index 3dbe761d38..a088188fe4 100644 --- a/stable/dex/templates/deployment.yaml +++ b/stable/dex/templates/deployment.yaml @@ -1,6 +1,11 @@ {{ $fullname := include "dex.fullname" . }} -{{ $tlsBuiltName := printf "%s-tls" $fullname }} -{{ $tlsSecretName := default $tlsBuiltName .Values.secret.tlsName }} +{{ $httpsTlsBuiltName := printf "%s-tls" $fullname }} +{{ $httpsTlsSecretName := default $httpsTlsBuiltName .Values.certs.web.secret.tlsName }} +{{ $grpcTlsServerBuiltName := printf "%s-server-tls" $fullname }} +{{ $grpcTlsServerSecretName := default $grpcTlsServerBuiltName .Values.certs.grpc.secret.serverTlsName }} +{{ $grpcCaBuiltName := printf "%s-ca" $fullname }} +{{ $grpcCaSecretName := default $grpcCaBuiltName .Values.certs.grpc.secret.caName }} + apiVersion: apps/v1beta2 kind: Deployment metadata: @@ -41,16 +46,18 @@ spec: resources: {{ toYaml .Values.resources | indent 10 }} ports: - - name: https - containerPort: 5556 - protocol: TCP +{{ toYaml .Values.ports | indent 10 }} env: {{ toYaml .Values.env | indent 10 }} volumeMounts: - mountPath: /etc/dex/cfg name: config - - mountPath: /etc/dex/tls - name: tls + - mountPath: /etc/dex/tls/https/server + name: https-tls + - mountPath: /etc/dex/tls/grpc/server + name: grpc-tls-server + - mountPath: /etc/dex/tls/grpc/ca + name: grpc-tls-ca {{- if ne (len .Values.extraVolumeMounts) 0 }} {{ toYaml .Values.extraVolumeMounts | indent 8 }} {{- end }} @@ -62,10 +69,18 @@ spec: path: config.yaml secretName: {{ template "dex.fullname" . }} name: config - - name: tls + - name: https-tls secret: defaultMode: 420 - secretName: {{ $tlsSecretName | quote }} + secretName: {{ $httpsTlsSecretName | quote }} + - name: grpc-tls-server + secret: + defaultMode: 420 + secretName: {{ $grpcTlsServerSecretName | quote }} + - name: grpc-tls-ca + secret: + defaultMode: 420 + secretName: {{ $grpcCaSecretName| quote }} {{- if ne (len .Values.extraVolumes) 0 }} {{ toYaml .Values.extraVolumes | indent 6 }} {{- end }} diff --git a/stable/dex/templates/job-grpc-certs.yaml b/stable/dex/templates/job-grpc-certs.yaml new file mode 100644 index 0000000000..95e23a71f8 --- /dev/null +++ b/stable/dex/templates/job-grpc-certs.yaml @@ -0,0 +1,98 @@ +{{- if .Values.certs.grpc.create }} +{{ $fullname := include "dex.fullname" . }} +{{ $tlsServerBuiltName := printf "%s-server-tls" $fullname }} +{{ $tlsServerSecretName := default $tlsServerBuiltName .Values.certs.grpc.secret.serverTlsName }} +{{ $tlsClientBuiltName := printf "%s-client-tls" $fullname }} +{{ $tlsClientSecretName := default $tlsClientBuiltName .Values.certs.grpc.secret.clientTlsName }} +{{ $caBuiltName := printf "%s-ca" $fullname }} +{{ $caName := default $caBuiltName .Values.certs.grpc.secret.caName }} +{{ $openSslConfigName := printf "%s-openssl-config" $fullname }} +{{ $local := dict "i" 0 }} +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-weight": "2" + "helm.sh/hook-delete-policy": hook-succeeded + name: {{ $fullname }}-grpc-certs + labels: + app: {{ template "dex.name" . }} + chart: {{ template "dex.chart" . }} + heritage: "{{ .Release.Service }}" + release: "{{ .Release.Name }}" + component: "job" +spec: + activeDeadlineSeconds: {{ .Values.certs.grpc.activeDeadlineSeconds }} + template: + metadata: + labels: + app: {{ template "dex.name" . }} + release: "{{ .Release.Name }}" + component: "job" + spec: + serviceAccountName: {{ template "dex.serviceAccountName" . }} + restartPolicy: OnFailure + containers: + - name: main + image: "{{ .Values.certs.image }}:{{ .Values.certs.imageTag }}" + imagePullPolicy: {{ .Values.certs.imagePullPolicy }} + command: + - /bin/bash + - -exc + - | + export CONFIG=/etc/dex/tls/grpc/openssl.conf; + cat << EOF > san.cnf + {{- $_ := set $local "i" 1 }} + {{- range .Values.certs.grpc.altNames }} + DNS.{{ $local.i }}:{{ . }} + {{- $_ := set $local "i" ( add1 $local.i ) }} + {{- end }} + {{- $_ := set $local "i" 1 }} + {{- range .Values.certs.grpc.altIPs }} + IP.{{ $local.i }}:{{ . }} + {{- $_ := set $local "i" ( add1 $local.i ) }} + {{- end }} + EOF + export SAN=$(cat san.cnf | paste -sd "," -) + + # Creating basic files/directories + mkdir -p {certs,crl,newcerts} + touch index.txt + touch index.txt.attr + echo 1000 > serial + # CA private key (unencrypted) + openssl genrsa -out ca.key 4096; + # Certificate Authority (self-signed certificate) + openssl req -config $CONFIG -new -x509 -days 3650 -sha256 -key ca.key -extensions v3_ca -out ca.crt -subj "/CN=grpc-ca"; + # Server private key (unencrypted) + openssl genrsa -out server.key 2048; + # Server certificate signing request (CSR) + openssl req -config $CONFIG -new -sha256 -key server.key -out server.csr -subj "/CN=grpc-server"; + # Certificate Authority signs CSR to grant a certificate + openssl ca -batch -config $CONFIG -extensions server_cert -days 365 -notext -md sha256 -in server.csr -out server.crt -cert ca.crt -keyfile ca.key; + # Client private key (unencrypted) + openssl genrsa -out client.key 2048; + # Signed client certificate signing request (CSR) + openssl req -config $CONFIG -new -sha256 -key client.key -out client.csr -subj "/CN=grpc-client"; + # Certificate Authority signs CSR to grant a certificate + openssl ca -batch -config $CONFIG -extensions usr_cert -days 365 -notext -md sha256 -in client.csr -out client.crt -cert ca.crt -keyfile ca.key; + # Remove CSR's + rm *.csr; + + # Cleanup the existing configmap and secrets + kubectl delete configmap {{ $caName }} --namespace {{ .Release.Namespace }} || true + kubectl delete secret {{ $caName }} {{ $tlsServerSecretName }} {{ $tlsClientSecretName }} --namespace {{ .Release.Namespace }} || true + kubectl create configmap {{ $caName }} --namespace {{ .Release.Namespace }} --from-file=ca.crt; + # Store all certficates in secrets + kubectl create secret tls {{ $caName }} --namespace {{ .Release.Namespace }} --cert=ca.crt --key=ca.key; + kubectl create secret tls {{ $tlsServerSecretName }} --namespace {{ .Release.Namespace }} --cert=server.crt --key=server.key; + kubectl create secret tls {{ $tlsClientSecretName }} --namespace {{ .Release.Namespace }} --cert=client.crt --key=client.key; + volumeMounts: + - name: openssl-config + mountPath: /etc/dex/tls/grpc + volumes: + - name: openssl-config + configMap: + name: {{ $openSslConfigName }} +{{- end }} diff --git a/stable/dex/templates/job.yaml b/stable/dex/templates/job-web-certs.yaml similarity index 79% rename from stable/dex/templates/job.yaml rename to stable/dex/templates/job-web-certs.yaml index 7ffed69c72..c2e56afc36 100644 --- a/stable/dex/templates/job.yaml +++ b/stable/dex/templates/job-web-certs.yaml @@ -1,17 +1,18 @@ -{{- if .Values.selfSigned.create }} +{{- if .Values.certs.web.create }} {{ $fullname := include "dex.fullname" . }} {{ $tlsBuiltName := printf "%s-tls" $fullname }} -{{ $tlsSecretName := default $tlsBuiltName .Values.secret.tlsName }} +{{ $tlsSecretName := default $tlsBuiltName .Values.certs.web.secret.tlsName }} {{ $caBuiltName := printf "%s-ca" $fullname }} -{{ $caName := default $caBuiltName .Values.secret.caName }} +{{ $caName := default $caBuiltName .Values.certs.web.secret.caName }} {{ $local := dict "i" 0 }} apiVersion: batch/v1 kind: Job metadata: annotations: "helm.sh/hook": post-install + "helm.sh/hook-weight": "1" "helm.sh/hook-delete-policy": hook-succeeded - name: {{ template "dex.fullname" . }} + name: {{ $fullname }}-web-certs labels: app: {{ template "dex.name" . }} chart: {{ template "dex.chart" . }} @@ -19,7 +20,7 @@ metadata: release: "{{ .Release.Name }}" component: "job" spec: - activeDeadlineSeconds: {{ .Values.selfSigned.activeDeadlineSeconds }} + activeDeadlineSeconds: {{ .Values.certs.web.activeDeadlineSeconds }} template: metadata: labels: @@ -31,8 +32,8 @@ spec: restartPolicy: OnFailure containers: - name: main - image: "{{ .Values.selfSigned.image }}:{{ .Values.selfSigned.imageTag }}" - imagePullPolicy: {{ .Values.selfSigned.imagePullPolicy }} + image: "{{ .Values.certs.image }}:{{ .Values.certs.imageTag }}" + imagePullPolicy: {{ .Values.certs.imagePullPolicy }} command: - /bin/bash - -exc @@ -51,23 +52,23 @@ spec: [alt_names] {{- $_ := set $local "i" 1 }} - {{- range .Values.selfSigned.altNames }} + {{- range .Values.certs.web.altNames }} DNS.{{ $local.i }} = {{ . }} {{- $_ := set $local "i" ( add1 $local.i ) }} {{- end }} {{- $_ := set $local "i" 1 }} - {{- range .Values.selfSigned.altIPs }} + {{- range .Values.certs.web.altIPs }} IP.{{ $local.i }} = {{ . }} {{- $_ := set $local "i" ( add1 $local.i ) }} {{- end }} EOF openssl genrsa -out ca-key.pem 2048; - openssl req -x509 -new -nodes -key ca-key.pem -days {{ .Values.selfSigned.caDays }} -out ca.pem -subj "/CN=dex-ca"; + openssl req -x509 -new -nodes -key ca-key.pem -days {{ .Values.certs.web.caDays }} -out ca.pem -subj "/CN=dex-ca"; openssl genrsa -out key.pem 2048; openssl req -new -key key.pem -out csr.pem -subj "/CN=dex" -config req.cnf; - openssl x509 -req -in csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -days {{ .Values.selfSigned.certDays }} -extensions v3_req -extfile req.cnf; + openssl x509 -req -in csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -days {{ .Values.certs.web.certDays }} -extensions v3_req -extfile req.cnf; kubectl delete configmap {{ $caName | quote }} --namespace {{ .Release.Namespace }} || true kubectl delete secret {{ $caName | quote }} {{ $tlsSecretName }} --namespace {{ .Release.Namespace }} || true diff --git a/stable/dex/templates/service.yaml b/stable/dex/templates/service.yaml index 8ef3472783..c4bbafb1fa 100644 --- a/stable/dex/templates/service.yaml +++ b/stable/dex/templates/service.yaml @@ -15,8 +15,11 @@ spec: type: {{ .Values.service.type}} sessionAffinity: None ports: - - port: {{ .Values.service.port }} - targetPort: https +{{- range .Values.ports }} + - name: {{ .name }} + port: {{ .containerPort }} + targetPort: {{ .containerPort}} +{{- end}} {{- if hasKey .Values.service "externalIPs" }} externalIPs: {{ toYaml .Values.service.externalIPs | indent 4 }} diff --git a/stable/dex/values.yaml b/stable/dex/values.yaml index 48e34b0f08..09dd94238c 100644 --- a/stable/dex/values.yaml +++ b/stable/dex/values.yaml @@ -13,39 +13,54 @@ nodeSelector: {} replicas: 1 +# resources: + # limits: + # cpu: 100m + # memory: 50Mi + # requests: + # cpu: 100m + # memory: 50Mi + +ports: + - name: http + containerPort: 8080 + protocol: TCP + - name: grpc + containerPort: 5000 + protocol: TCP + service: type: ClusterIP - port: 5556 - # externalIPs: - -resources: - # Normal resource usage of dex server - # limits: - # cpu: 100m - # memory: 50Mi - # requests: - # cpu: 100m - # memory: 50Mi + annotations: {} extraVolumes: [] extraVolumeMounts: [] -selfSigned: - create: true +certs: image: gcr.io/google_containers/kubernetes-dashboard-init-amd64 imageTag: "v1.0.0" imagePullPolicy: "IfNotPresent" - caDays: 10000 - certDays: 10000 - altNames: - - dex.minikube.local - altIPs: {} -# - 192.168.42.219 - -secret: {} -# Override the default secret names here. -# tlsName: dex-tls -# caName: dex-ca + web: + create: true + activeDeadlineSeconds: 300 + caDays: 10000 + certDays: 10000 + altNames: + - dex.io + altIPs: {} + secret: + tlsName: dex-web-server-tls + caName: dex-web-server-ca + grpc: + create: true + activeDeadlineSeconds: 300 + altNames: + - dex.io + altIPs: {} + secret: + serverTlsName: dex-grpc-server-tls + clientTlsName: dex-grpc-client-tls + caName: dex-grpc-ca env: [] @@ -61,7 +76,7 @@ serviceAccount: name: config: - issuer: https://dex.minikube.local:5556 + issuer: https://dex.io storage: type: kubernetes config: @@ -69,9 +84,14 @@ config: logger: level: debug web: - https: 0.0.0.0:5556 - tlsCert: /etc/dex/tls/tls.crt - tlsKey: /etc/dex/tls/tls.key + http: 0.0.0.0:8080 +# tlsCert: /etc/dex/tls/https/server/tls.crt +# tlsKey: /etc/dex/tls/https/server/tls.key + grpc: + addr: 0.0.0.0:5000 + tlsCert: /etc/dex/tls/grpc/server/tls.crt + tlsKey: /etc/dex/tls/grpc/server/tls.key + tlsClientCA: /etc/dex/tls/grpc/ca/tls.crt connectors: # - type: github # id: github @@ -90,9 +110,9 @@ config: # - 'http://192.168.42.219:31850/oauth2/callback' # name: 'Example App' # secret: ZXhhbXBsZS1hcHAtc2VjcmV0 - +# enablePasswordDB: true -# staticPasswords: +# staticPasswords: # - email: "admin@example.com" # # bcrypt hash of the string "password" # hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W"