mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 10:26:29 +02:00
* config: add RemoveRequestHeaders Currently, we have "set_request_headers" config, which reflects envoy route.Route.RequestHeadersToAdd. This commit add new config "remove_request_headers", which reflects envoy RequestHeadersToRemove. This is also a preparation for future PRs to implement disable user identity in request headers feature. * integration: add test for remove_request_headers * docs: add documentation/changelog for remove_request_headers
190 lines
6.2 KiB
Go
190 lines
6.2 KiB
Go
package controlplane
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
envoy_config_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
|
|
envoy_config_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
|
|
envoy_type_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
|
|
"github.com/golang/protobuf/ptypes"
|
|
"github.com/golang/protobuf/ptypes/any"
|
|
"github.com/golang/protobuf/ptypes/wrappers"
|
|
"google.golang.org/protobuf/types/known/durationpb"
|
|
"google.golang.org/protobuf/types/known/structpb"
|
|
|
|
"github.com/pomerium/pomerium/config"
|
|
)
|
|
|
|
func buildGRPCRoutes() []*envoy_config_route_v3.Route {
|
|
action := &envoy_config_route_v3.Route_Route{
|
|
Route: &envoy_config_route_v3.RouteAction{
|
|
ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
|
|
Cluster: "pomerium-control-plane-grpc",
|
|
},
|
|
},
|
|
}
|
|
return []*envoy_config_route_v3.Route{{
|
|
Name: "pomerium-grpc",
|
|
Match: &envoy_config_route_v3.RouteMatch{
|
|
PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{
|
|
Prefix: "/",
|
|
},
|
|
Grpc: &envoy_config_route_v3.RouteMatch_GrpcRouteMatchOptions{},
|
|
},
|
|
Action: action,
|
|
TypedPerFilterConfig: map[string]*any.Any{
|
|
"envoy.filters.http.ext_authz": disableExtAuthz,
|
|
},
|
|
}}
|
|
}
|
|
|
|
func buildPomeriumHTTPRoutes(options *config.Options, domain string) []*envoy_config_route_v3.Route {
|
|
routes := []*envoy_config_route_v3.Route{
|
|
buildControlPlanePathRoute("/ping"),
|
|
buildControlPlanePathRoute("/healthz"),
|
|
buildControlPlanePathRoute("/.pomerium"),
|
|
buildControlPlanePrefixRoute("/.pomerium/"),
|
|
buildControlPlanePathRoute("/.well-known/pomerium"),
|
|
buildControlPlanePrefixRoute("/.well-known/pomerium/"),
|
|
}
|
|
// if we're handling authentication, add the oauth2 callback url
|
|
if config.IsAuthenticate(options.Services) && domain == options.GetAuthenticateURL().Host {
|
|
routes = append(routes, buildControlPlanePathRoute(options.AuthenticateCallbackPath))
|
|
}
|
|
// if we're the proxy and this is the forward-auth url
|
|
if config.IsProxy(options.Services) && options.ForwardAuthURL != nil && domain == options.ForwardAuthURL.Host {
|
|
routes = append(routes, buildControlPlanePrefixRoute("/"))
|
|
}
|
|
return routes
|
|
}
|
|
|
|
func buildControlPlanePathRoute(path string) *envoy_config_route_v3.Route {
|
|
return &envoy_config_route_v3.Route{
|
|
Name: "pomerium-path-" + path,
|
|
Match: &envoy_config_route_v3.RouteMatch{
|
|
PathSpecifier: &envoy_config_route_v3.RouteMatch_Path{Path: path},
|
|
},
|
|
Action: &envoy_config_route_v3.Route_Route{
|
|
Route: &envoy_config_route_v3.RouteAction{
|
|
ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
|
|
Cluster: "pomerium-control-plane-http",
|
|
},
|
|
},
|
|
},
|
|
TypedPerFilterConfig: map[string]*any.Any{
|
|
"envoy.filters.http.ext_authz": disableExtAuthz,
|
|
},
|
|
}
|
|
}
|
|
|
|
func buildControlPlanePrefixRoute(prefix string) *envoy_config_route_v3.Route {
|
|
return &envoy_config_route_v3.Route{
|
|
Name: "pomerium-prefix-" + prefix,
|
|
Match: &envoy_config_route_v3.RouteMatch{
|
|
PathSpecifier: &envoy_config_route_v3.RouteMatch_Prefix{Prefix: prefix},
|
|
},
|
|
Action: &envoy_config_route_v3.Route_Route{
|
|
Route: &envoy_config_route_v3.RouteAction{
|
|
ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
|
|
Cluster: "pomerium-control-plane-http",
|
|
},
|
|
},
|
|
},
|
|
TypedPerFilterConfig: map[string]*any.Any{
|
|
"envoy.filters.http.ext_authz": disableExtAuthz,
|
|
},
|
|
}
|
|
}
|
|
|
|
func buildPolicyRoutes(options *config.Options, domain string) []*envoy_config_route_v3.Route {
|
|
var routes []*envoy_config_route_v3.Route
|
|
for i, policy := range options.Policies {
|
|
if policy.Source.Host != domain {
|
|
continue
|
|
}
|
|
|
|
match := &envoy_config_route_v3.RouteMatch{}
|
|
switch {
|
|
case policy.Regex != "":
|
|
match.PathSpecifier = &envoy_config_route_v3.RouteMatch_SafeRegex{
|
|
SafeRegex: &envoy_type_matcher_v3.RegexMatcher{
|
|
EngineType: &envoy_type_matcher_v3.RegexMatcher_GoogleRe2{
|
|
GoogleRe2: &envoy_type_matcher_v3.RegexMatcher_GoogleRE2{},
|
|
},
|
|
Regex: policy.Regex,
|
|
},
|
|
}
|
|
case policy.Path != "":
|
|
match.PathSpecifier = &envoy_config_route_v3.RouteMatch_Path{Path: policy.Path}
|
|
case policy.Prefix != "":
|
|
match.PathSpecifier = &envoy_config_route_v3.RouteMatch_Prefix{Prefix: policy.Prefix}
|
|
default:
|
|
match.PathSpecifier = &envoy_config_route_v3.RouteMatch_Prefix{Prefix: "/"}
|
|
}
|
|
clusterName := getPolicyName(&policy)
|
|
|
|
var requestHeadersToAdd []*envoy_config_core_v3.HeaderValueOption
|
|
for k, v := range policy.SetRequestHeaders {
|
|
requestHeadersToAdd = append(requestHeadersToAdd, &envoy_config_core_v3.HeaderValueOption{
|
|
Header: &envoy_config_core_v3.HeaderValue{
|
|
Key: k,
|
|
Value: v,
|
|
},
|
|
Append: &wrappers.BoolValue{Value: false},
|
|
})
|
|
}
|
|
|
|
var routeTimeout *durationpb.Duration
|
|
if policy.AllowWebsockets {
|
|
// disable the route timeout for websocket support
|
|
routeTimeout = ptypes.DurationProto(0)
|
|
} else {
|
|
if policy.UpstreamTimeout != 0 {
|
|
routeTimeout = ptypes.DurationProto(policy.UpstreamTimeout)
|
|
} else {
|
|
routeTimeout = ptypes.DurationProto(options.DefaultUpstreamTimeout)
|
|
}
|
|
}
|
|
|
|
routes = append(routes, &envoy_config_route_v3.Route{
|
|
Name: fmt.Sprintf("policy-%d", i),
|
|
Match: match,
|
|
Metadata: &envoy_config_core_v3.Metadata{
|
|
FilterMetadata: map[string]*structpb.Struct{
|
|
"envoy.filters.http.lua": {
|
|
Fields: map[string]*structpb.Value{
|
|
"remove_pomerium_cookie": {
|
|
Kind: &structpb.Value_StringValue{
|
|
StringValue: options.CookieName,
|
|
},
|
|
},
|
|
"remove_pomerium_authorization": {
|
|
Kind: &structpb.Value_BoolValue{
|
|
BoolValue: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Action: &envoy_config_route_v3.Route_Route{
|
|
Route: &envoy_config_route_v3.RouteAction{
|
|
ClusterSpecifier: &envoy_config_route_v3.RouteAction_Cluster{
|
|
Cluster: clusterName,
|
|
},
|
|
UpgradeConfigs: []*envoy_config_route_v3.RouteAction_UpgradeConfig{{
|
|
UpgradeType: "websocket",
|
|
Enabled: &wrappers.BoolValue{Value: policy.AllowWebsockets},
|
|
}},
|
|
HostRewriteSpecifier: &envoy_config_route_v3.RouteAction_AutoHostRewrite{
|
|
AutoHostRewrite: &wrappers.BoolValue{Value: !policy.PreserveHostHeader},
|
|
},
|
|
Timeout: routeTimeout,
|
|
},
|
|
},
|
|
RequestHeadersToAdd: requestHeadersToAdd,
|
|
RequestHeadersToRemove: policy.RemoveRequestHeaders,
|
|
})
|
|
}
|
|
return routes
|
|
}
|