Description
Description:
I have a case where applications running in Kubernetes communicate with external services (outside Kubernetes and in another network) through a dedicated forward proxy. Apps send HTTP CONNECT request and the proxy opens a TCP tunnel. The flow is illustrated below.
I would like to make forward proxy transparent for apps by routing requests from applications via Envoy to forward proxy. This would allow to avoid sending HTTP CONNECT requests from apps. The desired solution is illustrated below.
It's quite easy to achieve the desired flow by creating the following listener:
static_resources:
listeners:
- name: egress_gateway_listener
address:
socket_address:
address: 0.0.0.0
port_value: 443
listener_filters:
- name: envoy.filters.listener.tls_inspector
filter_chains:
- filters:
- name: tcp
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
cluster: external_proxy_cluster
tunneling_config:
hostname: example.com:443
clusters:
- name: external_proxy_cluster
connect_timeout: 0.25s
type: strict_dns
lb_policy: round_robin
load_assignment:
cluster_name: proxy_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: external-proxy
port_value: 3128
The problem is that the tunneling_config.hostname
can only be statically defined, so I can't tunnel traffic to multiple destinations having a single listener. One of the potential solutions would be to set hostname
based on SNI. TLS Inspector filter provides SNI value in %REQUESTED_SERVER_NAME%
, but it's not possible to overwrite Host
header.
tunneling_config:
hostname: example.com:443
headers_to_add:
- header:
key: Host
value: "%REQUESTED_SERVER_NAME%"
append_action: OVERWRITE_IF_EXISTS_OR_ADD
So what do you think about to make Host
header mutable or to figure out another way to dynamically set tunneling_config.hostname
?