保护 Envoy

Envoy 提供了许多功能来保护进出您的网络的流量,以及您的网络内代理和服务之间的流量。

传输层安全 (TLS) 可用于保护所有类型的 HTTP 流量,包括 WebSockets

Envoy 还支持使用 TLS 传输和接收通用 TCP 流量。

Envoy 还提供了一些其他基于 HTTP 的协议,用于身份验证和授权,例如 JWTRBACOAuth

警告

以下指南将指导您逐步完成保护流量的各个方面。

要保护经过不受信任网络的流量,强烈建议您在控制连接两端或提供相关协议的地方使用加密和双向认证。

这里我们将提供一个使用 mTLS 的指南,它提供了加密和双向认证。

在使用 TLS 时,强烈建议您 验证 所有证书,尽可能做到这一点。

您有责任确保证书链的完整性,这超出了本指南的范围。

上游和下游 TLS 上下文

连接到 Envoy 代理流量的机器相对于 Envoy 来说是“下游”。

通过设置 DownstreamTLSContexttransport_socket 中的 listener,可以指定客户端可以连接到的 TLS 上下文。

您还需要提供有效的证书。

 1static_resources:
 2
 3  listeners:
 4  - name: listener_0
 5    address:
 6      socket_address:
 7        address: 0.0.0.0
 8        port_value: 10000
 9    filter_chains:
10    - filters:
11      - name: envoy.filters.network.http_connection_manager
12        typed_config:
13          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
14          stat_prefix: ingress_http
15          http_filters:
16          - name: envoy.filters.http.router
17            typed_config:
18              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
19          route_config:
20            name: local_route
21            virtual_hosts:
22            - name: local_service
23              domains: ["*"]
24              routes:
25              - match:
26                  prefix: "/"
27                route:
28                  host_rewrite_literal: www.envoyproxy.io
29                  cluster: service_envoyproxy_io
30      transport_socket:
31        name: envoy.transport_sockets.tls
32        typed_config:
33          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
34          common_tls_context:
35            tls_certificates:
36            - certificate_chain:
37                filename: certs/servercert.pem
38              private_key:
39                filename: certs/serverkey.pem

连接到“上游” TLS 服务反过来是通过在 transport_socketcluster 中添加 UpstreamTLSContext 来完成的。

40  clusters:
41  - name: service_envoyproxy_io
42    type: LOGICAL_DNS
43    # Comment out the following line to test on v6 networks
44    dns_lookup_family: V4_ONLY
45    load_assignment:
46      cluster_name: service_envoyproxy_io
47      endpoints:
48      - lb_endpoints:
49        - endpoint:
50            address:
51              socket_address:
52                address: www.envoyproxy.io
53                port_value: 443
54    transport_socket:
55      name: envoy.transport_sockets.tls
56      typed_config:
57        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext

在连接时验证端点的证书

当 Envoy 连接到上游 TLS 服务时,默认情况下它不会验证所提供的证书。

您可以使用 validation_context 来指定 Envoy 如何验证这些证书。

首先,您可以确保证书来自相互信任的证书颁发机构

42              socket_address:
43                address: www.envoyproxy.io
44                port_value: 443
45    transport_socket:
46      name: envoy.transport_sockets.tls
47      typed_config:
48        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
49        common_tls_context:
50          validation_context:
51            trusted_ca:
52              filename: certs/cacert.pem

您还可以确保证书的“主体备用名称”匹配。

这通常由 Web 证书 (X.509) 用于标识证书有效的域名或域名。

44                port_value: 443
45    transport_socket:
46      name: envoy.transport_sockets.tls
47      typed_config:
48        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
49        common_tls_context:
50          validation_context:
51            trusted_ca:
52              filename: certs/cacert.pem
53            match_typed_subject_alt_names:
54            - san_type: DNS

注意

如果证书的“主体备用名称”是通配符域名,例如 *.example.com,则使用 match_typed_subject_alt_names 匹配时应该使用它。

注意

参见 这里 查看证书验证的所有可能配置。

使用双向 TLS (mTLS) 强制客户端证书认证

使用双向 TLS (mTLS),Envoy 还提供了一种方法来验证连接的客户端。

至少您需要设置 require_client_certificate 并指定一个相互信任的证书颁发机构

29                  cluster: service_envoyproxy_io
30      transport_socket:
31        name: envoy.transport_sockets.tls
32        typed_config:
33          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
34          require_client_certificate: true
35          common_tls_context:
36            validation_context:
37              trusted_ca:
38                filename: certs/cacert.pem
39              match_typed_subject_alt_names:
40              - san_type: DNS
41                matcher:
42                  exact: proxy-postgres-frontend.example.com
43            tls_certificates:

您可以通过指定允许的“主体备用名称”来进一步限制连接的客户端的身份验证,这些名称在 match_typed_subject_alt_names 中,类似于 上面描述的 验证上游证书。

29                  cluster: service_envoyproxy_io
30      transport_socket:
31        name: envoy.transport_sockets.tls
32        typed_config:
33          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
34          require_client_certificate: true
35          common_tls_context:
36            validation_context:
37              trusted_ca:
38                filename: certs/cacert.pem
39              match_typed_subject_alt_names:
40              - san_type: DNS
41                matcher:
42                  exact: proxy-postgres-frontend.example.com
43            tls_certificates:

注意

参见 这里 查看证书验证的所有可能配置。

使用双向 TLS (mTLS) 通过客户端证书连接

当使用客户端证书连接到上游时,您可以按如下方式设置它们

46              private_key:
47                filename: certs/serverkey.pem
48
49  clusters:
50  - name: service_envoyproxy_io
51    type: LOGICAL_DNS
52    # Comment out the following line to test on v6 networks
53    dns_lookup_family: V4_ONLY
54    load_assignment:
55      cluster_name: service_envoyproxy_io
56      endpoints:
57      - lb_endpoints:
58        - endpoint:
59            address:
60              socket_address:
61                address: www.envoyproxy.io
62                port_value: 443
63    transport_socket:
64      name: envoy.transport_sockets.tls
65      typed_config:
66        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
67        common_tls_context:
68          tls_certificates:
69          - certificate_chain:
70              filename: certs/clientcert.pem

使用 SNI 在同一个 IP 地址提供多个 TLS 域名

SNITLS 协议的一个扩展,它允许从同一个 IP 地址提供的多个域名使用 TLS 保护。

要使用 SNI 保护侦听连接上的特定域名,您应该设置 filter_chain_matchlistener

29                  cluster: service_envoyproxy_io
30      filter_chain_match:
31        server_names:
32        - my-service-name.example.com
33      transport_socket:
34        name: envoy.transport_sockets.tls
35        typed_config:
36          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
37          common_tls_context:

查看这里了解有关 使用 SNI 创建多个端点的更多信息

使用 SNI 连接到端点

当连接到使用 SNITLS 端点时,您应该在 UpstreamTLSContext 的配置中设置 sni

这通常是您连接到的服务的 DNS 名称。

57                port_value: 443
58    transport_socket:
59      name: envoy.transport_sockets.tls
60      typed_config:
61        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
62        sni: www.envoyproxy.io

当连接到受 SNI 保护的 Envoy 端点时,它必须与端点 filter_chain_match 中设置的 server_names 之一匹配,如 上面描述的