internal/controlplane: make sure options.Headers are set for response (#907)

When switching to envoy, we forgot to adopt the middleware to set
response headers with options.Headers, which causes HSTS header is
missing in v0.9.0 release.

Fixes #901
This commit is contained in:
Cuong Manh Le 2020-06-17 00:56:01 +07:00 committed by GitHub
parent ee2170f5f5
commit f62bb686d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 8 deletions

View file

@ -98,6 +98,11 @@ func buildControlPlanePrefixRoute(prefix string) *envoy_config_route_v3.Route {
func buildPolicyRoutes(options *config.Options, domain string) []*envoy_config_route_v3.Route {
var routes []*envoy_config_route_v3.Route
responseHeadersToAdd := make([]*envoy_config_core_v3.HeaderValueOption, 0, len(options.Headers))
for k, v := range options.Headers {
responseHeadersToAdd = append(responseHeadersToAdd, mkEnvoyHeader(k, v))
}
for i, policy := range options.Policies {
if policy.Source.Host != domain {
continue
@ -123,15 +128,9 @@ func buildPolicyRoutes(options *config.Options, domain string) []*envoy_config_r
}
clusterName := getPolicyName(&policy)
var requestHeadersToAdd []*envoy_config_core_v3.HeaderValueOption
requestHeadersToAdd := make([]*envoy_config_core_v3.HeaderValueOption, 0, len(policy.SetRequestHeaders))
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},
})
requestHeadersToAdd = append(requestHeadersToAdd, mkEnvoyHeader(k, v))
}
var routeTimeout *durationpb.Duration
@ -184,7 +183,18 @@ func buildPolicyRoutes(options *config.Options, domain string) []*envoy_config_r
},
RequestHeadersToAdd: requestHeadersToAdd,
RequestHeadersToRemove: policy.RemoveRequestHeaders,
ResponseHeadersToAdd: responseHeadersToAdd,
})
}
return routes
}
func mkEnvoyHeader(k, v string) *envoy_config_core_v3.HeaderValueOption {
return &envoy_config_core_v3.HeaderValueOption{
Header: &envoy_config_core_v3.HeaderValue{
Key: k,
Value: v,
},
Append: &wrappers.BoolValue{Value: false},
}
}

View file

@ -362,6 +362,56 @@ func Test_buildPolicyRoutes(t *testing.T) {
`, routes)
}
// Make sure default Headers are set for response.
// See also https://github.com/pomerium/pomerium/issues/901
func TestAddOptionsHeadersToResponse(t *testing.T) {
routes := buildPolicyRoutes(&config.Options{
CookieName: "pomerium",
DefaultUpstreamTimeout: time.Second * 3,
Policies: []config.Policy{
{
Source: &config.StringURL{URL: mustParseURL("https://example.com")},
},
},
Headers: map[string]string{"Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload"},
}, "example.com")
testutil.AssertProtoJSONEqual(t, `
[
{
"name": "policy-0",
"match": {
"prefix": "/"
},
"metadata": {
"filterMetadata": {
"envoy.filters.http.lua": {
"remove_pomerium_authorization": true,
"remove_pomerium_cookie": "pomerium"
}
}
},
"route": {
"autoHostRewrite": true,
"cluster": "policy-701142725541ce1f",
"timeout": "3s",
"upgradeConfigs": [{
"enabled": false,
"upgradeType": "websocket"
}]
},
"responseHeadersToAdd": [{
"append": false,
"header": {
"key": "Strict-Transport-Security",
"value": "max-age=31536000; includeSubDomains; preload"
}
}]
}
]
`, routes)
}
func mustParseURL(str string) *url.URL {
u, err := url.Parse(str)
if err != nil {