Skip to content

Commit

Permalink
internal/dag: Set SNI on upstream externalName type clusters for TCPP…
Browse files Browse the repository at this point in the history
…roxy (#3291)

Sets the SNI on any TCPProxy.Service which references an externalName type service as well as having the upstream protocol of "tls".

Updates #2517

Signed-off-by: Steve Sloka <[email protected]>
  • Loading branch information
stevesloka authored Feb 18, 2021
1 parent e3a2775 commit 4ddb326
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 1 deletion.
58 changes: 58 additions & 0 deletions internal/dag/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4076,6 +4076,28 @@ func TestDAGInsert(t *testing.T) {
},
}

tcpProxyExternalNameService := &contour_api_v1.HTTPProxy{
ObjectMeta: metav1.ObjectMeta{
Name: "example-com",
Namespace: "default",
},
Spec: contour_api_v1.HTTPProxySpec{
VirtualHost: &contour_api_v1.VirtualHost{
Fqdn: "example.com",
TLS: &contour_api_v1.TLS{
SecretName: sec1.Name,
},
},
TCPProxy: &contour_api_v1.TCPProxy{
Services: []contour_api_v1.Service{{
Name: s14.GetName(),
Port: 80,
Protocol: pointer.StringPtr("tls"),
}},
},
},
}

tests := map[string]struct {
objs []interface{}
disablePermitInsecure bool
Expand Down Expand Up @@ -7211,6 +7233,42 @@ func TestDAGInsert(t *testing.T) {
},
),
},
"insert tcp proxy with externalName service": {
objs: []interface{}{
tcpProxyExternalNameService,
s14,
sec1,
},
want: listeners(
&Listener{
Port: 443,
VirtualHosts: virtualhosts(
&SecureVirtualHost{
VirtualHost: VirtualHost{
Name: "example.com",
},
TCPProxy: &TCPProxy{
Clusters: []*Cluster{{
Upstream: &Service{
ExternalName: "externalservice.io",
Weighted: WeightedService{
Weight: 1,
ServiceName: s14.Name,
ServiceNamespace: s14.Namespace,
ServicePort: s14.Spec.Ports[0],
},
},
Protocol: "tls",
SNI: "externalservice.io",
}},
},
MinTLSVersion: "1.2",
Secret: secret(sec1),
},
),
},
),
},
"insert proxy with replace header policy - route - host header": {
objs: []interface{}{
proxyReplaceHostHeaderRoute,
Expand Down
11 changes: 10 additions & 1 deletion internal/dag/httpproxy_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -678,11 +678,20 @@ func (p *HTTPProxyProcessor) processHTTPProxyTCPProxy(validCond *contour_api_v1.
"Spec.TCPProxy unresolved service reference: %s", err)
return false
}

// Determine the protocol to use to speak to this Cluster.
protocol, err := getProtocol(service, s)
if err != nil {
validCond.AddError(contour_api_v1.ConditionTypeServiceError, "UnsupportedProtocol", err.Error())
return false
}

proxy.Clusters = append(proxy.Clusters, &Cluster{
Upstream: s,
Protocol: s.Protocol,
Protocol: protocol,
LoadBalancerPolicy: lbPolicy,
TCPHealthCheckPolicy: tcpHealthCheckPolicy(tcpproxy.HealthCheckPolicy),
SNI: s.ExternalName,
})
}
secure := p.dag.EnsureSecureVirtualHost(host)
Expand Down
43 changes: 43 additions & 0 deletions internal/featuretests/v3/externalname_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package v3
import (
"testing"

"github.com/projectcontour/contour/internal/featuretests"

envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
envoy_extensions_upstream_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/upstreams/http/v3"
Expand Down Expand Up @@ -276,4 +278,45 @@ func TestExternalNameService(t *testing.T) {
),
),
})

sec1 := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "secret",
Namespace: "default",
},
Type: "kubernetes.io/tls",
Data: featuretests.Secretdata(featuretests.CERTIFICATE, featuretests.RSA_PRIVATE_KEY),
}

// Create TCPProxy with upstream protocol 'tls' to an externalName type service
// and verify that the SNI on the upstream request matches the externalName value.
rh.OnDelete(fixture.NewProxy("kuard").WithSpec(contour_api_v1.HTTPProxySpec{}))
rh.OnAdd(sec1)
rh.OnAdd(fixture.NewProxy("kuard").
WithFQDN("kuard.projectcontour.io").
WithCertificate(sec1.Name).
WithSpec(contour_api_v1.HTTPProxySpec{
TCPProxy: &contour_api_v1.TCPProxy{
Services: []contour_api_v1.Service{{
Protocol: pointer.StringPtr("tls"),
Name: s1.Name,
Port: 80,
}},
},
}),
)

c.Request(clusterType).Equals(&envoy_discovery_v3.DiscoveryResponse{
TypeUrl: clusterType,
Resources: resources(t,
DefaultCluster(
externalNameCluster("default/kuard/80/da39a3ee5e", "default/kuard", "default_kuard_80", "foo.io", 80),
&envoy_cluster_v3.Cluster{
TransportSocket: envoy_v3.UpstreamTLSTransportSocket(
envoy_v3.UpstreamTLSContext(nil, "foo.io", nil),
),
},
),
),
})
}

0 comments on commit 4ddb326

Please sign in to comment.