set up for dynamic forward proxy

This commit is contained in:
Kenneth Jenkins 2025-02-10 15:44:00 -08:00
parent 50756ab49f
commit 24995b1806
6 changed files with 94 additions and 0 deletions

View file

@ -12,6 +12,9 @@ import (
envoy_config_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
envoy_config_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
envoy_extensions_clusters_dynamic_forward_proxy_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/clusters/dynamic_forward_proxy/v3"
envoy_extensions_common_dynamic_forward_proxy_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/common/dynamic_forward_proxy/v3"
envoy_extensions_network_dns_resolver_cares_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/network/dns_resolver/cares/v3"
envoy_extensions_transport_sockets_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/durationpb"
@ -22,6 +25,7 @@ import (
"github.com/pomerium/pomerium/internal/log"
"github.com/pomerium/pomerium/internal/telemetry/trace"
"github.com/pomerium/pomerium/internal/urlutil"
"github.com/pomerium/pomerium/pkg/protoutil"
)
// BuildClusters builds envoy clusters from the given config.
@ -114,6 +118,9 @@ func (b *Builder) BuildClusters(ctx context.Context, cfg *config.Config) ([]*env
clusters = append(clusters, cluster)
}
}
// XXX
clusters = append(clusters, b.forwardProxyCluster())
}
if err = validateClusters(clusters); err != nil {
@ -539,3 +546,48 @@ func getClusterDiscoveryType(lbEndpoints []*envoy_config_endpoint_v3.LbEndpoint)
}
return &envoy_config_cluster_v3.Cluster_Type{Type: envoy_config_cluster_v3.Cluster_STRICT_DNS}
}
func (b *Builder) forwardProxyCluster() *envoy_config_cluster_v3.Cluster {
clusterConfig := protoutil.NewAny(&envoy_extensions_clusters_dynamic_forward_proxy_v3.ClusterConfig{
ClusterImplementationSpecifier: &envoy_extensions_clusters_dynamic_forward_proxy_v3.ClusterConfig_DnsCacheConfig{
DnsCacheConfig: b.forwardProxyDNSCacheConfig(),
},
})
return &envoy_config_cluster_v3.Cluster{
Name: "dynamic-forward-proxy-cluster",
LbPolicy: envoy_config_cluster_v3.Cluster_CLUSTER_PROVIDED,
ClusterDiscoveryType: &envoy_config_cluster_v3.Cluster_ClusterType{
ClusterType: &envoy_config_cluster_v3.Cluster_CustomClusterType{
Name: "envoy.clusters.dynamic_forward_proxy",
TypedConfig: clusterConfig,
},
},
}
}
func (b *Builder) forwardProxyDNSCacheConfig() *envoy_extensions_common_dynamic_forward_proxy_v3.DnsCacheConfig {
resolverConfig := protoutil.NewAny(&envoy_extensions_network_dns_resolver_cares_v3.CaresDnsResolverConfig{
Resolvers: []*envoy_config_core_v3.Address{{
Address: &envoy_config_core_v3.Address_SocketAddress{
SocketAddress: &envoy_config_core_v3.SocketAddress{
Address: "8.8.8.8", // XXX: this should be configurable
PortSpecifier: &envoy_config_core_v3.SocketAddress_PortValue{
PortValue: 53,
},
},
},
}},
DnsResolverOptions: &envoy_config_core_v3.DnsResolverOptions{
UseTcpForDnsLookups: true,
NoDefaultSearchDomain: true,
},
})
return &envoy_extensions_common_dynamic_forward_proxy_v3.DnsCacheConfig{
Name: "dynamic_forward_proxy_cache_config",
DnsLookupFamily: envoy_config_cluster_v3.Cluster_AUTO,
TypedDnsResolverConfig: &envoy_config_core_v3.TypedExtensionConfig{
Name: "envoy.network.dns_resolver.cares",
TypedConfig: resolverConfig,
},
}
}

View file

@ -3,6 +3,8 @@ package envoyconfig
import (
envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
envoy_config_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
envoy_extensions_common_dynamic_forward_proxy_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/common/dynamic_forward_proxy/v3"
envoy_extensions_filters_http_dynamic_forward_proxy_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/dynamic_forward_proxy/v3"
envoy_extensions_filters_http_ext_authz_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/ext_authz/v3"
envoy_extensions_filters_http_header_mutation_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/header_mutation/v3"
envoy_extensions_filters_http_lua_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/lua/v3"
@ -76,6 +78,21 @@ func HTTPRouterFilter() *envoy_extensions_filters_network_http_connection_manage
}
}
func DynamicForwardProxyFilter(
dnsCacheConfig *envoy_extensions_common_dynamic_forward_proxy_v3.DnsCacheConfig,
) *envoy_extensions_filters_network_http_connection_manager.HttpFilter {
return &envoy_extensions_filters_network_http_connection_manager.HttpFilter{
Name: "envoy.filters.http.dynamic_forward_proxy",
ConfigType: &envoy_extensions_filters_network_http_connection_manager.HttpFilter_TypedConfig{
TypedConfig: protoutil.NewAny(&envoy_extensions_filters_http_dynamic_forward_proxy_v3.FilterConfig{
ImplementationSpecifier: &envoy_extensions_filters_http_dynamic_forward_proxy_v3.FilterConfig_DnsCacheConfig{
DnsCacheConfig: dnsCacheConfig,
},
}),
},
}
}
// LuaFilter creates a lua HTTP filter.
func LuaFilter(defaultSourceCode string) *envoy_extensions_filters_network_http_connection_manager.HttpFilter {
return &envoy_extensions_filters_network_http_connection_manager.HttpFilter{

View file

@ -35,6 +35,7 @@ func (b *Builder) BuildListeners(
li = proto.Clone(li).(*envoy_config_listener_v3.Listener)
li.Name = "http-ingress-internal-listener"
li.Address = nil
li.EnableReusePort = nil // not supported for an internal listener
li.ListenerSpecifier = &envoy_config_listener_v3.Listener_InternalListener{
InternalListener: &envoy_config_listener_v3.Listener_InternalListenerConfig{},
}

View file

@ -175,6 +175,7 @@ func (b *Builder) buildMainHTTPConnectionManagerFilter(
if !useQUIC && cfg.Options.CodecType == config.CodecTypeHTTP3 {
filters = append(filters, newQUICAltSvcHeaderFilter(cfg))
}
filters = append(filters, DynamicForwardProxyFilter(b.forwardProxyDNSCacheConfig()))
filters = append(filters, HTTPRouterFilter())
var maxStreamDuration *durationpb.Duration

View file

@ -98,6 +98,9 @@ func (b *Builder) buildMainRouteConfiguration(
return nil, err
}
vh.Routes = append(vh.Routes, rs...)
// XXX
vh.Routes = append(vh.Routes, b.buildDynamicForwardProxyRoute(cfg))
}
virtualHosts = append(virtualHosts, vh)

View file

@ -355,6 +355,26 @@ func (b *Builder) buildRouteForPolicyAndMatch(
return route, nil
}
func (b *Builder) buildDynamicForwardProxyRoute(cfg *config.Config) *envoy_config_route_v3.Route {
return &envoy_config_route_v3.Route{
Name: "dynamic",
Match: &envoy_config_route_v3.RouteMatch{
PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
Prefix: "/",
},
},
Action: &envoy_config_route_v3.Route_Route{
Route: &envoy_config_route_v3.RouteAction{
ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
Cluster: "dynamic-forward-proxy-cluster",
},
},
},
// XXX: does this need any RequestHeadersToRemove?
// XXX: does this need a Decorator?
}
}
func (b *Builder) buildPolicyRouteDirectResponseAction(r *config.DirectResponse) *envoy_config_route_v3.DirectResponseAction {
return &envoy_config_route_v3.DirectResponseAction{
Status: uint32(r.Status),