diff --git a/changelog.d/2-features/coturn-federation-dtls-helm-chart b/changelog.d/2-features/coturn-federation-dtls-helm-chart new file mode 100644 index 0000000000..7802dd7fe7 --- /dev/null +++ b/changelog.d/2-features/coturn-federation-dtls-helm-chart @@ -0,0 +1 @@ +Add federation options to the `coturn` Helm chart including DTLS support. The options themselves are strongly inspired by the `restund` Helm chart. diff --git a/charts/coturn/Chart.yaml b/charts/coturn/Chart.yaml index 57176f6a46..ae35753e9d 100644 --- a/charts/coturn/Chart.yaml +++ b/charts/coturn/Chart.yaml @@ -11,4 +11,4 @@ version: 0.0.42 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. -appVersion: 4.6.2-wireapp.2 +appVersion: 4.6.2-federation-wireapp.10 diff --git a/charts/coturn/templates/_helpers.tpl b/charts/coturn/templates/_helpers.tpl new file mode 100644 index 0000000000..32fea22520 --- /dev/null +++ b/charts/coturn/templates/_helpers.tpl @@ -0,0 +1,45 @@ +{{- define "coturn.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "coturn.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "coturn.labels" -}} +helm.sh/chart: {{ include "coturn.chart" . }} +{{ include "coturn.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "coturn.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "coturn.selectorLabels" -}} +app.kubernetes.io/name: {{ include "coturn.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/coturn/templates/configmap-coturn-conf-template.yaml b/charts/coturn/templates/configmap-coturn-conf-template.yaml index 4988275b9d..cc458f7db6 100644 --- a/charts/coturn/templates/configmap-coturn-conf-template.yaml +++ b/charts/coturn/templates/configmap-coturn-conf-template.yaml @@ -20,13 +20,15 @@ data: no-tls {{- end }} + # This is mandatory for federated DTLS + CA-file=/etc/ssl/certs/ca-certificates.crt + ## don't turn on coturn's cli. no-cli ## turn, stun. listening-ip=__COTURN_EXT_IP__ listening-port={{ .Values.coturnTurnListenPort }} - max-allocate-lifetime=3600 relay-ip=__COTURN_EXT_IP__ realm=dummy.io no-stun-backward-compatibility @@ -82,3 +84,24 @@ data: zrest ## static authentication secrets will be added below this line when the ## runtime configuration is generated. + + {{- if .Values.federate.enabled }} + ### federation setup + federation-listening-ip=__COTURN_EXT_IP__ + federation-listening-port={{ .Values.federate.port }} + federation-no-dtls={{ not .Values.federate.dtls.enabled }} + {{- if .Values.federate.dtls.enabled }} + federation-cert=/coturn-dtls-certificate/tls.crt + federation-pkey=/coturn-dtls-certificate/tls.key + {{ if hasKey .Values.federate.dtls.tls "privateKeyPassword" }} + federation-pkey-pwd={{ .Values.federate.dtls.tls.privateKeyPassword }} + {{ end }} + # list of host/ip/cert common names / subject alt names, and optional issuer + # names to accept DTLS connections from. There can be multiple entries, each + # entry is formated as: + # [,] + {{ range $entry := .Values.federate.dtls.remoteWhitelist }} + federation-remote-whitelist={{ $entry.host }}{{ if hasKey $entry "issuer" }},{{ $entry.issuer }}{{end}} + {{ end }} + {{ end }} + {{ end }} diff --git a/charts/coturn/templates/secret-or-certificate.yaml b/charts/coturn/templates/secret-or-certificate.yaml new file mode 100644 index 0000000000..a48eba9b49 --- /dev/null +++ b/charts/coturn/templates/secret-or-certificate.yaml @@ -0,0 +1,41 @@ +{{- if .Values.federate.dtls.enabled -}} + +{{- if .Values.federate.dtls.tls.issuerRef -}} +{{- if or .Values.federate.dtls.tls.key .Values.federate.dtls.tls.crt }} +{{- fail "issuerRef and {crt,key} are mutually exclusive" -}} +{{- end -}} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: "{{ include "coturn.fullname" . }}" + labels: + {{- include "coturn.labels" . | nindent 4 }} + {{- if .Values.federate.dtls.tls.certificate.labels }} + {{- toYaml .Values.federate.dtls.tls.certificate.labels | nindent 4}} + {{- end }} +spec: + dnsNames: + {{- toYaml .Values.federate.dtls.tls.certificate.dnsNames | nindent 4 }} + secretName: coturn-dtls-certificate + issuerRef: + {{- toYaml .Values.federate.dtls.tls.issuerRef | nindent 4 }} + privateKey: + rotationPolicy: Always + algorithm: ECDSA + size: 384 +{{- else if and .Values.federate.dtls.tls.key .Values.federate.dtls.tls.crt }} +apiVersion: v1 +kind: Secret +metadata: + name: coturn-dtls-certificate + labels: + {{- include "coturn.labels" . | nindent 4 }} +type: Opaque +data: + tls.key: {{ .Values.federate.dtls.tls.key | b64enc }} + tls.crt: {{ .Values.federate.dtls.tls.crt | b64enc }} +{{- else -}} +{{- fail "must specify tls.key and tls.crt , or tls.issuerRef" -}} +{{- end -}} + +{{- end -}} diff --git a/charts/coturn/templates/statefulset.yaml b/charts/coturn/templates/statefulset.yaml index 93550eb97f..8fa0d5f0ed 100644 --- a/charts/coturn/templates/statefulset.yaml +++ b/charts/coturn/templates/statefulset.yaml @@ -58,6 +58,11 @@ spec: secret: secretName: {{ .Values.tls.secretRef }} {{- end }} + {{- if .Values.federate.dtls.enabled }} + - name: coturn-dtls-certificate + secret: + secretName: coturn-dtls-certificate + {{- end }} initContainers: - name: get-external-ip image: bitnami/kubectl:1.24.12 @@ -116,6 +121,11 @@ spec: mountPath: /secrets-tls/ readOnly: true {{- end }} + {{- if .Values.federate.dtls.enabled }} + - name: coturn-dtls-certificate + mountPath: /coturn-dtls-certificate/ + readOnly: true + {{- end }} command: - /bin/sh - -c diff --git a/charts/coturn/values.yaml b/charts/coturn/values.yaml index 2b02df64a8..683cb2501d 100644 --- a/charts/coturn/values.yaml +++ b/charts/coturn/values.yaml @@ -41,6 +41,50 @@ tls: config: verboseLogging: false +federate: + enabled: false + port: 9191 + + dtls: + enabled: false + + tls: + # Example: + # + # tls: + # key: "-----BEGIN EC PRIVATE KEY----- ..." # (ascii blob) private key + # crt: "-----BEGIN CERTIFICATE----- ..." # (ascii blob) certificate + # privateKeyPassword: "XXX" # optional, used when the key is password protected + # + # OR (mutually exclusive) + # + # tls: + # issuerRef: + # name: letsencrypt-http01 + # + # # We can reference ClusterIssuers by changing the kind here. + # # The default value is Issuer (i.e. a locally namespaced Issuer) + # # kind: Issuer + # kind: Issuer + # + # # This is optional since cert-manager will default to this value however + # # if you are using an external issuer, change this to that issuer group. + # group: cert-manager.io + # + # # optional labels to attach to the cert-manager Certificate + # certificate: + # labels: .. + + # # list of host/ip/cert common names / subject alt names, and optional issuer + # # names to accept DTLS connections from. There can be multiple entries. + # remoteWhitelist: + # - host: example.com + # issuer: Issuer Common Name + # - host: another.example.com + # issuer: "DigiCert SHA2 Extended Validation Server CA" + # - host: another-host-without-issuer.example.com + remoteWhitelist: [] + metrics: serviceMonitor: enabled: false