保護 Envoy

Envoy 提供了許多功能來保護您的網路內部和外部的流量,以及網路內代理和服務之間的流量。

傳輸層安全性 (TLS) 可用於保護所有類型的 HTTP 流量,包括 WebSockets

Envoy 也支援透過 TLS 傳輸和接收通用的 TCP 流量。

Envoy 還提供許多其他基於 HTTP 的身份驗證和授權協議,例如 JWTRBACOAuth

警告

以下指南將帶您了解保護流量的各個方面。

為了保護不受信任網路上的流量,強烈建議您在可以控制連線兩端或有相關協議可用的情況下,盡可能使用加密和雙向驗證。

在這裡,我們提供使用 mTLS 的指南,它同時提供加密和雙向驗證。

當使用 TLS 時,強烈建議您盡可能 驗證所有憑證。

您有責任確保憑證鏈的完整性,這不在本指南的範圍內。

上游和下游 TLS 上下文

連線到 Envoy 以代理流量的機器相對於 Envoy 而言是「下游」。

指定客戶端可以連線的 TLS 上下文,可以透過在 DownstreamTLSContexttransport_socketlistener 中設定。

您還需要提供有效的憑證。

 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 服務則相反,透過將 UpstreamTLSContext 新增到 transport_socketcluster 中。

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 相符,如上述說明