このアーキテクチャを想定
................................................
. .
. .
. .
. .
┌───────────────────┐ ┌─────────────────┐
┌──────────────────┤ Customer Firewall ├─┐ ┌────────────────────┤Provider Firewall├─┐
│ └──────────┬────────┘ │ │Provider Network └──┬──────────────┘ │
│ Customer Network │ │ │ ┌─────────┴─┐ │
│ │ │ │ ┌─────┤ Envoy - B ├───────┐ │
│ │ │ │ │ └─────┬─────┘ │ │
│ ┌──────┴─────┐ │ │ │ │ │ │
│ ┌─────────┐ │ │ │ │ │ │ │ │
│ │ Client ├────┤ Envoy - A │ │ │ ┌────┴────┐ ┌───┴─────┐ ┌────┴────┐ │
│ └─────────┘ │ │ │ │ │ Service │ │ Service │ │ Service │ │
│ └────────────┘ │ │ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │
└────────────────────────────────────────┘ └────────────────────────────────────────┘
クライアントはプロバイダーネットワークのサービスに接続したいが、顧客ファイアウォール厳格な方針を持っているHTTPフィルタリングそしてSNIフィルタリング。
不正なトラフィックはすべてドロップされるため、許可されていないドメイン/SNI もドロップされます。
SNI/ドメイン特使B(envoy-b.example.com
) は許可されたファイアウォールでは、しかし、他のドメインを許可しない。
すべてのサービスはHTTP/HTTPSです
Envoy サーバーの構成は次のとおりです。
特使 - A:
- ポートをリッスンし
80
、すべてのHTTPトラフィックをEnvoy-Bに転送します。HTTP2 + TLSv1.3 - ポートをリッスン
443
し、TPCトラフィックをEnvoy-Bに転送しますそれ以上の暗号化なしで
static_resources:
listeners:
# HTTP
- name: http_forwarder
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 80
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: http_route
virtual_hosts:
- name: http_forwarder
domains: [ "*" ]
routes:
- match:
prefix: "/"
route:
cluster: forwarder_to_envoy_b_http
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
# HTTPS/TLS
- name: https_forwarder
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 443
filter_chains:
- filters:
- name: envoy.filters.network.tcp_proxy
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: forwarder_to_envoy_b_tls
stat_prefix: https_passthrough
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
clusters:
- name: forwarder_to_envoy_b_http
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: forwarder_to_envoy_b_http
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: envoy-b.example.com
port_value: 8888
dns_resolution_config:
resolvers:
- socket_address:
address: "1.1.1.1"
port_value: 53
dns_resolver_options:
no_default_search_domain: true
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
common_tls_context:
tls_params:
tls_minimum_protocol_version: TLSv1_3
tls_maximum_protocol_version: TLSv1_3
- name: forwarder_to_envoy_b_tls
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: forwarder_to_envoy_b_tls
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: envoy-b.example.com
port_value: 8889
dns_resolution_config:
resolvers:
- socket_address:
address: "1.1.1.1"
port_value: 53
dns_resolver_options:
no_default_search_domain: true
特使 - B:
- ポートをリッスンし
8888
、すべてのHTTP2 + TLSv1.3
トラフィックでトラフィックを復号化するそして転送するプレーンHTTPリクエストサービスへ - ポートをリッスン
8889
し、TPCトラフィックをEnvoy-Bに転送しますそれ以上の暗号化/復号化なしで
static_resources:
listeners:
- name: http_listener_0
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 8888
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: [ "*" ]
routes:
- match:
prefix: "/"
route:
cluster: http_cluster
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_params:
tls_minimum_protocol_version: TLSv1_3
tls_maximum_protocol_version: TLSv1_3
tls_certificates:
certificate_chain:
filename: /certs/proxy-crt.pem
private_key:
filename: /certs/proxy-key.pem
alpn_protocols: HTTP2
- name: tls_listener_0
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 8889
filter_chains:
- filters:
- name: envoy.filters.network.tcp_proxy
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: tls_cluster
stat_prefix: https_passthrough
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
clusters:
- name: http_cluster
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: http_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: private.service.example.com
port_value: 80
dns_resolution_config:
resolvers:
- socket_address:
address: "1.1.1.1"
port_value: 53
dns_resolver_options:
no_default_search_domain: true
- name: tls_cluster
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: tls_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: private.service.example.com
port_value: 443
dns_resolution_config:
resolvers:
- socket_address:
address: "1.1.1.1"
port_value: 53
dns_resolver_options:
no_default_search_domain: true
問題
クライアントがHTTPリクエストを送信すると、特使 - A暗号化され、SNIはenvoy-b.example.com
クライアントファイアウォールで許可されます(元のリクエストのHOSTヘッダーの代わりにprivate.service.example.com
)
しかし、クライアントがHTTPS/TLSトラフィックを送信すると、特使 - A転送中ですTCP ストリーム、SNIは変更されずにそのまま残りますprivate.service.example.com
-> このホスト名はファイアウォールで許可されていないためそれは落とされるだろう!
TCP プロキシのトラフィックを再度暗号化して、SNI を変更しenvoy-b.example.com
、ファイアウォールがリクエストをドロップしないようにします。
transport_socket
両方の Envoy ホストに TLS トラフィックを追加しようとしましたが、機能しませんでした。
Envoy A > clusters > forwarder_to_envoy_b_tls
:
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
common_tls_context:
tls_params:
tls_minimum_protocol_version: TLSv1_3
tls_maximum_protocol_version: TLSv1_3
Envoy B > listener > tls_listener_0
:
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_params:
tls_minimum_protocol_version: TLSv1_3
tls_maximum_protocol_version: TLSv1_3
tls_certificates:
certificate_chain:
filename: /certs/proxy-crt.pem
private_key:
filename: /certs/proxy-key.pem
alpn_protocols: HTTP2
ノート
- クライアントは、Envoy B が HTTPS トラフィックを HTTP に変換し、それを転送 (HTTPS を使用) し、その後 Envoy A で再び HTTPS 暗号化が行われることを受け入れません。
- サービスの秘密鍵にアクセスできないため、注1で説明したことを実行すると、証明書が変更されます。
- 特使BSNIが必要トラフィックをどのサービスに転送するかを決定する