mirror of
https://github.com/pomerium/pomerium.git
synced 2025-07-18 00:58:08 +02:00
use envoy for http redirect server
This commit is contained in:
parent
04585af9ef
commit
d04de59be5
12 changed files with 208 additions and 102 deletions
|
@ -44,6 +44,8 @@ type Config struct {
|
||||||
MetricsPort string
|
MetricsPort string
|
||||||
// DebugPort is the port the debug listener is running on.
|
// DebugPort is the port the debug listener is running on.
|
||||||
DebugPort string
|
DebugPort string
|
||||||
|
// ACMEHTTPPort is the port that handles the ACME HTTP challenge.
|
||||||
|
ACMEHTTPPort string
|
||||||
// ACMETLSPort is the port that handles the ACME TLS-ALPN challenge.
|
// ACMETLSPort is the port that handles the ACME TLS-ALPN challenge.
|
||||||
ACMETLSALPNPort string
|
ACMETLSALPNPort string
|
||||||
|
|
||||||
|
@ -78,6 +80,7 @@ func (cfg *Config) Clone() *Config {
|
||||||
OutboundPort: cfg.OutboundPort,
|
OutboundPort: cfg.OutboundPort,
|
||||||
MetricsPort: cfg.MetricsPort,
|
MetricsPort: cfg.MetricsPort,
|
||||||
DebugPort: cfg.DebugPort,
|
DebugPort: cfg.DebugPort,
|
||||||
|
ACMEHTTPPort: cfg.ACMEHTTPPort,
|
||||||
ACMETLSALPNPort: cfg.ACMETLSALPNPort,
|
ACMETLSALPNPort: cfg.ACMETLSALPNPort,
|
||||||
|
|
||||||
MetricsScrapeEndpoints: endpoints,
|
MetricsScrapeEndpoints: endpoints,
|
||||||
|
@ -134,13 +137,14 @@ func (cfg *Config) Checksum() uint64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AllocatePorts populates
|
// AllocatePorts populates
|
||||||
func (cfg *Config) AllocatePorts(ports [6]string) {
|
func (cfg *Config) AllocatePorts(ports [7]string) {
|
||||||
cfg.GRPCPort = ports[0]
|
cfg.GRPCPort = ports[0]
|
||||||
cfg.HTTPPort = ports[1]
|
cfg.HTTPPort = ports[1]
|
||||||
cfg.OutboundPort = ports[2]
|
cfg.OutboundPort = ports[2]
|
||||||
cfg.MetricsPort = ports[3]
|
cfg.MetricsPort = ports[3]
|
||||||
cfg.DebugPort = ports[4]
|
cfg.DebugPort = ports[4]
|
||||||
cfg.ACMETLSALPNPort = ports[5]
|
cfg.ACMEHTTPPort = ports[5]
|
||||||
|
cfg.ACMETLSALPNPort = ports[6]
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTLSClientConfig returns TLS configuration that accounts for additional CA entries
|
// GetTLSClientConfig returns TLS configuration that accounts for additional CA entries
|
||||||
|
|
|
@ -120,12 +120,12 @@ func NewFileOrEnvironmentSource(
|
||||||
EnvoyVersion: envoyVersion,
|
EnvoyVersion: envoyVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
ports, err := netutil.AllocatePorts(6)
|
ports, err := netutil.AllocatePorts(7)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("allocating ports: %w", err)
|
return nil, fmt.Errorf("allocating ports: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.AllocatePorts(*(*[6]string)(ports))
|
cfg.AllocatePorts(*(*[7]string)(ports))
|
||||||
|
|
||||||
metrics.SetConfigInfo(ctx, cfg.Options.Services, "local", cfg.Checksum(), true)
|
metrics.SetConfigInfo(ctx, cfg.Options.Services, "local", cfg.Checksum(), true)
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,52 @@ import (
|
||||||
envoy_config_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
|
envoy_config_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
|
||||||
envoy_config_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
|
envoy_config_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3"
|
||||||
envoy_config_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
|
envoy_config_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
|
||||||
|
envoy_config_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
acmeHTTPClusterName = "pomerium-acme-http"
|
||||||
|
acmeHTTPPrefix = "/.well-known/acme-challenge/"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (b *Builder) buildACMEHTTPCluster(cfg *config.Config) *envoy_config_cluster_v3.Cluster {
|
||||||
|
port, _ := strconv.ParseUint(cfg.ACMEHTTPPort, 10, 32)
|
||||||
|
return &envoy_config_cluster_v3.Cluster{
|
||||||
|
Name: acmeHTTPClusterName,
|
||||||
|
LoadAssignment: &envoy_config_endpoint_v3.ClusterLoadAssignment{
|
||||||
|
ClusterName: acmeHTTPClusterName,
|
||||||
|
Endpoints: []*envoy_config_endpoint_v3.LocalityLbEndpoints{{
|
||||||
|
LbEndpoints: []*envoy_config_endpoint_v3.LbEndpoint{{
|
||||||
|
HostIdentifier: &envoy_config_endpoint_v3.LbEndpoint_Endpoint{
|
||||||
|
Endpoint: &envoy_config_endpoint_v3.Endpoint{
|
||||||
|
Address: buildTCPAddress("127.0.0.1", uint32(port)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Builder) buildACMEHTTPRoute() *envoy_config_route_v3.Route {
|
||||||
|
return &envoy_config_route_v3.Route{
|
||||||
|
Match: &envoy_config_route_v3.RouteMatch{
|
||||||
|
PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
|
||||||
|
Prefix: acmeHTTPPrefix,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: &envoy_config_route_v3.Route_Route{
|
||||||
|
Route: &envoy_config_route_v3.RouteAction{
|
||||||
|
ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
|
||||||
|
Cluster: acmeHTTPClusterName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Pomerium implements the ACME TLS-ALPN protocol by adding a filter chain to the main HTTPS listener
|
// Pomerium implements the ACME TLS-ALPN protocol by adding a filter chain to the main HTTPS listener
|
||||||
// that matches the acme-tls/1 application protocol on incoming requests and forwards them to a listener
|
// that matches the acme-tls/1 application protocol on incoming requests and forwards them to a listener
|
||||||
// started in the `autocert` package. The proxying is done using TCP so that the Go listener can terminate
|
// started in the `autocert` package. The proxying is done using TCP so that the Go listener can terminate
|
|
@ -96,6 +96,7 @@ func (b *Builder) BuildClusters(ctx context.Context, cfg *config.Config) ([]*env
|
||||||
|
|
||||||
clusters := []*envoy_config_cluster_v3.Cluster{
|
clusters := []*envoy_config_cluster_v3.Cluster{
|
||||||
b.buildACMETLSALPNCluster(cfg),
|
b.buildACMETLSALPNCluster(cfg),
|
||||||
|
b.buildACMEHTTPCluster(cfg),
|
||||||
controlGRPC,
|
controlGRPC,
|
||||||
controlHTTP,
|
controlHTTP,
|
||||||
controlMetrics,
|
controlMetrics,
|
||||||
|
|
|
@ -65,6 +65,10 @@ func (b *Builder) BuildListeners(
|
||||||
listeners = append(listeners, li)
|
listeners = append(listeners, li)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if shouldStartRedirectListener(cfg.Options) {
|
||||||
|
listeners = append(listeners, b.buildRedirectListener(cfg))
|
||||||
|
}
|
||||||
|
|
||||||
li, err := b.buildOutboundListener(cfg)
|
li, err := b.buildOutboundListener(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
80
config/envoyconfig/listeners_redirect.go
Normal file
80
config/envoyconfig/listeners_redirect.go
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
package envoyconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
envoy_config_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
|
||||||
|
envoy_config_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
|
||||||
|
envoy_extensions_filters_network_http_connection_manager "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
|
||||||
|
|
||||||
|
"github.com/pomerium/pomerium/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (b *Builder) buildRedirectListener(
|
||||||
|
cfg *config.Config,
|
||||||
|
) *envoy_config_listener_v3.Listener {
|
||||||
|
li := newTCPListener("http-redirect", buildTCPAddress(cfg.Options.HTTPRedirectAddr, 80))
|
||||||
|
|
||||||
|
// listener filters
|
||||||
|
if cfg.Options.UseProxyProtocol {
|
||||||
|
li.ListenerFilters = append(li.ListenerFilters, ProxyProtocolFilter())
|
||||||
|
}
|
||||||
|
|
||||||
|
li.FilterChains = append(li.FilterChains, &envoy_config_listener_v3.FilterChain{
|
||||||
|
Filters: []*envoy_config_listener_v3.Filter{
|
||||||
|
b.buildRedirectHTTPConnectionManagerFilter(cfg),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return li
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Builder) buildRedirectHTTPConnectionManagerFilter(
|
||||||
|
cfg *config.Config,
|
||||||
|
) *envoy_config_listener_v3.Filter {
|
||||||
|
_, strport, _ := net.SplitHostPort(cfg.Options.Addr)
|
||||||
|
port, _ := strconv.ParseUint(strport, 10, 32)
|
||||||
|
if port == 0 {
|
||||||
|
port = 443
|
||||||
|
}
|
||||||
|
|
||||||
|
return HTTPConnectionManagerFilter(&envoy_extensions_filters_network_http_connection_manager.HttpConnectionManager{
|
||||||
|
AlwaysSetRequestIdInResponse: true,
|
||||||
|
StatPrefix: "http-redirect",
|
||||||
|
RouteSpecifier: &envoy_extensions_filters_network_http_connection_manager.HttpConnectionManager_RouteConfig{
|
||||||
|
RouteConfig: &envoy_config_route_v3.RouteConfiguration{
|
||||||
|
Name: "http-redirect",
|
||||||
|
VirtualHosts: []*envoy_config_route_v3.VirtualHost{{
|
||||||
|
Name: "http-redirect",
|
||||||
|
Domains: []string{"*"},
|
||||||
|
Routes: []*envoy_config_route_v3.Route{
|
||||||
|
b.buildACMEHTTPRoute(),
|
||||||
|
{
|
||||||
|
Match: &envoy_config_route_v3.RouteMatch{
|
||||||
|
PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
|
||||||
|
Prefix: "/",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: &envoy_config_route_v3.Route_Redirect{
|
||||||
|
Redirect: &envoy_config_route_v3.RedirectAction{
|
||||||
|
SchemeRewriteSpecifier: &envoy_config_route_v3.RedirectAction_HttpsRedirect{
|
||||||
|
HttpsRedirect: true,
|
||||||
|
},
|
||||||
|
PortRedirect: uint32(port),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
HttpFilters: []*envoy_extensions_filters_network_http_connection_manager.HttpFilter{
|
||||||
|
HTTPRouterFilter(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldStartRedirectListener(options *config.Options) bool {
|
||||||
|
return !options.InsecureServer && options.HTTPRedirectAddr != ""
|
||||||
|
}
|
22
config/envoyconfig/testdata/clusters.json
vendored
22
config/envoyconfig/testdata/clusters.json
vendored
|
@ -21,6 +21,28 @@
|
||||||
},
|
},
|
||||||
"name": "pomerium-acme-tls-alpn"
|
"name": "pomerium-acme-tls-alpn"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"loadAssignment": {
|
||||||
|
"clusterName": "pomerium-acme-http",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "127.0.0.1",
|
||||||
|
"portValue": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"name": "pomerium-acme-http"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"connectTimeout": "10s",
|
"connectTimeout": "10s",
|
||||||
"dnsLookupFamily": "V4_PREFERRED",
|
"dnsLookupFamily": "V4_PREFERRED",
|
||||||
|
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/httputil"
|
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
||||||
"github.com/pomerium/pomerium/internal/urlutil"
|
"github.com/pomerium/pomerium/internal/urlutil"
|
||||||
|
@ -50,13 +49,16 @@ type Manager struct {
|
||||||
config *config.Config
|
config *config.Config
|
||||||
certmagic *certmagic.Config
|
certmagic *certmagic.Config
|
||||||
acmeMgr atomic.Pointer[certmagic.ACMEIssuer]
|
acmeMgr atomic.Pointer[certmagic.ACMEIssuer]
|
||||||
srv *http.Server
|
|
||||||
|
|
||||||
acmeTLSALPNLock sync.Mutex
|
acmeTLSALPNLock sync.Mutex
|
||||||
acmeTLSALPNPort string
|
acmeTLSALPNPort string
|
||||||
acmeTLSALPNListener net.Listener
|
acmeTLSALPNListener net.Listener
|
||||||
acmeTLSALPNConfig *tls.Config
|
acmeTLSALPNConfig *tls.Config
|
||||||
|
|
||||||
|
acmeHTTPLock sync.Mutex
|
||||||
|
acmeHTTPPort string
|
||||||
|
acmeHTTPListener net.Listener
|
||||||
|
|
||||||
*ocspCache
|
*ocspCache
|
||||||
|
|
||||||
config.ChangeDispatcher
|
config.ChangeDispatcher
|
||||||
|
@ -228,7 +230,7 @@ func (mgr *Manager) renewConfigCerts(ctx context.Context) error {
|
||||||
log.Ctx(ctx).Info().Msg("updating certificates")
|
log.Ctx(ctx).Info().Msg("updating certificates")
|
||||||
|
|
||||||
cfg = mgr.src.GetConfig().Clone()
|
cfg = mgr.src.GetConfig().Clone()
|
||||||
mgr.updateServer(ctx, cfg)
|
mgr.updateACMEHTTPServer(ctx, cfg)
|
||||||
mgr.updateACMETLSALPNServer(ctx, cfg)
|
mgr.updateACMETLSALPNServer(ctx, cfg)
|
||||||
if err := mgr.updateAutocert(ctx, cfg); err != nil {
|
if err := mgr.updateAutocert(ctx, cfg); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -246,7 +248,7 @@ func (mgr *Manager) update(ctx context.Context, cfg *config.Config) error {
|
||||||
defer mgr.mu.Unlock()
|
defer mgr.mu.Unlock()
|
||||||
defer func() { mgr.config = cfg }()
|
defer func() { mgr.config = cfg }()
|
||||||
|
|
||||||
mgr.updateServer(ctx, cfg)
|
mgr.updateACMEHTTPServer(ctx, cfg)
|
||||||
mgr.updateACMETLSALPNServer(ctx, cfg)
|
mgr.updateACMETLSALPNServer(ctx, cfg)
|
||||||
return mgr.updateAutocert(ctx, cfg)
|
return mgr.updateAutocert(ctx, cfg)
|
||||||
}
|
}
|
||||||
|
@ -313,40 +315,51 @@ func (mgr *Manager) updateAutocert(ctx context.Context, cfg *config.Config) erro
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mgr *Manager) updateServer(ctx context.Context, cfg *config.Config) {
|
func (mgr *Manager) updateACMEHTTPServer(ctx context.Context, cfg *config.Config) {
|
||||||
if mgr.srv != nil {
|
mgr.acmeHTTPLock.Lock()
|
||||||
// nothing to do if the address hasn't changed
|
defer mgr.acmeHTTPLock.Unlock()
|
||||||
if mgr.srv.Addr == cfg.Options.HTTPRedirectAddr {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// close immediately, don't care about the error
|
|
||||||
_ = mgr.srv.Close()
|
|
||||||
mgr.srv = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.Options.HTTPRedirectAddr == "" {
|
// if the port hasn't changed, we're done
|
||||||
|
if mgr.acmeHTTPPort == cfg.ACMEHTTPPort {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
redirect := httputil.RedirectHandler()
|
// store the updated port
|
||||||
|
mgr.acmeHTTPPort = cfg.ACMEHTTPPort
|
||||||
|
|
||||||
hsrv := &http.Server{
|
// close the existing listener
|
||||||
Addr: cfg.Options.HTTPRedirectAddr,
|
if mgr.acmeHTTPListener != nil {
|
||||||
|
_ = mgr.acmeHTTPListener.Close()
|
||||||
|
mgr.acmeHTTPListener = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// start a new listener
|
||||||
|
addr := net.JoinHostPort("127.0.0.1", cfg.ACMEHTTPPort)
|
||||||
|
ln, err := net.Listen("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
log.Ctx(ctx).Error().Err(err).Msg("failed to run acme http server")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mgr.acmeHTTPListener = ln
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
srv := &http.Server{
|
||||||
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if mgr.handleHTTPChallenge(w, r) {
|
if mgr.handleHTTPChallenge(w, r) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
redirect.ServeHTTP(w, r)
|
// just serve not found
|
||||||
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||||
}),
|
}),
|
||||||
|
ReadTimeout: time.Minute,
|
||||||
|
WriteTimeout: time.Minute,
|
||||||
|
IdleTimeout: 5 * time.Minute,
|
||||||
}
|
}
|
||||||
go func() {
|
err := srv.Serve(ln)
|
||||||
log.Ctx(ctx).Info().Str("addr", hsrv.Addr).Msg("starting http redirect server")
|
|
||||||
err := hsrv.ListenAndServe()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Ctx(ctx).Error().Err(err).Msg("failed to run http redirect server")
|
log.Ctx(ctx).Error().Err(err).Msg("error serving acme http server")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
mgr.srv = hsrv
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mgr *Manager) updateACMETLSALPNServer(ctx context.Context, cfg *config.Config) {
|
func (mgr *Manager) updateACMETLSALPNServer(ctx context.Context, cfg *config.Config) {
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
|
@ -298,66 +297,6 @@ func TestConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRedirect(t *testing.T) {
|
|
||||||
li, err := net.Listen("tcp", "127.0.0.1:0")
|
|
||||||
if !assert.NoError(t, err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
addr := li.Addr().String()
|
|
||||||
_ = li.Close()
|
|
||||||
|
|
||||||
src := config.NewStaticSource(&config.Config{
|
|
||||||
Options: &config.Options{
|
|
||||||
HTTPRedirectAddr: addr,
|
|
||||||
SetResponseHeaders: map[string]string{
|
|
||||||
"X-Frame-Options": "SAMEORIGIN",
|
|
||||||
"X-XSS-Protection": "1; mode=block",
|
|
||||||
"Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
_, err = New(context.Background(), src)
|
|
||||||
if !assert.NoError(t, err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = waitFor(addr)
|
|
||||||
if !assert.NoError(t, err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
client := &http.Client{
|
|
||||||
CheckRedirect: func(_ *http.Request, _ []*http.Request) error {
|
|
||||||
return http.ErrUseLastResponse
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := client.Get(fmt.Sprintf("http://%s", addr))
|
|
||||||
if !assert.NoError(t, err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
|
|
||||||
assert.Equal(t, http.StatusMovedPermanently, res.StatusCode, "should redirect to https")
|
|
||||||
for k, v := range src.GetConfig().Options.SetResponseHeaders {
|
|
||||||
assert.NotEqual(t, v, res.Header.Get(k), "should ignore options header")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func waitFor(addr string) error {
|
|
||||||
var err error
|
|
||||||
deadline := time.Now().Add(time.Second * 30)
|
|
||||||
for time.Now().Before(deadline) {
|
|
||||||
var conn net.Conn
|
|
||||||
conn, err = net.Dial("tcp", addr)
|
|
||||||
if err == nil {
|
|
||||||
conn.Close()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func readJWSPayload(r io.Reader, dst any) {
|
func readJWSPayload(r io.Reader, dst any) {
|
||||||
var req struct {
|
var req struct {
|
||||||
Protected string `json:"protected"`
|
Protected string `json:"protected"`
|
||||||
|
|
|
@ -30,6 +30,12 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
|
"google.golang.org/grpc/grpclog"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/config/envoyconfig/filemgr"
|
"github.com/pomerium/pomerium/config/envoyconfig/filemgr"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
|
@ -39,11 +45,6 @@ import (
|
||||||
"github.com/pomerium/pomerium/pkg/health"
|
"github.com/pomerium/pomerium/pkg/health"
|
||||||
"github.com/pomerium/pomerium/pkg/netutil"
|
"github.com/pomerium/pomerium/pkg/netutil"
|
||||||
"github.com/pomerium/pomerium/pkg/slices"
|
"github.com/pomerium/pomerium/pkg/slices"
|
||||||
"github.com/rs/zerolog"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"golang.org/x/sync/errgroup"
|
|
||||||
"google.golang.org/grpc/grpclog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Environment is a lightweight integration test fixture that runs Pomerium
|
// Environment is a lightweight integration test fixture that runs Pomerium
|
||||||
|
@ -450,7 +451,7 @@ func (e *environment) Start() {
|
||||||
cfg := &config.Config{
|
cfg := &config.Config{
|
||||||
Options: config.NewDefaultOptions(),
|
Options: config.NewDefaultOptions(),
|
||||||
}
|
}
|
||||||
ports, err := netutil.AllocatePorts(9)
|
ports, err := netutil.AllocatePorts(10)
|
||||||
require.NoError(e.t, err)
|
require.NoError(e.t, err)
|
||||||
atoi := func(str string) int {
|
atoi := func(str string) int {
|
||||||
p, err := strconv.Atoi(str)
|
p, err := strconv.Atoi(str)
|
||||||
|
@ -468,7 +469,7 @@ func (e *environment) Start() {
|
||||||
e.ports.Metrics.Resolve(atoi(ports[6]))
|
e.ports.Metrics.Resolve(atoi(ports[6]))
|
||||||
e.ports.Debug.Resolve(atoi(ports[7]))
|
e.ports.Debug.Resolve(atoi(ports[7]))
|
||||||
e.ports.ALPN.Resolve(atoi(ports[8]))
|
e.ports.ALPN.Resolve(atoi(ports[8]))
|
||||||
cfg.AllocatePorts(*(*[6]string)(ports[3:]))
|
cfg.AllocatePorts(*(*[7]string)(ports[3:]))
|
||||||
|
|
||||||
cfg.Options.AutocertOptions = config.AutocertOptions{Enable: false}
|
cfg.Options.AutocertOptions = config.AutocertOptions{Enable: false}
|
||||||
cfg.Options.Services = "all"
|
cfg.Options.Services = "all"
|
||||||
|
|
|
@ -78,12 +78,12 @@ func New(secret []byte, fileCachePath *string, writer writers.ConfigWriter, api
|
||||||
func setConfigDefaults(cfg *config.Config) error {
|
func setConfigDefaults(cfg *config.Config) error {
|
||||||
cfg.Options = config.NewDefaultOptions()
|
cfg.Options = config.NewDefaultOptions()
|
||||||
|
|
||||||
ports, err := netutil.AllocatePorts(6)
|
ports, err := netutil.AllocatePorts(7)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("allocating ports: %w", err)
|
return fmt.Errorf("allocating ports: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.AllocatePorts(*(*[6]string)(ports[:6]))
|
cfg.AllocatePorts(*(*[7]string)(ports[:7]))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue