Skip to content
This repository has been archived by the owner on Jul 11, 2023. It is now read-only.

Commit

Permalink
envoy/lds: Make outbound HTTP filter chain specific to HTTP traffic (#…
Browse files Browse the repository at this point in the history
…2101)

Currently, OSM only supports HTTP protocol, and as such the outbound
filter chain is specific to HTTP (via the HTTP filter). This change
renames the function and adds an additional filter chain match criteria
to the HTTP filter chain to be specific to HTTP protocols that the
downstream client is allowed to use for HTTP requests. Since OSM
only supports non TLS based HTTP request origination for in-mesh
traffic, the supported protocols are http/1.0, http/1.1,
h2c (HTTP2 without TLS, ex. grpc.Insecure()). HTTP2 over TLS (h2)
is not supported since OSM requires clients create HTTP requests
over plaintext, with OSM providing mTLS capability via proxy-proxy
communication.

The additional filter chain matching based on application protocols
should not affect the egress filter, given that destination IP
has a higher precedence over application protocols in the filter
chain match order. Egress traffic will not match the outbound
mesh filter chain because the destination IP of egress traffic
will not be a part of the in-mesh destination prefixes that get
programmed in the mesh filter chain.

This change is in preparation for supporting TCP traffic as a part
of #1521.

Signed-off-by: Shashank Ram <shashank08@gmail.com>
  • Loading branch information
shashankram authored Nov 20, 2020
1 parent b58a44f commit 68ab84d
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 12 deletions.
22 changes: 18 additions & 4 deletions pkg/envoy/lds/inmesh.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ const (
inboundMeshFilterChainName = "inbound-mesh-filter-chain"
)

var (
// supportedDownstreamHTTPProtocols is the list of allowed HTTP protocols that the
// downstream can use in an HTTP request. Since the downstream client is only allowed
// to send plaintext traffic to an in-mesh destinations, we do not include HTTP2 over
// TLS (h2) in this list.
supportedDownstreamHTTPProtocols = []string{"http/1.0", "http/1.1", "h2c"}
)

func getInboundInMeshFilterChain(proxyServiceName service.MeshService, cfg configurator.Configurator) (*xds_listener.FilterChain, error) {
marshalledDownstreamTLSContext, err := envoy.MessageToAny(envoy.GetDownstreamTLSContext(proxyServiceName, true /* mTLS */))
if err != nil {
Expand Down Expand Up @@ -86,10 +94,16 @@ func getOutboundFilterForService(dstSvc service.MeshService, cfg configurator.Co
}, nil
}

// getOutboundFilterChainMatchForService builds a filter chain to match the destination traffic.
// Filter Chain currently match on destination IP for possible service endpoints
func getOutboundFilterChainMatchForService(dstSvc service.MeshService, catalog catalog.MeshCataloger, cfg configurator.Configurator) (*xds_listener.FilterChainMatch, error) {
filterMatch := &xds_listener.FilterChainMatch{}
// getOutboundHTTPFilterChainMatchForService builds a filter chain to match the HTTP baseddestination traffic.
// Filter Chain currently matches on the following:
// 1. Destination IP of service endpoints
// 2. HTTP application protocols
func getOutboundHTTPFilterChainMatchForService(dstSvc service.MeshService, catalog catalog.MeshCataloger, cfg configurator.Configurator) (*xds_listener.FilterChainMatch, error) {
filterMatch := &xds_listener.FilterChainMatch{
// HTTP filter chain should only match on supported HTTP protocols that the downstream can use
// to originate a request.
ApplicationProtocols: supportedDownstreamHTTPProtocols,
}

endpoints, err := catalog.GetResolvableServiceEndpoints(dstSvc)
if err != nil {
Expand Down
7 changes: 6 additions & 1 deletion pkg/envoy/lds/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ func newOutboundListener(catalog catalog.MeshCataloger, cfg configurator.Configu
// to its original destination.
Name: wellknown.OriginalDestination,
},
{
// The HttpInspector ListenerFilter is used to inspect plaintext traffic
// for HTTP protocols.
Name: wellknown.HttpInspector,
},
},
}, nil
}
Expand Down Expand Up @@ -155,7 +160,7 @@ func getOutboundFilterChains(catalog catalog.MeshCataloger, cfg configurator.Con
}

// Get filter match criteria for destination service
filterChainMatch, err := getOutboundFilterChainMatchForService(keyService, catalog, cfg)
filterChainMatch, err := getOutboundHTTPFilterChainMatchForService(keyService, catalog, cfg)
if err != nil {
log.Error().Err(err).Msgf("Error getting Chain Match for service %s", keyService.String())
return nil, err
Expand Down
33 changes: 26 additions & 7 deletions pkg/envoy/lds/listener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import (
"testing"

xds_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
xds_listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
xds_hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
"github.com/golang/mock/gomock"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/stretchr/testify/assert"
"google.golang.org/protobuf/types/known/wrapperspb"

"github.com/openservicemesh/osm/pkg/catalog"
"github.com/openservicemesh/osm/pkg/configurator"
Expand Down Expand Up @@ -69,21 +71,38 @@ func TestGetFilterChainMatchForService(t *testing.T) {
nil,
)

filterChainMatch, err := getOutboundFilterChainMatchForService(tests.BookbuyerService, mockCatalog, mockConfigurator)
filterChainMatch, err := getOutboundHTTPFilterChainMatchForService(tests.BookbuyerService, mockCatalog, mockConfigurator)

assert.NoError(err)
assert.Equal(filterChainMatch.PrefixRanges[0].GetAddressPrefix(), tests.Endpoint.IP.String())
assert.Equal(filterChainMatch.PrefixRanges[0].GetPrefixLen().GetValue(), uint32(32))
assert.Equal(filterChainMatch.PrefixRanges[1].GetAddressPrefix(), net.IPv4(192, 168, 0, 1).String())
assert.Equal(filterChainMatch.PrefixRanges[1].GetPrefixLen().GetValue(), uint32(32))

// Test negative getOutboundFilterChainMatchForService when no endpoints are present
expectedFilterChainMatch := &xds_listener.FilterChainMatch{
// HTTP filter chain should only match on supported HTTP protocols that the downstream can use
// to originate a request.
ApplicationProtocols: []string{"http/1.0", "http/1.1", "h2c"},
PrefixRanges: []*xds_core.CidrRange{
{
AddressPrefix: tests.Endpoint.IP.String(),
PrefixLen: &wrapperspb.UInt32Value{
Value: 32,
},
},
{
AddressPrefix: "192.168.0.1",
PrefixLen: &wrapperspb.UInt32Value{
Value: 32,
},
},
},
}
assert.Equal(filterChainMatch, expectedFilterChainMatch)

// Test negative getOutboundHTTPFilterChainMatchForService when no endpoints are present
mockCatalog.EXPECT().GetResolvableServiceEndpoints(tests.BookbuyerService).Return(
[]endpoint.Endpoint{},
nil,
)

filterChainMatch, err = getOutboundFilterChainMatchForService(tests.BookbuyerService, mockCatalog, mockConfigurator)
filterChainMatch, err = getOutboundHTTPFilterChainMatchForService(tests.BookbuyerService, mockCatalog, mockConfigurator)
assert.NoError(err)
assert.Nil(filterChainMatch)
}
Expand Down

0 comments on commit 68ab84d

Please sign in to comment.