Assuma esta arte
................................................
. .
. .
. .
. .
┌───────────────────┐ ┌─────────────────┐
┌──────────────────┤ Customer Firewall ├─┐ ┌────────────────────┤Provider Firewall├─┐
│ └──────────┬────────┘ │ │Provider Network └──┬──────────────┘ │
│ Customer Network │ │ │ ┌─────────┴─┐ │
│ │ │ │ ┌─────┤ Envoy - B ├───────┐ │
│ │ │ │ │ └─────┬─────┘ │ │
│ ┌──────┴─────┐ │ │ │ │ │ │
│ ┌─────────┐ │ │ │ │ │ │ │ │
│ │ Client ├────┤ Envoy - A │ │ │ ┌────┴────┐ ┌───┴─────┐ ┌────┴────┐ │
│ └─────────┘ │ │ │ │ │ Service │ │ Service │ │ Service │ │
│ └────────────┘ │ │ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │
└────────────────────────────────────────┘ └────────────────────────────────────────┘
O cliente deseja se conectar aos serviços da rede do provedor, mas oFirewall do clientetem uma política rígida sobreFiltragem HTTPeFiltragem SNI.
Ele eliminará qualquer tráfego não autorizado, portanto, qualquer domínio/SNI não permitido será eliminado.
O SNI/Domínio deEnviado B( envoy-b.example.com
) épermitidono firewall, mas elesnão permitir nenhum outro domínio.
Todos os serviços são HTTP/HTTPS
Aqui está a configuração dos servidores enviados:
Enviado - A:
- Ele escuta na porta
80
e, em cada tráfego HTTP, encaminhará o tráfego para o Envoy - B usandoHTTP2+TLSv1.3 - Ele escuta na porta
443
e em todosTPCtráfego, ele encaminhará o tráfego para Envoy - Bsem qualquer criptografia adicional
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
Enviado - B:
- Ele escuta na porta
8888
e em todoHTTP2 + TLSv1.3
tráfego, ele irádescriptografar o tráfegoe encaminhar osolicitação HTTP simplespara serviços - Ele escuta na porta
8889
e em todosTPCtráfego, ele encaminhará o tráfego para Envoy - Bsem qualquer criptografia/descriptografia adicional
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
O problema
Quando o cliente envia uma solicitação HTTP,Enviado - Airá criptografá-lo e o SNI será envoy-b.example.com
o permitido no firewall do cliente (em vez do cabeçalho HOST da solicitação original private.service.example.com
)
Mas quando o cliente envia um tráfego HTTPS/TLS,Enviado - Aestá apenas encaminhando umFluxo TCP, então o SNI não muda e permanece private.service.example.com
-> Como esse nome de host não é permitido no firewallele será descartado!
Quero que o tráfego do proxy TCP seja criptografado novamente para que o SNI mude para envoy-b.example.com
e o firewall não descarte a solicitação.
Tentei adicionar transport_socket
tráfego TLS em ambos os hosts enviados, mas não funcionou:
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
Notas
- O cliente não aceita que o enviado B converta o tráfego HTTPS em HTTP, depois o transfira (usando HTTPS) e, novamente, a criptografia HTTPS aconteça no Enviado A
- Não temos acesso às chaves privadas do serviço, portanto se fizermos o que está explicado na nota 1, os certificados mudam
- O Enviado BREQUER SNIpara determinar o tráfego deve encaminhar para quais serviços