保护 Envoy
Envoy 提供了许多功能来保护进出您的网络的流量,以及您的网络内代理和服务之间的流量。
传输层安全 (TLS
) 可用于保护所有类型的 HTTP
流量,包括 WebSockets
。
Envoy 还支持使用 TLS
传输和接收通用 TCP
流量。
Envoy 还提供了一些其他基于 HTTP
的协议,用于身份验证和授权,例如 JWT、RBAC 和 OAuth。
警告
以下指南将指导您逐步完成保护流量的各个方面。
要保护经过不受信任网络的流量,强烈建议您在控制连接两端或提供相关协议的地方使用加密和双向认证。
这里我们将提供一个使用 mTLS 的指南,它提供了加密和双向认证。
在使用 TLS
时,强烈建议您 验证 所有证书,尽可能做到这一点。
您有责任确保证书链的完整性,这超出了本指南的范围。
上游和下游 TLS
上下文
连接到 Envoy 代理流量的机器相对于 Envoy 来说是“下游”。
通过设置 DownstreamTLSContext 在 transport_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_socket 的 cluster 中添加 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
域名
SNI
是 TLS
协议的一个扩展,它允许从同一个 IP
地址提供的多个域名使用 TLS
保护。
要使用 SNI
保护侦听连接上的特定域名,您应该设置 filter_chain_match 的 listener
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
连接到端点
当连接到使用 SNI
的 TLS
端点时,您应该在 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 之一匹配,如 上面描述的。