Skip to content

Commit

Permalink
feat: proxy protocol in ClientTrafficPolicy (envoyproxy#2203)
Browse files Browse the repository at this point in the history
* feat: proxy protocol in ClientTrafficPolicy

relates to envoyproxy#1328

Signed-off-by: Arko Dasgupta <arko@tetrate.io>

* address review comments

Signed-off-by: Arko Dasgupta <arko@tetrate.io>

---------

Signed-off-by: Arko Dasgupta <arko@tetrate.io>
Co-authored-by: zirain <zirain2009@gmail.com>
  • Loading branch information
arkodg and zirain authored Nov 21, 2023
1 parent 7ca8eb4 commit ae523a8
Show file tree
Hide file tree
Showing 12 changed files with 364 additions and 0 deletions.
14 changes: 14 additions & 0 deletions internal/gatewayapi/clienttrafficpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,9 @@ func translateClientTrafficPolicyForListener(policySpec *egv1a1.ClientTrafficPol
if httpIR != nil {
// Translate TCPKeepalive
translateListenerTCPKeepalive(policySpec.TCPKeepalive, httpIR)

// Translate Proxy Protocol
translateListenerProxyProtocol(policySpec.EnableProxyProtocol, httpIR)
}
}

Expand Down Expand Up @@ -321,3 +324,14 @@ func translateListenerTCPKeepalive(tcpKeepAlive *egv1a1.TCPKeepalive, httpIR *ir

httpIR.TCPKeepalive = irTCPKeepalive
}

func translateListenerProxyProtocol(enableProxyProtocol *bool, httpIR *ir.HTTPListener) {
// Return early if not set
if enableProxyProtocol == nil {
return
}

if *enableProxyProtocol {
httpIR.EnableProxyProtocol = true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
clientTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
namespace: envoy-gateway
name: target-gateway-1-section-http-1
spec:
enableProxyProtocol: true
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
sectionName: http-1
namespace: envoy-gateway
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http-1
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
- name: http-2
protocol: HTTP
port: 8080
allowedRoutes:
namespaces:
from: Same
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
clientTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
creationTimestamp: null
name: target-gateway-1-section-http-1
namespace: envoy-gateway
spec:
enableProxyProtocol: true
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
namespace: envoy-gateway
sectionName: http-1
status:
conditions:
- lastTransitionTime: null
message: ClientTrafficPolicy has been accepted.
reason: Accepted
status: "True"
type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
creationTimestamp: null
name: gateway-1
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
- allowedRoutes:
namespaces:
from: Same
name: http-1
port: 80
protocol: HTTP
- allowedRoutes:
namespaces:
from: Same
name: http-2
port: 8080
protocol: HTTP
status:
listeners:
- attachedRoutes: 0
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: null
message: Listener has been successfully translated
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: null
message: Listener references have been resolved
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: http-1
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
- attachedRoutes: 0
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: null
message: Listener has been successfully translated
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: null
message: Listener references have been resolved
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: http-2
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
infraIR:
envoy-gateway/gateway-1:
proxy:
listeners:
- address: ""
ports:
- containerPort: 10080
name: http-1
protocol: HTTP
servicePort: 80
- containerPort: 8080
name: http-2
protocol: HTTP
servicePort: 8080
metadata:
labels:
gateway.envoyproxy.io/owning-gateway-name: gateway-1
gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
name: envoy-gateway/gateway-1
xdsIR:
envoy-gateway/gateway-1:
accessLog:
text:
- path: /dev/stdout
http:
- address: 0.0.0.0
enableProxyProtocol: true
hostnames:
- '*'
isHTTP2: false
name: envoy-gateway/gateway-1/http-1
port: 10080
- address: 0.0.0.0
hostnames:
- '*'
isHTTP2: false
name: envoy-gateway/gateway-1/http-2
port: 8080
2 changes: 2 additions & 0 deletions internal/ir/xds.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ type HTTPListener struct {
IsHTTP2 bool `json:"isHTTP2" yaml:"isHTTP2"`
// TCPKeepalive configuration for the listener
TCPKeepalive *TCPKeepalive `json:"tcpKeepalive,omitempty" yaml:"tcpKeepalive,omitempty"`
// EnableProxyProtocol enables the listener to interpret proxy protocol header
EnableProxyProtocol bool `json:"enableProxyProtocol,omitempty" yaml:"enableProxyProtocol,omitempty"`
}

// Validate the fields within the HTTPListener structure
Expand Down
3 changes: 3 additions & 0 deletions internal/xds/translator/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ func (t *Translator) addXdsHTTPFilterChain(xdsListener *listenerv3.Listener, irL
Tracing: hcmTracing,
}

// Add the proxy protocol filter if needed
patchProxyProtocolFilter(xdsListener, irListener)

if irListener.IsHTTP2 {
mgr.HttpFilters = append(mgr.HttpFilters, xdsfilters.GRPCWeb)
// always enable grpc stats filter
Expand Down
54 changes: 54 additions & 0 deletions internal/xds/translator/proxy_protocol.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright Envoy Gateway Authors
// SPDX-License-Identifier: Apache-2.0
// The full text of the Apache license is available in the LICENSE file at
// the root of the repo.

package translator

import (
listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
proxyprotocolv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/proxy_protocol/v3"
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
"google.golang.org/protobuf/types/known/anypb"

"github.com/envoyproxy/gateway/internal/ir"
)

// patchProxyProtocolFilter builds and appends the Proxy Protocol Filter to the
// HTTP Listener's Listener Filters if applicable.
func patchProxyProtocolFilter(xdsListener *listenerv3.Listener, irListener *ir.HTTPListener) {
// Return early if unset
if xdsListener == nil || irListener == nil || !irListener.EnableProxyProtocol {
return
}

// Return early if filter already exists.
for _, filter := range xdsListener.ListenerFilters {
if filter.Name == wellknown.ProxyProtocol {
return
}
}

proxyProtocolFilter := buildProxyProtocolFilter()

if proxyProtocolFilter != nil {
xdsListener.ListenerFilters = append(xdsListener.ListenerFilters, proxyProtocolFilter)
}
}

// buildProxypProtocolFilter returns a Proxy Protocol listener filter from the provided IR listener.
func buildProxyProtocolFilter() *listenerv3.ListenerFilter {
pp := &proxyprotocolv3.ProxyProtocol{}

ppAny, err := anypb.New(pp)
if err != nil {
return nil
}

return &listenerv3.ListenerFilter{
Name: wellknown.ProxyProtocol,
ConfigType: &listenerv3.ListenerFilter_TypedConfig{
TypedConfig: ppAny,
},
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
http:
- name: "first-listener"
address: "0.0.0.0"
port: 10080
hostnames:
- "foo.com"
tls:
- name: secret-1
# byte slice representation of "key-data"
serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
# byte slice representation of "key-data"
privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
- name: secret-2
serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
enableProxyProtocol: true
routes:
- name: "first-route"
hostname: "*"
destination:
name: "first-route-dest"
settings:
- endpoints:
- host: "1.2.3.4"
port: 50000
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- commonLbConfig:
localityWeightedLbConfig: {}
connectTimeout: 10s
dnsLookupFamily: V4_ONLY
edsClusterConfig:
edsConfig:
ads: {}
resourceApiVersion: V3
serviceName: first-route-dest
lbPolicy: LEAST_REQUEST
name: first-route-dest
outlierDetection: {}
perConnectionBufferLimitBytes: 32768
type: EDS
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
- clusterName: first-route-dest
endpoints:
- lbEndpoints:
- endpoint:
address:
socketAddress:
address: 1.2.3.4
portValue: 50000
loadBalancingWeight: 1
loadBalancingWeight: 1
locality:
region: first-route-dest/backend/0
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
- address:
socketAddress:
address: 0.0.0.0
portValue: 10080
filterChains:
- filterChainMatch:
serverNames:
- foo.com
filters:
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
commonHttpProtocolOptions:
headersWithUnderscoresAction: REJECT_REQUEST
http2ProtocolOptions:
initialConnectionWindowSize: 1048576
initialStreamWindowSize: 65536
maxConcurrentStreams: 100
httpFilters:
- name: envoy.filters.http.router
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
mergeSlashes: true
normalizePath: true
pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
rds:
configSource:
ads: {}
resourceApiVersion: V3
routeConfigName: first-listener
statPrefix: https
upgradeConfigs:
- upgradeType: websocket
useRemoteAddress: true
transportSocket:
name: envoy.transport_sockets.tls
typedConfig:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
commonTlsContext:
alpnProtocols:
- h2
- http/1.1
tlsCertificateSdsSecretConfigs:
- name: secret-1
sdsConfig:
ads: {}
resourceApiVersion: V3
- name: secret-2
sdsConfig:
ads: {}
resourceApiVersion: V3
listenerFilters:
- name: envoy.filters.listener.proxy_protocol
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.listener.proxy_protocol.v3.ProxyProtocol
- name: envoy.filters.listener.tls_inspector
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
name: first-listener
perConnectionBufferLimitBytes: 32768
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
- ignorePortInHostMatching: true
name: first-listener
virtualHosts:
- domains:
- '*'
name: first-listener/*
routes:
- match:
prefix: /
name: first-route
route:
cluster: first-route-dest
Loading

0 comments on commit ae523a8

Please sign in to comment.