diff --git a/charts/gateway/Chart.yaml b/charts/gateway/Chart.yaml index 78bef5c..ccd95c7 100644 --- a/charts/gateway/Chart.yaml +++ b/charts/gateway/Chart.yaml @@ -16,7 +16,7 @@ type: application # Versions are expected to follow Semantic Versioning (https://semver.org/) # major.minor mirrors the API7 EE release line (3.9.x), patch is this chart's # own counter on that line and is decoupled from the app patch (see appVersion). -version: 3.9.5 +version: 3.9.6 # 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 diff --git a/charts/gateway/README.md b/charts/gateway/README.md index 4c72f24..04c1972 100644 --- a/charts/gateway/README.md +++ b/charts/gateway/README.md @@ -193,8 +193,9 @@ The command removes all the Kubernetes components associated with the chart and | gateway.readinessProbe | object | `{}` | kubernetes readiness probe, we will provide a probe based on tcpSocket to gateway's HTTP port by default. | | gateway.stream | object | `{"autoAssignNodePort":false,"enabled":false,"only":false,"tcp":[],"udp":[]}` | API7 Gateway service settings for stream. L4 proxy (TCP/UDP) | | gateway.stream.autoAssignNodePort | bool | `false` | Whether to set nodePort to the same value as the TCP/UDP port when gateway.type is NodePort, make sure the nodePort to be in the valid NodePort range of kubernetes service. | -| gateway.tls | object | `{"additionalContainerPorts":[],"certCAFilename":"","containerPort":9443,"enabled":true,"existingCASecret":"","fallbackSNI":"","http2":{"enabled":true},"ip":"0.0.0.0","nodePort":null,"servicePort":443,"sslProtocols":"TLSv1.2 TLSv1.3"}` | API7 Gateway service settings for tls | +| gateway.tls | object | `{"additionalContainerPorts":[],"additionalTrustedCAs":[],"certCAFilename":"","containerPort":9443,"enabled":true,"existingCASecret":"","fallbackSNI":"","http2":{"enabled":true},"ip":"0.0.0.0","nodePort":null,"servicePort":443,"sslProtocols":"TLSv1.2 TLSv1.3"}` | API7 Gateway service settings for tls | | gateway.tls.additionalContainerPorts | list | `[]` | Support multiple https ports, See [Configuration](https://github.com/apache/apisix/blob/0bc65ea9acd726f79f80ae0abd8f50b7eb172e3d/conf/config-default.yaml#L99) | +| gateway.tls.additionalTrustedCAs | list | `[]` | Additional CA certificates to append to the gateway's outbound trust store (`ssl_trusted_certificate`), on top of the system CAs and `existingCASecret`. Each entry mounts `filename` from the given Secret `secretName` into the gateway and adds it to the trust list, so the gateway can verify external services signed by a private/enterprise CA (e.g. an `openid-connect` identity provider) without replacing the Control Plane-managed CA in `existingCASecret`. Takes effect after a gateway Pod restart, because the trust store is merged at startup. | | gateway.tls.certCAFilename | string | `""` | Filename be used in the gateway.tls.existingCASecret | | gateway.tls.existingCASecret | string | `""` | Specifies the name of Secret contains trusted CA certificates in the PEM format used to verify the certificate when APISIX needs to do SSL/TLS handshaking with external services (e.g. etcd) | | gateway.tls.fallbackSNI | string | `""` | If set this, when the client doesn't send SNI during handshake, the fallback SNI will be used instead | diff --git a/charts/gateway/templates/_helpers.tpl b/charts/gateway/templates/_helpers.tpl index a5e0bd6..a2446bb 100644 --- a/charts/gateway/templates/_helpers.tpl +++ b/charts/gateway/templates/_helpers.tpl @@ -196,3 +196,26 @@ Output: JSON {"entries": [{"port": 9200, "nodePort": ""}, ...]} {{- end -}} {{- dict "entries" $result | toJson -}} {{- end -}} + +{{/* +Build the value of `apisix.ssl.ssl_trusted_certificate` — the gateway's outbound +trust store. Starts from the system CA bundle (`system`), then appends the +Control Plane CA (gateway.tls.existingCASecret) and every entry in +gateway.tls.additionalTrustedCAs, matching the mount paths rendered in _pod.tpl. +Returns an empty string when TLS is disabled or no CA is configured, so the +caller can omit the key entirely. +*/}} +{{- define "gateway.sslTrustedCertificate" -}} +{{- if .Values.gateway.tls.enabled -}} +{{- $paths := list -}} +{{- if .Values.gateway.tls.existingCASecret -}} +{{- $paths = append $paths (printf "/usr/local/apisix/conf/ssl/%s" .Values.gateway.tls.certCAFilename) -}} +{{- end -}} +{{- range $i, $ca := .Values.gateway.tls.additionalTrustedCAs -}} +{{- $paths = append $paths (printf "/usr/local/apisix/conf/ssl/additional-ca-%d/%s" $i $ca.filename) -}} +{{- end -}} +{{- if $paths -}} +{{- printf "system,%s" (join "," $paths) -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/gateway/templates/_pod.tpl b/charts/gateway/templates/_pod.tpl index 494e0bb..fe7165e 100644 --- a/charts/gateway/templates/_pod.tpl +++ b/charts/gateway/templates/_pod.tpl @@ -189,6 +189,13 @@ spec: name: ssl subPath: {{ .Values.gateway.tls.certCAFilename }} {{- end }} + {{- if .Values.gateway.tls.enabled }} + {{- range $i, $ca := .Values.gateway.tls.additionalTrustedCAs }} + - mountPath: /usr/local/apisix/conf/ssl/additional-ca-{{ $i }} + name: additional-ca-{{ $i }} + readOnly: true + {{- end }} + {{- end }} {{- if .Values.etcd.auth.tls.enabled }} - mountPath: /etcd-ssl @@ -296,6 +303,16 @@ spec: secretName: {{ .Values.gateway.tls.existingCASecret | quote }} name: ssl {{- end }} + {{- if .Values.gateway.tls.enabled }} + {{- range $i, $ca := .Values.gateway.tls.additionalTrustedCAs }} + - secret: + secretName: {{ $ca.secretName | quote }} + items: + - key: {{ $ca.filename | quote }} + path: {{ $ca.filename | quote }} + name: additional-ca-{{ $i }} + {{- end }} + {{- end }} {{- if .Values.etcd.auth.tls.enabled }} - secret: secretName: {{ .Values.etcd.auth.tls.existingSecret | quote }} diff --git a/charts/gateway/templates/configmap.yaml b/charts/gateway/templates/configmap.yaml index a1cea48..fbd36fe 100644 --- a/charts/gateway/templates/configmap.yaml +++ b/charts/gateway/templates/configmap.yaml @@ -142,8 +142,8 @@ data: {{- end }} ssl_protocols: {{ .Values.gateway.tls.sslProtocols | quote }} ssl_ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA" - {{- if and .Values.gateway.tls.enabled .Values.gateway.tls.existingCASecret }} - ssl_trusted_certificate: "system,/usr/local/apisix/conf/ssl/{{ .Values.gateway.tls.certCAFilename }}" + {{- with (include "gateway.sslTrustedCertificate" .) }} + ssl_trusted_certificate: {{ . | quote }} {{- end }} {{- if .Values.gateway.tls.fallbackSNI }} fallback_sni: {{ .Values.gateway.tls.fallbackSNI }} diff --git a/charts/gateway/values.yaml b/charts/gateway/values.yaml index c9afaaa..80f2a93 100644 --- a/charts/gateway/values.yaml +++ b/charts/gateway/values.yaml @@ -350,6 +350,10 @@ gateway: existingCASecret: "" # -- Filename be used in the gateway.tls.existingCASecret certCAFilename: "" + # -- Additional CA certificates to append to the gateway's outbound trust store (`ssl_trusted_certificate`), on top of the system CAs and `existingCASecret`. Each entry mounts `filename` from the given Secret `secretName` into the gateway and adds it to the trust list, so the gateway can verify external services signed by a private/enterprise CA (e.g. an `openid-connect` identity provider) without replacing the Control Plane-managed CA in `existingCASecret`. Takes effect after a gateway Pod restart, because the trust store is merged at startup. + additionalTrustedCAs: [] + # - secretName: keycloak-ca + # filename: keycloak-ca.crt http2: enabled: true # -- TLS protocols allowed to use.