mirror of
https://github.com/pomerium/pomerium.git
synced 2025-07-30 15:00:51 +02:00
envoy: support http2 prior knowledge for insecure upstream targets (#5205)
This allows using the scheme 'h2c' to indicate http2 prior knowledge for insecure upstream servers. This can be used to perform TLS termination for GRPC servers configured with insecure credentials. As an example, this allows the following route configuration: routes: - from: https://grpc.localhost.pomerium.io to: h2c://localhost:9090
This commit is contained in:
parent
554e77bc7c
commit
e3e7de741c
3 changed files with 224 additions and 25 deletions
102
config/envoyconfig/protocols_int_test.go
Normal file
102
config/envoyconfig/protocols_int_test.go
Normal file
|
@ -0,0 +1,102 @@
|
|||
package envoyconfig_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/interop"
|
||||
"google.golang.org/grpc/interop/grpc_testing"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/pomerium/pomerium/config"
|
||||
"github.com/pomerium/pomerium/pkg/cmd/pomerium"
|
||||
"github.com/pomerium/pomerium/pkg/netutil"
|
||||
)
|
||||
|
||||
func TestH2C(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
ctx, ca := context.WithCancel(context.Background())
|
||||
|
||||
opts := config.NewDefaultOptions()
|
||||
listener, err := (&net.ListenConfig{}).Listen(ctx, "tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
ports, err := netutil.AllocatePorts(7)
|
||||
require.NoError(t, err)
|
||||
urls, err := config.ParseWeightedUrls("http://"+listener.Addr().String(), "h2c://"+listener.Addr().String())
|
||||
require.NoError(t, err)
|
||||
opts.Addr = fmt.Sprintf("127.0.0.1:%s", ports[0])
|
||||
opts.Routes = []config.Policy{
|
||||
{
|
||||
From: fmt.Sprintf("https://grpc-http.localhost.pomerium.io:%s", ports[0]),
|
||||
To: urls[:1],
|
||||
AllowPublicUnauthenticatedAccess: true,
|
||||
},
|
||||
{
|
||||
From: fmt.Sprintf("https://grpc-h2c.localhost.pomerium.io:%s", ports[0]),
|
||||
To: urls[1:],
|
||||
AllowPublicUnauthenticatedAccess: true,
|
||||
},
|
||||
}
|
||||
opts.CertFile = "../../integration/tpl/files/trusted.pem"
|
||||
opts.KeyFile = "../../integration/tpl/files/trusted-key.pem"
|
||||
cfg := &config.Config{Options: opts}
|
||||
cfg.AllocatePorts(*(*[6]string)(ports[1:]))
|
||||
|
||||
server := grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
|
||||
grpc_testing.RegisterTestServiceServer(server, interop.NewTestServer())
|
||||
go server.Serve(listener)
|
||||
|
||||
errC := make(chan error, 1)
|
||||
go func() {
|
||||
errC <- pomerium.Run(ctx, config.NewStaticSource(cfg))
|
||||
}()
|
||||
|
||||
t.Cleanup(func() {
|
||||
ca()
|
||||
assert.ErrorIs(t, context.Canceled, <-errC)
|
||||
})
|
||||
|
||||
tlsConfig, err := credentials.NewClientTLSFromFile("../../integration/tpl/files/ca.pem", "")
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("h2c", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cc, err := grpc.Dial(fmt.Sprintf("grpc-h2c.localhost.pomerium.io:%s", ports[0]), grpc.WithTransportCredentials(tlsConfig))
|
||||
require.NoError(t, err)
|
||||
client := grpc_testing.NewTestServiceClient(cc)
|
||||
var md metadata.MD
|
||||
_, err = client.EmptyCall(ctx, &grpc_testing.Empty{}, grpc.WaitForReady(true), grpc.Header(&md))
|
||||
cc.Close()
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, md, "x-envoy-upstream-service-time")
|
||||
})
|
||||
t.Run("http", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cc, err := grpc.Dial(fmt.Sprintf("grpc-http.localhost.pomerium.io:%s", ports[0]), grpc.WithTransportCredentials(tlsConfig))
|
||||
require.NoError(t, err)
|
||||
client := grpc_testing.NewTestServiceClient(cc)
|
||||
var md metadata.MD
|
||||
_, err = client.EmptyCall(ctx, &grpc_testing.Empty{}, grpc.WaitForReady(true), grpc.Trailer(&md))
|
||||
cc.Close()
|
||||
stat := status.Convert(err)
|
||||
assert.NotNil(t, stat)
|
||||
assert.Equal(t, stat.Code(), codes.Unavailable)
|
||||
assert.NotContains(t, md, "x-envoy-upstream-service-time")
|
||||
assert.Contains(t, stat.Message(), "<!DOCTYPE html>")
|
||||
assert.Contains(t, stat.Message(), "upstream_reset_before_response_started{protocol_error}")
|
||||
})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue