From 2efdcc0f0d6449e4b1a2b0f744b80aea2a97627f Mon Sep 17 00:00:00 2001 From: James Peach Date: Wed, 29 Apr 2020 16:56:36 +1000 Subject: [PATCH] internal: filter misdirected TLS requests TLS routes are specialized to a unique virtual hostname. However, if wildcard certificates are being used, browsers will aggressively coalesce and reuse server connections even when the full origin hostname doesn't match. This results on 404 responses because each TLS virtual host only has routes for one host. We can avoid this behaviour bleeding out to users by generating a 421 Misdirected Request response if the request authority doesn't match the FQDN of the virtual host. In this case, the browser is supposed to understand that the request wasn't processed and re-send it on a new connection. This fixes #1493. Signed-off-by: James Peach --- .../009-https-misdirected-request.yaml | 204 ++++++++++++++++++ .../testsuite/policies/contour-resources.rego | 11 + internal/contour/listener.go | 3 + internal/contour/listener_test.go | 4 + internal/e2e/lds_test.go | 82 ++----- internal/envoy/listener.go | 59 ++++- .../featuretests/downstreamvalidation_test.go | 7 +- internal/featuretests/envoy.go | 11 + .../tlscertificatedelegation_test.go | 7 +- .../featuretests/tlsprotocolversion_test.go | 15 +- site/_resources/envoy.md | 2 +- 11 files changed, 313 insertions(+), 92 deletions(-) create mode 100644 _integration/testsuite/httpproxy/009-https-misdirected-request.yaml diff --git a/_integration/testsuite/httpproxy/009-https-misdirected-request.yaml b/_integration/testsuite/httpproxy/009-https-misdirected-request.yaml new file mode 100644 index 00000000000..270630dcc74 --- /dev/null +++ b/_integration/testsuite/httpproxy/009-https-misdirected-request.yaml @@ -0,0 +1,204 @@ +# Copyright 2020 VMware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import data.contour.resources + +# Ensure that cert-manager is installed. +# Version check the certificates resource. + +Group := "cert-manager.io" +Version := "v1alpha2" + +have_certmanager_version { + v := resources.versions["certificates"] + v[_].Group == Group + v[_].Version == Version +} + +skip[msg] { + not resources.is_supported("certificates") + msg := "cert-manager is not installed" +} + +skip[msg] { + not have_certmanager_version + + avail := resources.versions["certificates"] + + msg := concat("\n", [ + sprintf("cert-manager version %s/%s is not installed", [Group, Version]), + "available versions:", + yaml.marshal(avail) + ]) +} + +--- + +# Create a self-signed issuer to give us secrets. + +apiVersion: cert-manager.io/v1alpha2 +kind: Issuer +metadata: + name: selfsigned +spec: + selfSigned: {} + +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ingress-conformance-echo +$apply: + fixture: + as: echo + +--- + +apiVersion: v1 +kind: Service +metadata: + name: ingress-conformance-echo +$apply: + fixture: + as: echo + +--- + +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: echo-cert +spec: + dnsNames: + - echo.projectcontour.io + secretName: echo + issuerRef: + name: selfsigned + +--- + +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: echo +spec: + virtualhost: + fqdn: echo.projectcontour.io + tls: + secretName: echo + routes: + - services: + - name: echo + port: 80 + +--- + +import data.contour.resources + +Name := "echo" + +fatal_proxy_is_not_present[msg] { + not resources.is_present("httpproxies", Name) + msg := sprintf("HTTPProxy for %q is not present", [ Name ]) +} + +--- + +import data.contour.resources + +Name := "echo" + +fatal_proxy_is_not_valid[msg] { + status := resources.status("httpproxies", Name) + + object.get(status, "currentStatus", "") != "valid" + + msg := sprintf("HTTPProxy %q is not valid\n%s", [ + Name, yaml.marshal(status) + ]) +} + +--- + +import data.contour.http.client +import data.contour.http.request +import data.contour.http.response + +Response := client.Get({ + "url": sprintf("https://%s/misdirected/%d", [ + client.target_addr, time.now_ns() + ]), + "headers": { + "Host": "echo.projectcontour.io", + "User-Agent": client.ua("misdirected-request"), + }, + "tls_insecure_skip_verify": true, +}) + +error_non_200_response [msg] { + not Response + msg := "no response" +} + +error_non_200_response [msg] { + status := object.get(Response, "status_code", 000) + status != 200 + msg := sprintf("got status %d, wanted %d", [status, 200]) +} + +error_wrong_routing [msg] { + not response.has_testid(Response) + msg := "response has missing body or test ID" +} + +error_wrong_routing[msg] { + wanted := "echo" + testid := response.testid(Response) + testid != wanted + msg := sprintf("got test ID %q, wanted %q", [testid, wanted]) +} + +--- + +import data.contour.http.client +import data.contour.http.request +import data.contour.http.response + +# Send a request with a Host header that doesn't match the SNI name that +# we have for the proxy document. We expect the mismatch will generate a +# 421 respnse, not 404. + +Response := client.Get({ + "url": sprintf("https://%s/misdirected/%d", [ + client.target_addr, time.now_ns() + ]), + "headers": { + "Host": "echo-two.projectcontour.io", + "User-Agent": client.ua("misdirected-request"), + }, + "tls_server_name": "echo.projectcontour.io", + "tls_insecure_skip_verify": true, +}) + +error_non_421_response [msg] { + not Response + msg := "no response" +} + +error_non_421_response [msg] { + status := object.get(Response, "status_code", 000) + status != 421 + msg := sprintf("got status %d, wanted %d", [status, 421]) +} diff --git a/_integration/testsuite/policies/contour-resources.rego b/_integration/testsuite/policies/contour-resources.rego index dab9af2cb53..ade42935b55 100644 --- a/_integration/testsuite/policies/contour-resources.rego +++ b/_integration/testsuite/policies/contour-resources.rego @@ -81,3 +81,14 @@ get(resource, name) = obj { } else = obj { obj := {} } + +# status returns the status field of the named resource. If the resource +# is not present, and empty object is returned. Implemented in terms of +# 'get', so namespace syntax works for the object name. +# +# Examples: +# resources.status("httpproxies", "foo") +status(resource, name) = s { + r := get(resource, name) + s := object.get(r, "status", {}) +} diff --git a/internal/contour/listener.go b/internal/contour/listener.go index c1331aba4cc..55031df1378 100644 --- a/internal/contour/listener.go +++ b/internal/contour/listener.go @@ -298,6 +298,7 @@ func visitListeners(root dag.Vertex, lvc *ListenerVisitorConfig) map[string]*v2. if lv.http { // Add a listener if there are vhosts bound to http. cm := envoy.HTTPConnectionManagerBuilder(). + DefaultFilters(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(lvc.newInsecureAccessLog()). @@ -366,6 +367,8 @@ func (v *listenerVisitor) visit(vertex dag.Vertex) { // coded into monitoring dashboards. filters = envoy.Filters( envoy.HTTPConnectionManagerBuilder(). + AddFilter(envoy.FilterMisdirectedRequests(vh.VirtualHost.Name)). + DefaultFilters(). RouteConfigName(path.Join("https", vh.VirtualHost.Name)). MetricsPrefix(ENVOY_HTTPS_LISTENER). AccessLoggers(v.ListenerVisitorConfig.newSecureAccessLog()). diff --git a/internal/contour/listener_test.go b/internal/contour/listener_test.go index 2d970392224..237a2d401aa 100644 --- a/internal/contour/listener_test.go +++ b/internal/contour/listener_test.go @@ -129,6 +129,8 @@ func TestListenerCacheQuery(t *testing.T) { func TestListenerVisit(t *testing.T) { httpsFilterFor := func(vhost string) *envoy_api_v2_listener.Filter { return envoy.HTTPConnectionManagerBuilder(). + AddFilter(envoy.FilterMisdirectedRequests(vhost)). + DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). RouteConfigName(path.Join("https", vhost)). AccessLoggers(envoy.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG)). @@ -790,6 +792,8 @@ func TestListenerVisit(t *testing.T) { }, TransportSocket: transportSocket("secret", envoy_api_v2_auth.TlsParameters_TLSv1_1, "h2", "http/1.1"), Filters: envoy.Filters(envoy.HTTPConnectionManagerBuilder(). + AddFilter(envoy.FilterMisdirectedRequests("whatever.example.com")). + DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). RouteConfigName(path.Join("https", "whatever.example.com")). AccessLoggers(envoy.FileAccessLogEnvoy("/tmp/https_access.log")). diff --git a/internal/e2e/lds_test.go b/internal/e2e/lds_test.go index eee60075bc5..2dbcc1b02eb 100644 --- a/internal/e2e/lds_test.go +++ b/internal/e2e/lds_test.go @@ -15,6 +15,7 @@ package e2e import ( "context" + "path" "testing" v2 "github.com/envoyproxy/go-control-plane/envoy/api/v2" @@ -32,6 +33,16 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" ) +func httpsFilterFor(vhost string) *envoy_api_v2_listener.Filter { + return envoy.HTTPConnectionManagerBuilder(). + AddFilter(envoy.FilterMisdirectedRequests(vhost)). + DefaultFilters(). + RouteConfigName(path.Join("https", vhost)). + MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). + AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). + Get() +} + func TestNonTLSListener(t *testing.T) { rh, cc, done := setup(t) defer done() @@ -227,11 +238,7 @@ func TestTLSListener(t *testing.T) { envoy.TLSInspector(), ), FilterChains: filterchaintls("kuard.example.com", s1, - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/kuard.example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), + httpsFilterFor("kuard.example.com"), "h2", "http/1.1"), }, staticListener(), @@ -279,11 +286,7 @@ func TestTLSListener(t *testing.T) { envoy.TLSInspector(), ), FilterChains: filterchaintls("kuard.example.com", s1, - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/kuard.example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), + httpsFilterFor("kuard.example.com"), "h2", "http/1.1"), }, staticListener(), @@ -400,11 +403,7 @@ func TestIngressRouteTLSListener(t *testing.T) { envoy.TLSInspector(), ), FilterChains: filterchaintls("kuard.example.com", secret1, - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/kuard.example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), + httpsFilterFor("kuard.example.com"), "h2", "http/1.1"), } @@ -460,13 +459,7 @@ func TestIngressRouteTLSListener(t *testing.T) { envoy_api_v2_auth.TlsParameters_TLSv1_3, nil, "h2", "http/1.1"), - envoy.Filters( - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/kuard.example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), - ), + envoy.Filters(httpsFilterFor("kuard.example.com")), ), }, } @@ -558,11 +551,7 @@ func TestLDSFilter(t *testing.T) { envoy.TLSInspector(), ), FilterChains: filterchaintls("kuard.example.com", s1, - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/kuard.example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), + httpsFilterFor("kuard.example.com"), "h2", "http/1.1"), }, ), @@ -747,11 +736,7 @@ func TestLDSIngressHTTPSUseProxyProtocol(t *testing.T) { envoy.TLSInspector(), ), FilterChains: filterchaintls("kuard.example.com", s1, - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/kuard.example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), + httpsFilterFor("kuard.example.com"), "h2", "http/1.1"), } assert.Equal(t, &v2.DiscoveryResponse{ @@ -861,13 +846,7 @@ func TestLDSCustomAddressAndPort(t *testing.T) { envoy.TLSInspector(), ), FilterChains: filterchaintls("kuard.example.com", s1, - - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/kuard.example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), - + httpsFilterFor("kuard.example.com"), "h2", "http/1.1"), } assert.Equal(t, &v2.DiscoveryResponse{ @@ -967,11 +946,12 @@ func TestLDSCustomAccessLogPaths(t *testing.T) { ), FilterChains: filterchaintls("kuard.example.com", s1, envoy.HTTPConnectionManagerBuilder(). + AddFilter(envoy.FilterMisdirectedRequests("kuard.example.com")). + DefaultFilters(). RouteConfigName("https/kuard.example.com"). MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). AccessLoggers(envoy.FileAccessLogEnvoy("/tmp/https_access.log")). Get(), - "h2", "http/1.1"), } assert.Equal(t, &v2.DiscoveryResponse{ @@ -1071,11 +1051,7 @@ func TestIngressRouteHTTPS(t *testing.T) { envoy.TLSInspector(), ), FilterChains: filterchaintls("example.com", s1, - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), + httpsFilterFor("example.com"), "h2", "http/1.1"), } assert.Equal(t, &v2.DiscoveryResponse{ @@ -1162,13 +1138,7 @@ func TestIngressRouteMinimumTLSVersion(t *testing.T) { envoy_api_v2_auth.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - envoy.Filters( - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/kuard.example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), - ), + envoy.Filters(httpsFilterFor("kuard.example.com")), ), }, } @@ -1230,13 +1200,7 @@ func TestIngressRouteMinimumTLSVersion(t *testing.T) { envoy_api_v2_auth.TlsParameters_TLSv1_3, nil, "h2", "http/1.1"), - envoy.Filters( - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/kuard.example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), - ), + envoy.Filters(httpsFilterFor("kuard.example.com")), ), }, } diff --git a/internal/envoy/listener.go b/internal/envoy/listener.go index ab14490200a..54a6c0fd40e 100644 --- a/internal/envoy/listener.go +++ b/internal/envoy/listener.go @@ -14,6 +14,7 @@ package envoy import ( + "fmt" "sort" "time" @@ -22,6 +23,7 @@ import ( envoy_api_v2_core "github.com/envoyproxy/go-control-plane/envoy/api/v2/core" envoy_api_v2_listener "github.com/envoyproxy/go-control-plane/envoy/api/v2/listener" accesslog "github.com/envoyproxy/go-control-plane/envoy/config/filter/accesslog/v2" + lua "github.com/envoyproxy/go-control-plane/envoy/config/filter/http/lua/v2" http "github.com/envoyproxy/go-control-plane/envoy/config/filter/network/http_connection_manager/v2" tcp "github.com/envoyproxy/go-control-plane/envoy/config/filter/network/tcp_proxy/v2" "github.com/envoyproxy/go-control-plane/pkg/wellknown" @@ -67,6 +69,7 @@ type httpConnectionManagerBuilder struct { metricsPrefix string accessLoggers []*accesslog.AccessLog requestTimeout time.Duration + filters []*http.HttpFilter } // RouteConfigName sets the name of the RDS element that contains @@ -99,6 +102,27 @@ func (b *httpConnectionManagerBuilder) RequestTimeout(timeout time.Duration) *ht return b } +func (b *httpConnectionManagerBuilder) DefaultFilters() *httpConnectionManagerBuilder { + b.filters = append(b.filters, + &http.HttpFilter{ + Name: wellknown.Gzip, + }, + &http.HttpFilter{ + Name: wellknown.GRPCWeb, + }, + &http.HttpFilter{ + Name: wellknown.Router, + }, + ) + + return b +} + +func (b *httpConnectionManagerBuilder) AddFilter(f *http.HttpFilter) *httpConnectionManagerBuilder { + b.filters = append(b.filters, f) + return b +} + // Get returns a new http.HttpConnectionManager filter, constructed // from the builder settings. // @@ -111,13 +135,7 @@ func (b *httpConnectionManagerBuilder) Get() *envoy_api_v2_listener.Filter { ConfigSource: ConfigSource("contour"), }, }, - HttpFilters: []*http.HttpFilter{{ - Name: wellknown.Gzip, - }, { - Name: wellknown.GRPCWeb, - }, { - Name: wellknown.Router, - }}, + HttpFilters: b.filters, CommonHttpProtocolOptions: &envoy_api_v2_core.HttpProtocolOptions{ // Sets the idle timeout for HTTP connections to 60 seconds. // This is chosen as a rough default to stop idle connections wasting resources, @@ -166,6 +184,7 @@ func HTTPConnectionManager(routename string, accesslogger []*accesslog.AccessLog MetricsPrefix(routename). AccessLoggers(accesslogger). RequestTimeout(requestTimeout). + DefaultFilters(). Get() } @@ -281,6 +300,32 @@ func FilterChains(filters ...*envoy_api_v2_listener.Filter) []*envoy_api_v2_list } } +func FilterMisdirectedRequests(fqdn string) *http.HttpFilter { + code := ` +function envoy_on_request(request_handle) + local headers = request_handle:headers() + local host = headers:get(":authority") + + if host ~= "%s" then + request_handle:respond({ + [":status"] = "421", + }, + "" + ) + end +end +` + + return &http.HttpFilter{ + Name: "envoy.filters.http.lua", + ConfigType: &http.HttpFilter_TypedConfig{ + TypedConfig: protobuf.MustMarshalAny(&lua.Lua{ + InlineCode: fmt.Sprintf(code, fqdn), + }), + }, + } +} + // FilterChainTLS returns a TLS enabled envoy_api_v2_listener.FilterChain. func FilterChainTLS(domain string, downstream *envoy_api_v2_auth.DownstreamTlsContext, filters []*envoy_api_v2_listener.Filter) *envoy_api_v2_listener.FilterChain { fc := &envoy_api_v2_listener.FilterChain{ diff --git a/internal/featuretests/downstreamvalidation_test.go b/internal/featuretests/downstreamvalidation_test.go index cdf601092cd..16c2b7cba5d 100644 --- a/internal/featuretests/downstreamvalidation_test.go +++ b/internal/featuretests/downstreamvalidation_test.go @@ -18,7 +18,6 @@ import ( v2 "github.com/envoyproxy/go-control-plane/envoy/api/v2" projcontour "github.com/projectcontour/contour/apis/projectcontour/v1" - "github.com/projectcontour/contour/internal/contour" "github.com/projectcontour/contour/internal/dag" "github.com/projectcontour/contour/internal/envoy" "github.com/projectcontour/contour/internal/fixture" @@ -105,11 +104,7 @@ func TestDownstreamTLSCertificateValidation(t *testing.T) { envoy.TLSInspector(), ), FilterChains: filterchaintls("example.com", serverTLSSecret, - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), + httpsFilterFor("example.com"), &dag.PeerValidationContext{ CACertificate: &dag.Secret{ Object: clientCASecret, diff --git a/internal/featuretests/envoy.go b/internal/featuretests/envoy.go index 77d6312d155..a3f6de9aab5 100644 --- a/internal/featuretests/envoy.go +++ b/internal/featuretests/envoy.go @@ -16,6 +16,7 @@ package featuretests // envoy helpers import ( + "path" "time" v2 "github.com/envoyproxy/go-control-plane/envoy/api/v2" @@ -233,6 +234,16 @@ func filterchaintls(domain string, secret *v1.Secret, filter *envoy_api_v2_liste } } +func httpsFilterFor(vhost string) *envoy_api_v2_listener.Filter { + return envoy.HTTPConnectionManagerBuilder(). + AddFilter(envoy.FilterMisdirectedRequests(vhost)). + DefaultFilters(). + RouteConfigName(path.Join("https", vhost)). + MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). + AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). + Get() +} + func tcpproxy(statPrefix, cluster string) *envoy_api_v2_listener.Filter { return &envoy_api_v2_listener.Filter{ Name: wellknown.TCPProxy, diff --git a/internal/featuretests/tlscertificatedelegation_test.go b/internal/featuretests/tlscertificatedelegation_test.go index e5376f98327..a4959dd951a 100644 --- a/internal/featuretests/tlscertificatedelegation_test.go +++ b/internal/featuretests/tlscertificatedelegation_test.go @@ -19,7 +19,6 @@ import ( v2 "github.com/envoyproxy/go-control-plane/envoy/api/v2" ingressroutev1 "github.com/projectcontour/contour/apis/contour/v1beta1" projcontour "github.com/projectcontour/contour/apis/projectcontour/v1" - "github.com/projectcontour/contour/internal/contour" "github.com/projectcontour/contour/internal/envoy" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -128,11 +127,7 @@ func TestTLSCertificateDelegation(t *testing.T) { envoy.TLSInspector(), ), FilterChains: filterchaintls("example.com", sec1, - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), + httpsFilterFor("example.com"), nil, "h2", "http/1.1"), } diff --git a/internal/featuretests/tlsprotocolversion_test.go b/internal/featuretests/tlsprotocolversion_test.go index 74ea408262e..1047ae6140b 100644 --- a/internal/featuretests/tlsprotocolversion_test.go +++ b/internal/featuretests/tlsprotocolversion_test.go @@ -21,7 +21,6 @@ import ( envoy_api_v2_listener "github.com/envoyproxy/go-control-plane/envoy/api/v2/listener" ingressroutev1 "github.com/projectcontour/contour/apis/contour/v1beta1" projcontour "github.com/projectcontour/contour/apis/projectcontour/v1" - "github.com/projectcontour/contour/internal/contour" "github.com/projectcontour/contour/internal/dag" "github.com/projectcontour/contour/internal/envoy" v1 "k8s.io/api/core/v1" @@ -91,11 +90,7 @@ func TestTLSMinimumProtocolVersion(t *testing.T) { envoy.TLSInspector(), ), FilterChains: filterchaintls("kuard.example.com", sec1, - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/kuard.example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), + httpsFilterFor("kuard.example.com"), nil, "h2", "http/1.1"), }, @@ -144,13 +139,7 @@ func TestTLSMinimumProtocolVersion(t *testing.T) { envoy_api_v2_auth.TlsParameters_TLSv1_3, nil, "h2", "http/1.1"), - envoy.Filters( - envoy.HTTPConnectionManagerBuilder(). - RouteConfigName("https/kuard.example.com"). - MetricsPrefix(contour.ENVOY_HTTPS_LISTENER). - AccessLoggers(envoy.FileAccessLogEnvoy("/dev/stdout")). - Get(), - ), + envoy.Filters(httpsFilterFor("kuard.example.com")), ), }, } diff --git a/site/_resources/envoy.md b/site/_resources/envoy.md index 4a239c93354..8592d39340a 100644 --- a/site/_resources/envoy.md +++ b/site/_resources/envoy.md @@ -34,7 +34,7 @@ If you are using the image recommended in our [example deployment][3] no action If you are providing your own Envoy it must be compiled with the following extensions: - `access_loggers`: `envoy.access_loggers.file`,`envoy.access_loggers.http_grpc`,`envoy.access_loggers.tcp_grpc` -- `filters.http`: `envoy.buffer`,`envoy.cors`,`envoy.csrf`,`envoy.fault`,`envoy.filters.http.adaptive_concurrency`,`envoy.filters.http.dynamic_forward_proxy`,`envoy.filters.http.grpc_http1_reverse_bridge`,`envoy.filters.http.grpc_stats`,`envoy.filters.http.header_to_metadata`,`envoy.filters.http.original_src`,`envoy.grpc_http1_bridge`,`envoy.grpc_json_transcoder`,`envoy.grpc_web`,`envoy.gzip`,`envoy.health_check`,`envoy.ip_tagging`,`envoy.router` +- `filters.http`: `envoy.buffer`, `envoy.cors`, `envoy.csrf`, `envoy.fault`, `envoy.filters.http.adaptive_concurrency`, `envoy.filters.http.dynamic_forward_proxy`, `envoy.filters.http.grpc_http1_reverse_bridge`, `envoy.filters.http.grpc_stats`, `envoy.filters.http.header_to_metadata`, `envoy.filters.http.lua`, `envoy.filters.http.original_src`, `envoy.grpc_http1_bridge`, `envoy.grpc_json_transcoder`, `envoy.grpc_web`, `envoy.gzip`, `envoy.health_check`, `envoy.ip_tagging`, `envoy.router` - `filters.listener`: `envoy.listener.http_inspector`,`envoy.listener.original_dst`,`envoy.listener.original_src`,`envoy.listener.proxy_protocol`,`envoy.listener.tls_inspector` - `filters.network`: `envoy.echo`,`envoy.filters.network.sni_cluster`,`envoy.http_connection_manager`,`envoy.tcp_proxy` - `stat_sinks`: `envoy.metrics_service`