TLS 配置
Gateway API 提供了多种配置 TLS 的方式。本文档详细列出了各种 TLS 设置,并给出通用的指导原则,帮你高效地使用它们。
尽管本文覆盖了使用 Gateway API 进行 TLS 配置的最常见形式,部分实现也会提供实现特有的扩展,允许你以不同或更高级的方式配置 TLS。除了本文档之外,也值得读一下你所用的 Gateway API 实现自身关于 TLS 的文档。
客户端/服务端与 TLS
对 Gateway 来说,有两条连接:
- downstream(下游):客户端与 Gateway 之间的连接。
- upstream(上游):Gateway 与 Route 指定的后端资源之间的连接。这些后端资源通常是 Service。
在 Gateway API 中,downstream 和 upstream 连接的 TLS 配置是相互独立的。
对于 downstream 连接,根据 Listener 协议的不同,支持的 TLS 模式和 Route 类型也不同。
| Listener Protocol | TLS Mode | Route Type Supported |
|---|---|---|
TLS | Passthrough | TLSRoute |
TLS | Terminate | TLSRoute(扩展) |
HTTPS | Terminate | HTTPRoute |
GRPC | Terminate | GRPCRoute |
在 Passthrough TLS 模式下,TLS 设置不生效——因为客户端发起的 TLS 会话不会在 Gateway 终止,而是加密地透传过 Gateway。
对于 upstream 连接,使用的是 BackendTLSPolicy;此时 listener 协议和 TLS 模式都不适用于 upstream TLS 配置。BackendTLSPolicy 是一个 Union Feature,这意味着它适用于任何把流量转发到后端的 Route 或 filter。对 HTTPRoute、GRPCRoute 以及 TLSRoute(在 Terminate 模式下)来说,使用 BackendTLSPolicy 就开启了"在 Gateway 处终止、再重新加密"的连接模式。
TLSRoute 的 Terminate 模式在 Extended Support Level 下提供。
Downstream TLS
Downstream TLS 设置通过 Gateway 层级的 listener 来配置。
Listeners 与 TLS
Listener 按 domain 或 subdomain 维度暴露 TLS 设置。Listener 的 TLS 设置会作用于所有满足 hostname 匹配条件的域名。
在下面这个示例中,Gateway 为所有请求提供 default-cert Secret 中定义的 TLS 证书。尽管该示例引用的是 HTTPS 协议,同样可以把这一特性用于纯 TLS 协议 + TLSRoute 的组合。
listeners:
- protocol: HTTPS # 另一个可能的取值是 `TLS`
port: 443
tls:
mode: Terminate # 如果 protocol 是 `TLS`,另一个可能的取值是 `Passthrough`
certificateRefs:
- kind: Secret
group: ""
name: default-cert示例
携带不同证书的 Listeners
下面这个示例中,Gateway 被配置为同时服务 foo.example.com 和 bar.example.com 两个域名。它们的证书都在 Gateway 中指定。
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: tls-basic
spec:
gatewayClassName: example
listeners:
- name: foo-https
protocol: HTTPS
port: 443
hostname: foo.example.com
tls:
certificateRefs:
- kind: Secret
group: ""
name: foo-example-com-cert
- name: bar-https
protocol: HTTPS
port: 443
hostname: bar.example.com
tls:
certificateRefs:
- kind: Secret
group: ""
name: bar-example-com-cert通配符 TLS Listeners
在下面这个示例中,Gateway 为 *.example.com 配置了通配符证书,并同时为 foo.example.com 配置了一张独立的证书。由于"更具体的匹配会优先",Gateway 会对**foo.example.com 的请求使用 foo-example-com-cert,对其它**请求使用 wildcard-example-com-cert。
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: wildcard-tls-gateway
spec:
gatewayClassName: example
listeners:
- name: foo-https
protocol: HTTPS
port: 443
hostname: foo.example.com
tls:
certificateRefs:
- kind: Secret
group: ""
name: foo-example-com-cert
- name: wildcard-https
protocol: HTTPS
port: 443
hostname: "*.example.com"
tls:
certificateRefs:
- kind: Secret
group: ""
name: wildcard-example-com-cert跨命名空间的证书引用
下面这个示例中,Gateway 引用了另一个命名空间下的证书。这种引用是被允许的,前提是目标命名空间中创建了对应的 ReferenceGrant。没有 ReferenceGrant 的话,跨命名空间引用会无效。
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: cross-namespace-tls-gateway
namespace: gateway-api-example-ns1
spec:
gatewayClassName: example
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: "*.example.com"
tls:
certificateRefs:
- kind: Secret
group: ""
name: wildcard-example-com-cert
namespace: gateway-api-example-ns2
---
apiVersion: gateway.networking.k8s.io/v1
kind: ReferenceGrant
metadata:
name: allow-ns1-gateways-to-ref-secrets
namespace: gateway-api-example-ns2
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: gateway-api-example-ns1
to:
- group: ""
kind: Secret客户端证书校验(Frontend mTLS)
Gateway API 支持在 TLS 握手阶段校验前端客户端出示的 TLS 证书。
与"server 证书"按 listener 配置不同,客户端证书校验是在 spec.tls 字段的 Gateway 级别进行配置。这种设计专门用来降低 HTTP/2 与 TLS connection coalescing 带来的安全风险——在那种场景下,原本为一个 listener 建立的连接可能被同端口上的另一个 listener 复用,从而绕过 listener 级别的校验设置。
配置概览
客户端校验通过 frontendValidation 结构体定义,指明 Gateway 应如何校验客户端的身份。
caCertificateRefs:Kubernetes 对象的引用列表(通常是 ConfigMap),其中保存 PEM 编码的 CA 证书包,用作校验客户端证书的信任锚。- 其他选项(
opt1、opt2)也可以视情况使用。 clientValidationMode:客户端证书校验的模式:AllowValidOnly(默认):只有当客户端出示了一张通过指定 CA 校验的有效证书时,Gateway 才接受该连接。AllowInsecureFallback:即使客户端证书缺失或校验失败,Gateway 也接受该连接。这种模式通常会把授权决策委托给后端,因此需要慎用。
Gateway 级别作用域
校验既可以对 Gateway 全局应用,也可以针对特定端口覆盖:
- 默认配置:除非在端口上有单独覆盖,否则该配置作用于 Gateway 上的所有 HTTPS listener。
- 按端口配置:允许做细粒度控制,对特定端口上所有 listener 的默认配置进行覆盖。
上述两种作用域可以组合使用,达到"全局基线 + 端口特例"的灵活效果。
示例
基础客户端校验
下面这个示例展示如何配置客户端证书校验(含默认配置 + 端口级覆盖):
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: client-validation-basic
spec:
gatewayClassName: acme-lb
tls:
frontend:
default:
validation:
caCertificateRefs:
- kind: ConfigMap
group: ""
name: foo-example-com-ca-cert
perPort:
- port: 8443
tls:
validation:
caCertificateRefs:
- kind: ConfigMap
group: ""
name: bar-example-com-ca-cert
listeners:
- name: foo-https
protocol: HTTPS
port: 443
hostname: foo.example.com
tls:
certificateRefs:
- kind: Secret
group: ""
name: foo-example-com-cert
- name: bar-https
protocol: HTTPS
port: 8443
hostname: bar.example.com
tls:
certificateRefs:
- kind: Secret
group: ""
name: bar-example-com-certUpstream TLS
Upstream TLS 设置通过 BackendTLSPolicy 来配置,它通过 target reference 挂到 Service 上。
这个资源可以用于描述:Gateway 应使用哪个 SNI 来连接后端,以及应如何校验后端 Pod 所出示的证书。
TargetRefs 与 TLS
BackendTLSPolicy 包含 TargetRefs 与 Validation 两部分。TargetRefs 是必填的,它指明你的 HTTPRoute 需要为哪些 Service 启用 TLS。Validation 配置包含一个必填的 Hostname,以及 CACertificateRefs 或 WellKnownCACertificates 二选一。
Hostname 指 Gateway 连接后端时应使用的 SNI,必须与后端 Pod 所出示的证书匹配。
CACertificateRefs 指一张或多张 PEM 编码的 TLS 证书。如果没有指定要使用哪张证书,就必须把 WellKnownCACertificates 设为 "System",以告知 Gateway 使用系统级的 CA 信任证书集合。不同实现所使用的"系统证书"集合可能略有不同,请参考你所选实现的文档了解详情。
示例
使用系统证书
下面这个示例中,BackendTLSPolicy 被配置为使用系统证书来建立 TLS 加密的上游连接,期望为 dev Service 提供 Pod 后端服务的证书能对 dev.example.com 有效:
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: tls-upstream-dev
spec:
targetRefs:
- kind: Service
name: dev
group: ""
validation:
wellKnownCACertificates: "System"
hostname: dev.example.com使用显式 CA 证书
下面这个示例中,BackendTLSPolicy 被配置为使用 auth-cert ConfigMap 中定义的证书,来建立 TLS 加密的上游连接,期望为 auth Service 提供 Pod 后端服务的证书能对 auth.example.com 有效:
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: tls-upstream-auth
spec:
targetRefs:
- kind: Service
name: auth
group: ""
validation:
caCertificateRefs:
- kind: ConfigMap
name: auth-cert
group: ""
hostname: auth.example.comGateway 的证书选择(Backend mTLS)
对 upstream 连接做 mTLS 时,除了要校验后端的证书之外,Gateway 还需要出示一张客户端证书给后端。这能保证后端只接受来自被授权 Gateway 的连接。
Gateway 客户端证书配置
要配置 Gateway 连接后端时所使用的客户端证书,请在 Gateway 资源的 tls.backend.clientCertificateRef 字段中指定。
这一配置对该 Gateway 作为客户端发起的所有 upstream 连接都生效。
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: backend-tls
spec:
gatewayClassName: acme-lb
tls:
backend:
clientCertificateRef:
kind: Secret
group: ""
name: foo-example-cert
listeners:
- name: foo-http
protocol: HTTP
port: 80
hostname: foo.example.com扩展
Gateway 的 TLS 配置提供了一个 options 字段,可以补充实现特有的 TLS 设置。可以填进这里的特性例子包括:TLS 版本限制、可用的密码套件等。