Skip to content

Commit

Permalink
config: simplify default set response headers
Browse files Browse the repository at this point in the history
  • Loading branch information
calebdoxsey committed May 30, 2023
1 parent d315e68 commit 3deb6b9
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 80 deletions.
6 changes: 2 additions & 4 deletions config/envoyconfig/http_connection_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ func (b *Builder) buildVirtualHost(
options *config.Options,
name string,
host string,
requireStrictTransportSecurity bool,
) (*envoy_config_route_v3.VirtualHost, error) {
vh := &envoy_config_route_v3.VirtualHost{
Name: name,
Domains: []string{host},
}

// these routes match /.pomerium/... and similar paths
rs, err := b.buildPomeriumHTTPRoutes(options, host, requireStrictTransportSecurity)
rs, err := b.buildPomeriumHTTPRoutes(options, host)
if err != nil {
return nil, err
}
Expand All @@ -34,13 +33,12 @@ func (b *Builder) buildVirtualHost(
// coming directly from envoy
func (b *Builder) buildLocalReplyConfig(
options *config.Options,
requireStrictTransportSecurity bool,
) *envoy_http_connection_manager.LocalReplyConfig {
// add global headers for HSTS headers (#2110)
var headers []*envoy_config_core_v3.HeaderValueOption
// if we're the proxy or authenticate service, add our global headers
if config.IsProxy(options.Services) || config.IsAuthenticate(options.Services) {
headers = toEnvoyHeaders(options.GetSetResponseHeaders(requireStrictTransportSecurity))
headers = toEnvoyHeaders(options.GetSetResponseHeaders())
}

return &envoy_http_connection_manager.LocalReplyConfig{
Expand Down
2 changes: 1 addition & 1 deletion config/envoyconfig/listeners.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ func (b *Builder) buildMainHTTPConnectionManagerFilter(
UseRemoteAddress: &wrappers.BoolValue{Value: true},
SkipXffAppend: cfg.Options.SkipXffAppend,
XffNumTrustedHops: cfg.Options.XffNumTrustedHops,
LocalReplyConfig: b.buildLocalReplyConfig(cfg.Options, false),
LocalReplyConfig: b.buildLocalReplyConfig(cfg.Options),
NormalizePath: wrapperspb.Bool(true),
}

Expand Down
20 changes: 4 additions & 16 deletions config/envoyconfig/route_configurations.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package envoyconfig

import (
"context"
"crypto/tls"

envoy_config_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"

"github.com/pomerium/pomerium/config"
"github.com/pomerium/pomerium/pkg/cryptutil"
)

// BuildRouteConfigurations builds the route configurations for the RDS service.
Expand All @@ -32,15 +30,6 @@ func (b *Builder) buildMainRouteConfiguration(
_ context.Context,
cfg *config.Config,
) (*envoy_config_route_v3.RouteConfiguration, error) {
var certs []tls.Certificate
if !cfg.Options.InsecureServer {
var err error
certs, err = getAllCertificates(cfg)
if err != nil {
return nil, err
}
}

authorizeURLs, err := cfg.Options.GetInternalAuthorizeURLs()
if err != nil {
return nil, err
Expand All @@ -58,8 +47,7 @@ func (b *Builder) buildMainRouteConfiguration(

var virtualHosts []*envoy_config_route_v3.VirtualHost
for _, host := range allHosts {
requireStrictTransportSecurity := cryptutil.HasCertificateForServerName(certs, host)
vh, err := b.buildVirtualHost(cfg.Options, host, host, requireStrictTransportSecurity)
vh, err := b.buildVirtualHost(cfg.Options, host, host)
if err != nil {
return nil, err
}
Expand All @@ -78,7 +66,7 @@ func (b *Builder) buildMainRouteConfiguration(

// if we're the proxy, add all the policy routes
if config.IsProxy(cfg.Options.Services) {
rs, err := b.buildRoutesForPoliciesWithHost(cfg, certs, host)
rs, err := b.buildRoutesForPoliciesWithHost(cfg, host)
if err != nil {
return nil, err
}
Expand All @@ -90,12 +78,12 @@ func (b *Builder) buildMainRouteConfiguration(
}
}

vh, err := b.buildVirtualHost(cfg.Options, "catch-all", "*", false)
vh, err := b.buildVirtualHost(cfg.Options, "catch-all", "*")
if err != nil {
return nil, err
}
if config.IsProxy(cfg.Options.Services) {
rs, err := b.buildRoutesForPoliciesWithCatchAll(cfg, certs)
rs, err := b.buildRoutesForPoliciesWithCatchAll(cfg)
if err != nil {
return nil, err
}
Expand Down
14 changes: 7 additions & 7 deletions config/envoyconfig/route_configurations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ func TestBuilder_buildMainRouteConfiguration(t *testing.T) {
"name": "catch-all",
"domains": ["*"],
"routes": [
`+protojson.Format(b.buildControlPlanePathRoute(cfg.Options, "/ping", false))+`,
`+protojson.Format(b.buildControlPlanePathRoute(cfg.Options, "/healthz", false))+`,
`+protojson.Format(b.buildControlPlanePathRoute(cfg.Options, "/.pomerium", false))+`,
`+protojson.Format(b.buildControlPlanePrefixRoute(cfg.Options, "/.pomerium/", false))+`,
`+protojson.Format(b.buildControlPlanePathRoute(cfg.Options, "/.well-known/pomerium", false))+`,
`+protojson.Format(b.buildControlPlanePrefixRoute(cfg.Options, "/.well-known/pomerium/", false))+`,
`+protojson.Format(b.buildControlPlanePathRoute(cfg.Options, "/robots.txt", false))+`,
`+protojson.Format(b.buildControlPlanePathRoute(cfg.Options, "/ping"))+`,
`+protojson.Format(b.buildControlPlanePathRoute(cfg.Options, "/healthz"))+`,
`+protojson.Format(b.buildControlPlanePathRoute(cfg.Options, "/.pomerium"))+`,
`+protojson.Format(b.buildControlPlanePrefixRoute(cfg.Options, "/.pomerium/"))+`,
`+protojson.Format(b.buildControlPlanePathRoute(cfg.Options, "/.well-known/pomerium"))+`,
`+protojson.Format(b.buildControlPlanePrefixRoute(cfg.Options, "/.well-known/pomerium/"))+`,
`+protojson.Format(b.buildControlPlanePathRoute(cfg.Options, "/robots.txt"))+`,
{
"name": "policy-0",
"match": {
Expand Down
46 changes: 17 additions & 29 deletions config/envoyconfig/routes.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package envoyconfig

import (
"crypto/tls"
"encoding/json"
"fmt"
"net/url"
Expand All @@ -20,7 +19,6 @@ import (
"github.com/pomerium/pomerium/config"
"github.com/pomerium/pomerium/internal/httputil"
"github.com/pomerium/pomerium/internal/urlutil"
"github.com/pomerium/pomerium/pkg/cryptutil"
)

const (
Expand Down Expand Up @@ -53,7 +51,6 @@ func (b *Builder) buildGRPCRoutes() ([]*envoy_config_route_v3.Route, error) {
func (b *Builder) buildPomeriumHTTPRoutes(
options *config.Options,
host string,
requireStrictTransportSecurity bool,
) ([]*envoy_config_route_v3.Route, error) {
var routes []*envoy_config_route_v3.Route

Expand All @@ -65,20 +62,20 @@ func (b *Builder) buildPomeriumHTTPRoutes(
}
if !isFrontingAuthenticate {
routes = append(routes,
b.buildControlPlanePathRoute(options, "/ping", requireStrictTransportSecurity),
b.buildControlPlanePathRoute(options, "/healthz", requireStrictTransportSecurity),
b.buildControlPlanePathRoute(options, "/.pomerium", requireStrictTransportSecurity),
b.buildControlPlanePrefixRoute(options, "/.pomerium/", requireStrictTransportSecurity),
b.buildControlPlanePathRoute(options, "/.well-known/pomerium", requireStrictTransportSecurity),
b.buildControlPlanePrefixRoute(options, "/.well-known/pomerium/", requireStrictTransportSecurity),
b.buildControlPlanePathRoute(options, "/ping"),
b.buildControlPlanePathRoute(options, "/healthz"),
b.buildControlPlanePathRoute(options, "/.pomerium"),
b.buildControlPlanePrefixRoute(options, "/.pomerium/"),
b.buildControlPlanePathRoute(options, "/.well-known/pomerium"),
b.buildControlPlanePrefixRoute(options, "/.well-known/pomerium/"),
)
// per #837, only add robots.txt if there are no unauthenticated routes
if !hasPublicPolicyMatchingURL(options, url.URL{Scheme: "https", Host: host, Path: "/robots.txt"}) {
routes = append(routes, b.buildControlPlanePathRoute(options, "/robots.txt", requireStrictTransportSecurity))
routes = append(routes, b.buildControlPlanePathRoute(options, "/robots.txt"))
}
}

authRoutes, err := b.buildPomeriumAuthenticateHTTPRoutes(options, host, requireStrictTransportSecurity)
authRoutes, err := b.buildPomeriumAuthenticateHTTPRoutes(options, host)
if err != nil {
return nil, err
}
Expand All @@ -89,7 +86,6 @@ func (b *Builder) buildPomeriumHTTPRoutes(
func (b *Builder) buildPomeriumAuthenticateHTTPRoutes(
options *config.Options,
host string,
requireStrictTransportSecurity bool,
) ([]*envoy_config_route_v3.Route, error) {
if !config.IsAuthenticate(options.Services) {
return nil, nil
Expand All @@ -105,8 +101,8 @@ func (b *Builder) buildPomeriumAuthenticateHTTPRoutes(
}
if urlMatchesHost(u, host) {
return []*envoy_config_route_v3.Route{
b.buildControlPlanePathRoute(options, options.AuthenticateCallbackPath, requireStrictTransportSecurity),
b.buildControlPlanePathRoute(options, "/", requireStrictTransportSecurity),
b.buildControlPlanePathRoute(options, options.AuthenticateCallbackPath),
b.buildControlPlanePathRoute(options, "/"),
}, nil
}
}
Expand All @@ -116,7 +112,6 @@ func (b *Builder) buildPomeriumAuthenticateHTTPRoutes(
func (b *Builder) buildControlPlanePathRoute(
options *config.Options,
path string,
requireStrictTransportSecurity bool,
) *envoy_config_route_v3.Route {
r := &envoy_config_route_v3.Route{
Name: "pomerium-path-" + path,
Expand All @@ -130,7 +125,7 @@ func (b *Builder) buildControlPlanePathRoute(
},
},
},
ResponseHeadersToAdd: toEnvoyHeaders(options.GetSetResponseHeaders(requireStrictTransportSecurity)),
ResponseHeadersToAdd: toEnvoyHeaders(options.GetSetResponseHeaders()),
TypedPerFilterConfig: map[string]*any.Any{
PerFilterConfigExtAuthzName: PerFilterConfigExtAuthzContextExtensions(MakeExtAuthzContextExtensions(true, 0)),
},
Expand All @@ -141,7 +136,6 @@ func (b *Builder) buildControlPlanePathRoute(
func (b *Builder) buildControlPlanePrefixRoute(
options *config.Options,
prefix string,
requireStrictTransportSecurity bool,
) *envoy_config_route_v3.Route {
r := &envoy_config_route_v3.Route{
Name: "pomerium-prefix-" + prefix,
Expand All @@ -155,7 +149,7 @@ func (b *Builder) buildControlPlanePrefixRoute(
},
},
},
ResponseHeadersToAdd: toEnvoyHeaders(options.GetSetResponseHeaders(requireStrictTransportSecurity)),
ResponseHeadersToAdd: toEnvoyHeaders(options.GetSetResponseHeaders()),
TypedPerFilterConfig: map[string]*any.Any{
PerFilterConfigExtAuthzName: PerFilterConfigExtAuthzContextExtensions(MakeExtAuthzContextExtensions(true, 0)),
},
Expand Down Expand Up @@ -184,7 +178,6 @@ func getClusterStatsName(policy *config.Policy) string {

func (b *Builder) buildRoutesForPoliciesWithHost(
cfg *config.Config,
certs []tls.Certificate,
host string,
) ([]*envoy_config_route_v3.Route, error) {
var routes []*envoy_config_route_v3.Route
Expand All @@ -199,7 +192,7 @@ func (b *Builder) buildRoutesForPoliciesWithHost(
continue
}

policyRoutes, err := b.buildRoutesForPolicy(cfg, certs, &policy, fmt.Sprintf("policy-%d", i))
policyRoutes, err := b.buildRoutesForPolicy(cfg, &policy, fmt.Sprintf("policy-%d", i))
if err != nil {
return nil, err
}
Expand All @@ -211,7 +204,6 @@ func (b *Builder) buildRoutesForPoliciesWithHost(

func (b *Builder) buildRoutesForPoliciesWithCatchAll(
cfg *config.Config,
certs []tls.Certificate,
) ([]*envoy_config_route_v3.Route, error) {
var routes []*envoy_config_route_v3.Route
for i, p := range cfg.Options.GetAllPolicies() {
Expand All @@ -225,7 +217,7 @@ func (b *Builder) buildRoutesForPoliciesWithCatchAll(
continue
}

policyRoutes, err := b.buildRoutesForPolicy(cfg, certs, &policy, fmt.Sprintf("policy-%d", i))
policyRoutes, err := b.buildRoutesForPolicy(cfg, &policy, fmt.Sprintf("policy-%d", i))
if err != nil {
return nil, err
}
Expand All @@ -237,7 +229,6 @@ func (b *Builder) buildRoutesForPoliciesWithCatchAll(

func (b *Builder) buildRoutesForPolicy(
cfg *config.Config,
certs []tls.Certificate,
policy *config.Policy,
name string,
) ([]*envoy_config_route_v3.Route, error) {
Expand All @@ -250,14 +241,14 @@ func (b *Builder) buildRoutesForPolicy(
if strings.Contains(fromURL.Host, "*") {
// we have to match '*.example.com' and '*.example.com:443', so there are two routes
for _, host := range urlutil.GetDomainsForURL(fromURL) {
route, err := b.buildRouteForPolicyAndMatch(cfg, certs, policy, name, mkRouteMatchForHost(policy, host))
route, err := b.buildRouteForPolicyAndMatch(cfg, policy, name, mkRouteMatchForHost(policy, host))
if err != nil {
return nil, err
}
routes = append(routes, route)
}
} else {
route, err := b.buildRouteForPolicyAndMatch(cfg, certs, policy, name, mkRouteMatch(policy))
route, err := b.buildRouteForPolicyAndMatch(cfg, policy, name, mkRouteMatch(policy))
if err != nil {
return nil, err
}
Expand All @@ -268,7 +259,6 @@ func (b *Builder) buildRoutesForPolicy(

func (b *Builder) buildRouteForPolicyAndMatch(
cfg *config.Config,
certs []tls.Certificate,
policy *config.Policy,
name string,
match *envoy_config_route_v3.RouteMatch,
Expand All @@ -283,15 +273,13 @@ func (b *Builder) buildRouteForPolicyAndMatch(
return nil, err
}

requireStrictTransportSecurity := cryptutil.HasCertificateForServerName(certs, fromURL.Hostname())

route := &envoy_config_route_v3.Route{
Name: name,
Match: match,
Metadata: &envoy_config_core_v3.Metadata{},
RequestHeadersToAdd: toEnvoyHeaders(policy.SetRequestHeaders),
RequestHeadersToRemove: getRequestHeadersToRemove(cfg.Options, policy),
ResponseHeadersToAdd: toEnvoyHeaders(cfg.Options.GetSetResponseHeadersForPolicy(policy, requireStrictTransportSecurity)),
ResponseHeadersToAdd: toEnvoyHeaders(cfg.Options.GetSetResponseHeadersForPolicy(policy)),
}
if policy.Redirect != nil {
action, err := b.buildPolicyRouteRedirectAction(policy.Redirect)
Expand Down

0 comments on commit 3deb6b9

Please sign in to comment.