mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-22 05:27:13 +02:00
config: support multiple destination addresses (#1789)
* config: support multiple destination addresses * use constructor for string slice * add docs * add test for multiple destinations * fix name
This commit is contained in:
parent
c6b6141d12
commit
a4c7381eba
22 changed files with 556 additions and 191 deletions
|
@ -124,7 +124,11 @@ func TestAuthorize_OnConfigChange(t *testing.T) {
|
|||
}
|
||||
|
||||
func testPolicies(t *testing.T) []config.Policy {
|
||||
testPolicy := config.Policy{From: "https://pomerium.io", To: "http://httpbin.org", AllowedUsers: []string{"test@gmail.com"}}
|
||||
testPolicy := config.Policy{
|
||||
From: "https://pomerium.io",
|
||||
To: config.NewStringSlice("http://httpbin.org"),
|
||||
AllowedUsers: []string{"test@gmail.com"},
|
||||
}
|
||||
err := testPolicy.Validate()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
@ -157,7 +157,7 @@ func TestAuthorize_okResponse(t *testing.T) {
|
|||
SignedJWT: "valid-signed-jwt",
|
||||
MatchingPolicy: &config.Policy{
|
||||
EnableGoogleCloudServerlessAuthentication: true,
|
||||
Destination: mustParseURL("https://example.com"),
|
||||
Destinations: mustParseURLs("https://example.com"),
|
||||
},
|
||||
},
|
||||
&envoy_service_auth_v2.CheckResponse{
|
||||
|
|
|
@ -133,7 +133,11 @@ func (a *Authorize) getGoogleCloudServerlessAuthenticationHeaders(reply *evaluat
|
|||
}
|
||||
|
||||
serviceAccount := a.currentOptions.Load().GoogleCloudServerlessAuthenticationServiceAccount
|
||||
audience := fmt.Sprintf("https://%s", reply.MatchingPolicy.Destination.Hostname())
|
||||
var hostname string
|
||||
if len(reply.MatchingPolicy.Destinations) > 0 {
|
||||
hostname = reply.MatchingPolicy.Destinations[0].Hostname()
|
||||
}
|
||||
audience := fmt.Sprintf("https://%s", hostname)
|
||||
|
||||
src, err := getGoogleCloudServerlessTokenSource(serviceAccount, audience)
|
||||
if err != nil {
|
||||
|
|
|
@ -456,6 +456,14 @@ func mustParseURL(str string) *url.URL {
|
|||
return u
|
||||
}
|
||||
|
||||
func mustParseURLs(strs ...string) []*url.URL {
|
||||
var us []*url.URL
|
||||
for _, str := range strs {
|
||||
us = append(us, mustParseURL(str))
|
||||
}
|
||||
return us
|
||||
}
|
||||
|
||||
type mockDataBrokerServiceClient struct {
|
||||
databroker.DataBrokerServiceClient
|
||||
|
||||
|
|
135
config/custom.go
Normal file
135
config/custom.go
Normal file
|
@ -0,0 +1,135 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
// A StringSlice is a slice of strings.
|
||||
type StringSlice []string
|
||||
|
||||
// NewStringSlice creatse a new StringSlice.
|
||||
func NewStringSlice(values ...string) StringSlice {
|
||||
return StringSlice(values)
|
||||
}
|
||||
|
||||
const (
|
||||
array = iota
|
||||
arrayValue
|
||||
object
|
||||
objectKey
|
||||
objectValue
|
||||
)
|
||||
|
||||
// UnmarshalJSON unmarshals a JSON document into the string slice.
|
||||
func (slc *StringSlice) UnmarshalJSON(data []byte) error {
|
||||
typeStack := []int{array}
|
||||
stateStack := []int{arrayValue}
|
||||
|
||||
var vals []string
|
||||
dec := json.NewDecoder(bytes.NewReader(data))
|
||||
for {
|
||||
token, err := dec.Token()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
if delim, ok := token.(json.Delim); ok {
|
||||
switch delim {
|
||||
case '[':
|
||||
typeStack = append(typeStack, array)
|
||||
stateStack = append(stateStack, arrayValue)
|
||||
case '{':
|
||||
typeStack = append(typeStack, object)
|
||||
stateStack = append(stateStack, objectKey)
|
||||
case ']', '}':
|
||||
typeStack = typeStack[:len(typeStack)-1]
|
||||
stateStack = stateStack[:len(stateStack)-1]
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
switch stateStack[len(stateStack)-1] {
|
||||
case objectKey:
|
||||
stateStack[len(stateStack)-1] = objectValue
|
||||
case objectValue:
|
||||
stateStack[len(stateStack)-1] = objectKey
|
||||
fallthrough
|
||||
default:
|
||||
switch t := token.(type) {
|
||||
case bool:
|
||||
vals = append(vals, fmt.Sprint(t))
|
||||
case float64:
|
||||
vals = append(vals, fmt.Sprint(t))
|
||||
case json.Number:
|
||||
vals = append(vals, fmt.Sprint(t))
|
||||
case string:
|
||||
vals = append(vals, t)
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
*slc = StringSlice(vals)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalYAML unmarshals a YAML document into the string slice. UnmarshalJSON is
|
||||
// reused as the actual implementation.
|
||||
func (slc *StringSlice) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
var i interface{}
|
||||
err := unmarshal(&i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bs, err := json.Marshal(i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return slc.UnmarshalJSON(bs)
|
||||
}
|
||||
|
||||
// DecodeOptionsHookFunc returns a decode hook that will attempt to convert any type to a StringSlice.
|
||||
func DecodeOptionsHookFunc() mapstructure.DecodeHookFunc {
|
||||
return func(f, t reflect.Type, data interface{}) (interface{}, error) {
|
||||
if t != reflect.TypeOf(Options{}) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
m, ok := data.(map[string]interface{})
|
||||
if !ok {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
ps, ok := m["policy"].([]interface{})
|
||||
if !ok {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
for _, p := range ps {
|
||||
pm, ok := p.(map[interface{}]interface{})
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
rawTo, ok := pm["to"]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
rawBS, err := json.Marshal(rawTo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var slc StringSlice
|
||||
err = json.Unmarshal(rawBS, &slc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pm["to"] = slc
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
}
|
39
config/custom_test.go
Normal file
39
config/custom_test.go
Normal file
|
@ -0,0 +1,39 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func TestStringSlice_UnmarshalJSON(t *testing.T) {
|
||||
t.Run("string", func(t *testing.T) {
|
||||
var slc StringSlice
|
||||
json.Unmarshal([]byte(`"hello world"`), &slc)
|
||||
assert.Equal(t, NewStringSlice("hello world"), slc)
|
||||
})
|
||||
t.Run("array", func(t *testing.T) {
|
||||
var slc StringSlice
|
||||
json.Unmarshal([]byte(`["a","b","c"]`), &slc)
|
||||
assert.Equal(t, NewStringSlice("a", "b", "c"), slc)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStringSlice_UnmarshalYAML(t *testing.T) {
|
||||
t.Run("string", func(t *testing.T) {
|
||||
var slc StringSlice
|
||||
yaml.Unmarshal([]byte(`hello world`), &slc)
|
||||
assert.Equal(t, NewStringSlice("hello world"), slc)
|
||||
})
|
||||
t.Run("array", func(t *testing.T) {
|
||||
var slc StringSlice
|
||||
yaml.Unmarshal([]byte(`
|
||||
- a
|
||||
- b
|
||||
- c
|
||||
`), &slc)
|
||||
assert.Equal(t, NewStringSlice("a", "b", "c"), slc)
|
||||
})
|
||||
}
|
|
@ -15,6 +15,7 @@ import (
|
|||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
|
@ -360,7 +361,11 @@ func optionsFromViper(configFile string) (*Options, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if err := v.Unmarshal(o); err != nil {
|
||||
if err := v.Unmarshal(o, viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(
|
||||
mapstructure.StringToTimeDurationHookFunc(),
|
||||
mapstructure.StringToSliceHookFunc(","),
|
||||
DecodeOptionsHookFunc(),
|
||||
))); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal config: %w", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -161,7 +161,17 @@ func Test_parsePolicyFile(t *testing.T) {
|
|||
want []Policy
|
||||
wantErr bool
|
||||
}{
|
||||
{"simple json", []byte(fmt.Sprintf(`{"policy":[{"from": "%s","to":"%s"}]}`, source, dest)), []Policy{{From: source, To: dest, Source: &StringURL{sourceURL}, Destination: destURL}}, false},
|
||||
{
|
||||
"simple json",
|
||||
[]byte(fmt.Sprintf(`{"policy":[{"from": "%s","to":"%s"}]}`, source, dest)),
|
||||
[]Policy{{
|
||||
From: source,
|
||||
To: NewStringSlice(dest),
|
||||
Source: &StringURL{sourceURL},
|
||||
Destinations: []*url.URL{destURL},
|
||||
}},
|
||||
false,
|
||||
},
|
||||
{"bad from", []byte(`{"policy":[{"from": "%","to":"httpbin.org"}]}`), nil, true},
|
||||
{"bad to", []byte(`{"policy":[{"from": "pomerium.io","to":"%"}]}`), nil, true},
|
||||
}
|
||||
|
@ -214,7 +224,7 @@ func Test_Checksum(t *testing.T) {
|
|||
func TestOptionsFromViper(t *testing.T) {
|
||||
opts := []cmp.Option{
|
||||
cmpopts.IgnoreFields(Options{}, "CookieSecret", "GRPCInsecure", "GRPCAddr", "DataBrokerURLString", "DataBrokerURL", "AuthorizeURL", "AuthorizeURLString", "DefaultUpstreamTimeout", "CookieExpire", "Services", "Addr", "RefreshCooldown", "LogLevel", "KeyFile", "CertFile", "SharedKey", "ReadTimeout", "IdleTimeout", "GRPCClientTimeout", "GRPCClientDNSRoundRobin", "TracingSampleRate"),
|
||||
cmpopts.IgnoreFields(Policy{}, "Source", "Destination"),
|
||||
cmpopts.IgnoreFields(Policy{}, "Source", "Destinations"),
|
||||
cmpOptIgnoreUnexported,
|
||||
}
|
||||
|
||||
|
@ -228,7 +238,7 @@ func TestOptionsFromViper(t *testing.T) {
|
|||
"good",
|
||||
[]byte(`{"autocert_dir":"","insecure_server":true,"policy":[{"from": "https://from.example","to":"https://to.example"}]}`),
|
||||
&Options{
|
||||
Policies: []Policy{{From: "https://from.example", To: "https://to.example"}},
|
||||
Policies: []Policy{{From: "https://from.example", To: NewStringSlice("https://to.example")}},
|
||||
CookieName: "_pomerium",
|
||||
CookieSecure: true,
|
||||
InsecureServer: true,
|
||||
|
@ -252,7 +262,7 @@ func TestOptionsFromViper(t *testing.T) {
|
|||
"good disable header",
|
||||
[]byte(`{"autocert_dir":"","insecure_server":true,"headers": {"disable":"true"},"policy":[{"from": "https://from.example","to":"https://to.example"}]}`),
|
||||
&Options{
|
||||
Policies: []Policy{{From: "https://from.example", To: "https://to.example"}},
|
||||
Policies: []Policy{{From: "https://from.example", To: NewStringSlice("https://to.example")}},
|
||||
CookieName: "_pomerium",
|
||||
AuthenticateCallbackPath: "/oauth2/callback",
|
||||
CookieSecure: true,
|
||||
|
|
|
@ -24,8 +24,8 @@ import (
|
|||
|
||||
// Policy contains route specific configuration and access settings.
|
||||
type Policy struct {
|
||||
From string `mapstructure:"from" yaml:"from"`
|
||||
To string `mapstructure:"to" yaml:"to"`
|
||||
From string `mapstructure:"from" yaml:"from"`
|
||||
To StringSlice `mapstructure:"to" yaml:"to"`
|
||||
|
||||
// Redirect is used for a redirect action instead of `To`
|
||||
Redirect *PolicyRedirect `mapstructure:"redirect" yaml:"redirect"`
|
||||
|
@ -36,8 +36,8 @@ type Policy struct {
|
|||
AllowedDomains []string `mapstructure:"allowed_domains" yaml:"allowed_domains,omitempty" json:"allowed_domains,omitempty"`
|
||||
AllowedIDPClaims identity.FlattenedClaims `mapstructure:"allowed_idp_claims" yaml:"allowed_idp_claims,omitempty" json:"allowed_idp_claims,omitempty"`
|
||||
|
||||
Source *StringURL `yaml:",omitempty" json:"source,omitempty" hash:"ignore"`
|
||||
Destination *url.URL `yaml:",omitempty" json:"destination,omitempty" hash:"ignore"`
|
||||
Source *StringURL `yaml:",omitempty" json:"source,omitempty" hash:"ignore"`
|
||||
Destinations []*url.URL `yaml:",omitempty" json:"destinations,omitempty" hash:"ignore"`
|
||||
|
||||
// Additional route matching options
|
||||
Prefix string `mapstructure:"prefix" yaml:"prefix,omitempty" json:"prefix,omitempty"`
|
||||
|
@ -175,7 +175,7 @@ func NewPolicyFromProto(pb *configpb.Route) (*Policy, error) {
|
|||
|
||||
p := &Policy{
|
||||
From: pb.GetFrom(),
|
||||
To: pb.GetTo(),
|
||||
To: NewStringSlice(pb.GetTo()...),
|
||||
AllowedUsers: pb.GetAllowedUsers(),
|
||||
AllowedGroups: pb.GetAllowedGroups(),
|
||||
AllowedDomains: pb.GetAllowedDomains(),
|
||||
|
@ -360,10 +360,14 @@ func (p *Policy) Validate() error {
|
|||
p.Source = &StringURL{source}
|
||||
|
||||
switch {
|
||||
case p.To != "":
|
||||
p.Destination, err = urlutil.ParseAndValidateURL(p.To)
|
||||
if err != nil {
|
||||
return fmt.Errorf("config: policy bad destination url %w", err)
|
||||
case len(p.To) > 0:
|
||||
p.Destinations = nil
|
||||
for _, to := range p.To {
|
||||
dst, err := urlutil.ParseAndValidateURL(to)
|
||||
if err != nil {
|
||||
return fmt.Errorf("config: policy bad destination url %w", err)
|
||||
}
|
||||
p.Destinations = append(p.Destinations, dst)
|
||||
}
|
||||
case p.Redirect != nil:
|
||||
default:
|
||||
|
@ -436,21 +440,25 @@ func (p *Policy) Checksum() uint64 {
|
|||
// RouteID returns a unique identifier for a route
|
||||
func (p *Policy) RouteID() uint64 {
|
||||
id := routeID{
|
||||
Source: p.Source,
|
||||
Destination: p.Destination,
|
||||
Prefix: p.Prefix,
|
||||
Path: p.Path,
|
||||
Regex: p.Regex,
|
||||
Source: p.Source,
|
||||
Destinations: p.Destinations,
|
||||
Prefix: p.Prefix,
|
||||
Path: p.Path,
|
||||
Regex: p.Regex,
|
||||
}
|
||||
|
||||
return hashutil.MustHash(id)
|
||||
}
|
||||
|
||||
func (p *Policy) String() string {
|
||||
if p.Source == nil || p.Destination == nil {
|
||||
return fmt.Sprintf("%s → %s", p.From, p.To)
|
||||
if p.Source == nil || len(p.Destinations) == 0 {
|
||||
return fmt.Sprintf("%s → %s", p.From, strings.Join(p.To, ","))
|
||||
}
|
||||
return fmt.Sprintf("%s → %s", p.Source.String(), p.Destination.String())
|
||||
var dsts []string
|
||||
for _, dst := range p.Destinations {
|
||||
dsts = append(dsts, dst.String())
|
||||
}
|
||||
return fmt.Sprintf("%s → %s", p.Source.String(), strings.Join(dsts, ","))
|
||||
}
|
||||
|
||||
// Matches returns true if the policy would match the given URL.
|
||||
|
@ -497,9 +505,9 @@ func (u *StringURL) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
|
||||
type routeID struct {
|
||||
Source *StringURL
|
||||
Destination *url.URL
|
||||
Prefix string
|
||||
Path string
|
||||
Regex string
|
||||
Source *StringURL
|
||||
Destinations []*url.URL
|
||||
Prefix string
|
||||
Path string
|
||||
Regex string
|
||||
}
|
||||
|
|
|
@ -16,34 +16,34 @@ func Test_PolicyValidate(t *testing.T) {
|
|||
policy Policy
|
||||
wantErr bool
|
||||
}{
|
||||
{"good", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld"}, false},
|
||||
{"empty to host", Policy{From: "https://httpbin.corp.example", To: "https://"}, true},
|
||||
{"empty from host", Policy{From: "https://", To: "https://httpbin.corp.example"}, true},
|
||||
{"empty from scheme", Policy{From: "httpbin.corp.example", To: "https://httpbin.corp.example"}, true},
|
||||
{"empty to scheme", Policy{From: "https://httpbin.corp.example", To: "//httpbin.corp.example"}, true},
|
||||
{"path in from", Policy{From: "https://httpbin.corp.example/some/path", To: "https://httpbin.corp.example"}, true},
|
||||
{"cors policy", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", CORSAllowPreflight: true}, false},
|
||||
{"public policy", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", AllowPublicUnauthenticatedAccess: true}, false},
|
||||
{"public and whitelist", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", AllowPublicUnauthenticatedAccess: true, AllowedUsers: []string{"test@domain.example"}}, true},
|
||||
{"route must have", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", AllowPublicUnauthenticatedAccess: true, AllowedUsers: []string{"test@domain.example"}}, true},
|
||||
{"any authenticated user policy", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", AllowAnyAuthenticatedUser: true}, false},
|
||||
{"any authenticated user and whitelist", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", AllowAnyAuthenticatedUser: true, AllowedUsers: []string{"test@domain.example"}}, true},
|
||||
{"good client cert", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSClientKey: "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", TLSClientCert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJVENDQWdtZ0F3SUJBZ0lSQVBqTEJxS1lwcWU0ekhQc0dWdFR6T0F3RFFZSktvWklodmNOQVFFTEJRQXcKRWpFUU1BNEdBMVVFQXhNSFoyOXZaQzFqWVRBZUZ3MHhPVEE0TVRBeE9EUTVOREJhRncweU1UQXlNVEF4TnpRdwpNREZhTUJNeEVUQVBCZ05WQkFNVENIQnZiV1Z5YVhWdE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQTY3S2pxbVFZR3EwTVZ0QUNWcGVDbVhtaW5sUWJEUEdMbXNaQVVFd3VlSFFucnQzV3R2cEQKT202QWxhSk1VblcrSHU1NWpqb2thbEtlVmpUS21nWUdicVV6VkRvTWJQRGFIZWtsdGRCVE1HbE9VRnNQNFVKUwpEck80emROK3pvNDI4VFgyUG5HMkZDZFZLR3k0UEU4aWxIYldMY3I4NzFZalY1MWZ3OENMRFg5UFpKTnU4NjFDCkY3VjlpRUptNnNTZlFsbW5oTjhqMytXelZiUFFOeTFXc1I3aTllOWo2M0VxS3QyMlE5T1hMK1dBY0tza29JU20KQ05WUlVBalU4WVJWY2dRSkIrelEzNEFRUGx6ME9wNU8vUU4vTWVkamFGOHdMUytpdi96dmlTOGNxUGJ4bzZzTApxNkZOVGx0ay9Ra3hlQ2VLS1RRZS8za1BZdlFBZG5sNjVRSURBUUFCbzNFd2J6QU9CZ05WSFE4QkFmOEVCQU1DCkE3Z3dIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUIwR0ExVWREZ1FXQkJRQ1FYbWIKc0hpcS9UQlZUZVhoQ0dpNjhrVy9DakFmQmdOVkhTTUVHREFXZ0JSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOdVhWegpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBcm9XL2trMllleFN5NEhaQXFLNDVZaGQ5ay9QVTFiaDlFK1BRCk5jZFgzTUdEY2NDRUFkc1k4dll3NVE1cnhuMGFzcSt3VGFCcGxoYS9rMi9VVW9IQ1RqUVp1Mk94dEF3UTdPaWIKVE1tMEorU3NWT3d4YnFQTW9rK1RqVE16NFdXaFFUTzVwRmNoZDZXZXNCVHlJNzJ0aG1jcDd1c2NLU2h3YktIegpQY2h1QTQ4SzhPdi96WkxmZnduQVNZb3VCczJjd1ZiRDI3ZXZOMzdoMGFzR1BrR1VXdm1PSDduTHNVeTh3TTdqCkNGL3NwMmJmTC9OYVdNclJnTHZBMGZMS2pwWTQrVEpPbkVxQmxPcCsrbHlJTEZMcC9qMHNybjRNUnlKK0t6UTEKR1RPakVtQ1QvVEFtOS9XSThSL0FlYjcwTjEzTytYNEtaOUJHaDAxTzN3T1Vqd3BZZ3lxSnNoRnNRUG50VmMrSQpKQmF4M2VQU3NicUcwTFkzcHdHUkpRNmMrd1lxdGk2Y0tNTjliYlRkMDhCNUk1N1RRTHhNcUoycTFnWmw1R1VUCmVFZGNWRXltMnZmd0NPd0lrbGNBbThxTm5kZGZKV1FabE5VaHNOVWFBMkVINnlDeXdaZm9aak9hSDEwTXowV20KeTNpZ2NSZFQ3Mi9NR2VkZk93MlV0MVVvRFZmdEcxcysrditUQ1lpNmpUQU05dkZPckJ4UGlOeGFkUENHR2NZZAowakZIc2FWOGFPV1dQQjZBQ1JteHdDVDdRTnRTczM2MlpIOUlFWWR4Q00yMDUrZmluVHhkOUcwSmVRRTd2Kyt6CldoeWo2ZmJBWUIxM2wvN1hkRnpNSW5BOGxpekdrVHB2RHMxeTBCUzlwV3ppYmhqbVFoZGZIejdCZGpGTHVvc2wKZzlNZE5sND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="}, false},
|
||||
{"bad base64 client cert", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSClientKey: "!=", TLSClientCert: "!="}, true},
|
||||
{"bad one client cert empty", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSClientKey: "", TLSClientCert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJVENDQWdtZ0F3SUJBZ0lSQVBqTEJxS1lwcWU0ekhQc0dWdFR6T0F3RFFZSktvWklodmNOQVFFTEJRQXcKRWpFUU1BNEdBMVVFQXhNSFoyOXZaQzFqWVRBZUZ3MHhPVEE0TVRBeE9EUTVOREJhRncweU1UQXlNVEF4TnpRdwpNREZhTUJNeEVUQVBCZ05WQkFNVENIQnZiV1Z5YVhWdE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQTY3S2pxbVFZR3EwTVZ0QUNWcGVDbVhtaW5sUWJEUEdMbXNaQVVFd3VlSFFucnQzV3R2cEQKT202QWxhSk1VblcrSHU1NWpqb2thbEtlVmpUS21nWUdicVV6VkRvTWJQRGFIZWtsdGRCVE1HbE9VRnNQNFVKUwpEck80emROK3pvNDI4VFgyUG5HMkZDZFZLR3k0UEU4aWxIYldMY3I4NzFZalY1MWZ3OENMRFg5UFpKTnU4NjFDCkY3VjlpRUptNnNTZlFsbW5oTjhqMytXelZiUFFOeTFXc1I3aTllOWo2M0VxS3QyMlE5T1hMK1dBY0tza29JU20KQ05WUlVBalU4WVJWY2dRSkIrelEzNEFRUGx6ME9wNU8vUU4vTWVkamFGOHdMUytpdi96dmlTOGNxUGJ4bzZzTApxNkZOVGx0ay9Ra3hlQ2VLS1RRZS8za1BZdlFBZG5sNjVRSURBUUFCbzNFd2J6QU9CZ05WSFE4QkFmOEVCQU1DCkE3Z3dIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUIwR0ExVWREZ1FXQkJRQ1FYbWIKc0hpcS9UQlZUZVhoQ0dpNjhrVy9DakFmQmdOVkhTTUVHREFXZ0JSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOdVhWegpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBcm9XL2trMllleFN5NEhaQXFLNDVZaGQ5ay9QVTFiaDlFK1BRCk5jZFgzTUdEY2NDRUFkc1k4dll3NVE1cnhuMGFzcSt3VGFCcGxoYS9rMi9VVW9IQ1RqUVp1Mk94dEF3UTdPaWIKVE1tMEorU3NWT3d4YnFQTW9rK1RqVE16NFdXaFFUTzVwRmNoZDZXZXNCVHlJNzJ0aG1jcDd1c2NLU2h3YktIegpQY2h1QTQ4SzhPdi96WkxmZnduQVNZb3VCczJjd1ZiRDI3ZXZOMzdoMGFzR1BrR1VXdm1PSDduTHNVeTh3TTdqCkNGL3NwMmJmTC9OYVdNclJnTHZBMGZMS2pwWTQrVEpPbkVxQmxPcCsrbHlJTEZMcC9qMHNybjRNUnlKK0t6UTEKR1RPakVtQ1QvVEFtOS9XSThSL0FlYjcwTjEzTytYNEtaOUJHaDAxTzN3T1Vqd3BZZ3lxSnNoRnNRUG50VmMrSQpKQmF4M2VQU3NicUcwTFkzcHdHUkpRNmMrd1lxdGk2Y0tNTjliYlRkMDhCNUk1N1RRTHhNcUoycTFnWmw1R1VUCmVFZGNWRXltMnZmd0NPd0lrbGNBbThxTm5kZGZKV1FabE5VaHNOVWFBMkVINnlDeXdaZm9aak9hSDEwTXowV20KeTNpZ2NSZFQ3Mi9NR2VkZk93MlV0MVVvRFZmdEcxcysrditUQ1lpNmpUQU05dkZPckJ4UGlOeGFkUENHR2NZZAowakZIc2FWOGFPV1dQQjZBQ1JteHdDVDdRTnRTczM2MlpIOUlFWWR4Q00yMDUrZmluVHhkOUcwSmVRRTd2Kyt6CldoeWo2ZmJBWUIxM2wvN1hkRnpNSW5BOGxpekdrVHB2RHMxeTBCUzlwV3ppYmhqbVFoZGZIejdCZGpGTHVvc2wKZzlNZE5sND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="}, true},
|
||||
{"bad th other client cert empty", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSClientKey: "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", TLSClientCert: ""}, true},
|
||||
{"good root ca pool", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSCustomCA: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUU1RENDQXN5Z0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBREFTTVJBd0RnWURWUVFERXdkbmIyOWsKTFdOaE1CNFhEVEU1TURneE1ERTNOREF3TWxvWERUSXhNREl4TURFM05EQXdNbG93RWpFUU1BNEdBMVVFQXhNSApaMjl2WkMxallUQ0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQUw3b2VldEovNmNFCkdicTcvanNtcU9FM2VyVE1aRHR0eFM4STVGV1c0TkRXbWNpOE5IdWRMZDhlM1JtOEh6Y09jSjRQL0ErcDVsYmsKTjhySzY4OUlsQzhqM28yaEhSdEk2T21saFY3NEoxaUlIOGtkSXU2V2xPMWtOdUx5dGRrbjhRaytJOUNEWjlGSAorZzhRbnVka0tMUWJkZFdDVXJzUjR4cEcyK0VkNWdua0JJNG4zbmNLMFgvWEZocWhDTEU1eFBaQk5OWktGbHJxCm1lYUl4dHoyc2ZvWVY1NmcwMnNGS1QxSUlMNTVFMG14djRUa2JtSWw5Rk9qZEtCdkhFZnJHeXl5OFRGTHErUzMKTXo2em9xNDhuOEhGMUc5cHBLVk9OMUp0Mks1UWEvV2hpbjVrcWNhYTNwNE0vN2tiNmtxU0tMWG1iN0gyN3kvVQpEYjZDUG01d2lodjA2c1FobXN2MHhuS2hqMm8vQzhlcWxzNzZZWDF1Y2NqMzlmSTRlQ1E4cENFbTlVcDh5ZkkvCkxlYVpXbGE0NEZneWw3N1lyc2MvM0U5dk1hS0ZVeGRjR3VtMXQrNUZZYWpkY0EvTlFreTJBeTJqcHRwVXV1SFUKNnhYSzdEcXY5Z01jQS8zM1VYOFpHZklPRk0rY3FlOTQxaTVPT1hGSHJoRDlqeTRQR2M4Z2kxSTRyK1VXd0tCYgoxSGg1clQ3ckJZK1NLTTBzZmtpQlZ1RU9pbnk2dDF1Z2tEdjY4dXNFWFlIWlZXaWl6b1hmcDVHbjZmckUvd1IxCkRkak13TGEvT2tQTnVEVVQ4eU1GS2hWRnFHcXdHQzY2bys1cjQyMlVwa0s4SHJ5K2tsQ3pUTys3U0RodTJiWk4KUVFGT0NLSVVldnR3bGdabVBNck1BNTZ3dzVSSnNhVnhBZ01CQUFHalJUQkRNQTRHQTFVZER3RUIvd1FFQXdJQgpCakFTQmdOVkhSTUJBZjhFQ0RBR0FRSC9BZ0VBTUIwR0ExVWREZ1FXQkJSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOCnVYVnpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBZituUmpBVnZuT0pSckpBQWpKWVY3aVF3bHExUXZYRGcKbHZhY0JoVFJyWFh4OW5GaVRZUzV4MkFMbXZ5WHhubTdIS2VDSUZEclJwOE5MVFkyYjJXR01BcTFxc3JBT0QvegpTNmNSSW1OQ21QNmd0UHNUNDlabzBYajNrZjZyTXBPeHBiSUlnSmZMY056UGZpL25jeC9oRDNBOHl6Zk4wQTZZCnFFd2QvSkZPajdEa3RaQmdlSXZETlJXS0pveEpJRlZ4anJqLzFiVmkxZTRWVjVvWmhOako4SzlyV1FRK1EvK3QKZ3lGK0sycGxDQ1RiRWR6eU9heDY1djh5UDJ5RCs2WkFIRk9sRjI2TnZpUkw4OWJ1VHIwaEpZa0N5VXZ3MmJZaQo4Q3MyWDZkd0NDdXVhZUdVR2VRemszMGxQeUdWSmVKL3ZJMGJRSzlpZ2I5dFozY3d0WHBQdjN6a1B1TDE3d01WCitCMXo2RW1HZVVLNXlTQ0xFWjc2aVliNU0vY3ZjTUVOMWdoeFNIN0FmaDhMS0c0eWszT21SQ253akVqdTFhaWoKZGs3cjJuc0xmYU9KWFBRNU1wMzRYU1ltdTlpTVl0VytMbWZiSDJxMW9vS3dKZDhHNVhhRWRmQmpHUEQ5Q3FkWAphSlh0MDA0cVdsalJOS3p1MFNFRmJ6UldGNHRoeXlUTzE4QVI4eTNHV0Vwak95amdKSzlFeU1sQm9Qa3RYQVVVCjZzTFhqT3ZZU0ovd202NUhxVVZBTTVsRy96WVN3TGdCTDAwc1pJKzVGa0QwblU0Rkx6QWRLV05LWkRXZFVNbUwKVi9lV0ZGNGwwVFBvNTVhM0pUL1BGc2J0RFBLVWxvWVFXeTFybmFqR3J1L0Y5bGRCcHB1bUVUa2FOS2ZWT05Jcgp4cERnc1FhVkVXOD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="}, false},
|
||||
{"bad root ca pool", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSCustomCA: "!"}, true},
|
||||
{"good custom ca file", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSCustomCAFile: "testdata/ca.pem"}, false},
|
||||
{"bad custom ca file", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSCustomCAFile: "testdata/404.pem"}, true},
|
||||
{"good client certificate files", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSClientCertFile: "testdata/example-cert.pem", TLSClientKeyFile: "testdata/example-key.pem"}, false},
|
||||
{"bad certificate file", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSClientCertFile: "testdata/example-cert-404.pem", TLSClientKeyFile: "testdata/example-key.pem"}, true},
|
||||
{"bad key file", Policy{From: "https://httpbin.corp.example", To: "https://httpbin.corp.notatld", TLSClientCertFile: "testdata/example-cert.pem", TLSClientKeyFile: "testdata/example-key-404.pem"}, true},
|
||||
{"good tls server name", Policy{From: "https://httpbin.corp.example", To: "https://internal-host-name", TLSServerName: "httpbin.corp.notatld"}, false},
|
||||
{"good kube service account token file", Policy{From: "https://httpbin.corp.example", To: "https://internal-host-name", KubernetesServiceAccountTokenFile: "testdata/kubeserviceaccount.token"}, false},
|
||||
{"bad kube service account token file", Policy{From: "https://httpbin.corp.example", To: "https://internal-host-name", KubernetesServiceAccountTokenFile: "testdata/missing.token"}, true},
|
||||
{"good kube service account token", Policy{From: "https://httpbin.corp.example", To: "https://internal-host-name", KubernetesServiceAccountToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1OTY1MDk4MjIsImV4cCI6MTYyODA0NTgyMiwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.H0I6ccQrL6sKobsKQj9dqNcLw_INhU9_xJsVyCkgkiY"}, false},
|
||||
{"bad kube service account token and file", Policy{From: "https://httpbin.corp.example", To: "https://internal-host-name", KubernetesServiceAccountToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1OTY1MDk4MjIsImV4cCI6MTYyODA0NTgyMiwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.H0I6ccQrL6sKobsKQj9dqNcLw_INhU9_xJsVyCkgkiY", KubernetesServiceAccountTokenFile: "testdata/kubeserviceaccount.token"}, true},
|
||||
{"good", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld")}, false},
|
||||
{"empty to host", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://")}, true},
|
||||
{"empty from host", Policy{From: "https://", To: NewStringSlice("https://httpbin.corp.example")}, true},
|
||||
{"empty from scheme", Policy{From: "httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.example")}, true},
|
||||
{"empty to scheme", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("//httpbin.corp.example")}, true},
|
||||
{"path in from", Policy{From: "https://httpbin.corp.example/some/path", To: NewStringSlice("https://httpbin.corp.example")}, true},
|
||||
{"cors policy", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), CORSAllowPreflight: true}, false},
|
||||
{"public policy", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), AllowPublicUnauthenticatedAccess: true}, false},
|
||||
{"public and whitelist", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), AllowPublicUnauthenticatedAccess: true, AllowedUsers: []string{"test@domain.example"}}, true},
|
||||
{"route must have", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), AllowPublicUnauthenticatedAccess: true, AllowedUsers: []string{"test@domain.example"}}, true},
|
||||
{"any authenticated user policy", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), AllowAnyAuthenticatedUser: true}, false},
|
||||
{"any authenticated user and whitelist", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), AllowAnyAuthenticatedUser: true, AllowedUsers: []string{"test@domain.example"}}, true},
|
||||
{"good client cert", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), TLSClientKey: "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", TLSClientCert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJVENDQWdtZ0F3SUJBZ0lSQVBqTEJxS1lwcWU0ekhQc0dWdFR6T0F3RFFZSktvWklodmNOQVFFTEJRQXcKRWpFUU1BNEdBMVVFQXhNSFoyOXZaQzFqWVRBZUZ3MHhPVEE0TVRBeE9EUTVOREJhRncweU1UQXlNVEF4TnpRdwpNREZhTUJNeEVUQVBCZ05WQkFNVENIQnZiV1Z5YVhWdE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQTY3S2pxbVFZR3EwTVZ0QUNWcGVDbVhtaW5sUWJEUEdMbXNaQVVFd3VlSFFucnQzV3R2cEQKT202QWxhSk1VblcrSHU1NWpqb2thbEtlVmpUS21nWUdicVV6VkRvTWJQRGFIZWtsdGRCVE1HbE9VRnNQNFVKUwpEck80emROK3pvNDI4VFgyUG5HMkZDZFZLR3k0UEU4aWxIYldMY3I4NzFZalY1MWZ3OENMRFg5UFpKTnU4NjFDCkY3VjlpRUptNnNTZlFsbW5oTjhqMytXelZiUFFOeTFXc1I3aTllOWo2M0VxS3QyMlE5T1hMK1dBY0tza29JU20KQ05WUlVBalU4WVJWY2dRSkIrelEzNEFRUGx6ME9wNU8vUU4vTWVkamFGOHdMUytpdi96dmlTOGNxUGJ4bzZzTApxNkZOVGx0ay9Ra3hlQ2VLS1RRZS8za1BZdlFBZG5sNjVRSURBUUFCbzNFd2J6QU9CZ05WSFE4QkFmOEVCQU1DCkE3Z3dIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUIwR0ExVWREZ1FXQkJRQ1FYbWIKc0hpcS9UQlZUZVhoQ0dpNjhrVy9DakFmQmdOVkhTTUVHREFXZ0JSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOdVhWegpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBcm9XL2trMllleFN5NEhaQXFLNDVZaGQ5ay9QVTFiaDlFK1BRCk5jZFgzTUdEY2NDRUFkc1k4dll3NVE1cnhuMGFzcSt3VGFCcGxoYS9rMi9VVW9IQ1RqUVp1Mk94dEF3UTdPaWIKVE1tMEorU3NWT3d4YnFQTW9rK1RqVE16NFdXaFFUTzVwRmNoZDZXZXNCVHlJNzJ0aG1jcDd1c2NLU2h3YktIegpQY2h1QTQ4SzhPdi96WkxmZnduQVNZb3VCczJjd1ZiRDI3ZXZOMzdoMGFzR1BrR1VXdm1PSDduTHNVeTh3TTdqCkNGL3NwMmJmTC9OYVdNclJnTHZBMGZMS2pwWTQrVEpPbkVxQmxPcCsrbHlJTEZMcC9qMHNybjRNUnlKK0t6UTEKR1RPakVtQ1QvVEFtOS9XSThSL0FlYjcwTjEzTytYNEtaOUJHaDAxTzN3T1Vqd3BZZ3lxSnNoRnNRUG50VmMrSQpKQmF4M2VQU3NicUcwTFkzcHdHUkpRNmMrd1lxdGk2Y0tNTjliYlRkMDhCNUk1N1RRTHhNcUoycTFnWmw1R1VUCmVFZGNWRXltMnZmd0NPd0lrbGNBbThxTm5kZGZKV1FabE5VaHNOVWFBMkVINnlDeXdaZm9aak9hSDEwTXowV20KeTNpZ2NSZFQ3Mi9NR2VkZk93MlV0MVVvRFZmdEcxcysrditUQ1lpNmpUQU05dkZPckJ4UGlOeGFkUENHR2NZZAowakZIc2FWOGFPV1dQQjZBQ1JteHdDVDdRTnRTczM2MlpIOUlFWWR4Q00yMDUrZmluVHhkOUcwSmVRRTd2Kyt6CldoeWo2ZmJBWUIxM2wvN1hkRnpNSW5BOGxpekdrVHB2RHMxeTBCUzlwV3ppYmhqbVFoZGZIejdCZGpGTHVvc2wKZzlNZE5sND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="}, false},
|
||||
{"bad base64 client cert", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), TLSClientKey: "!=", TLSClientCert: "!="}, true},
|
||||
{"bad one client cert empty", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), TLSClientKey: "", TLSClientCert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJVENDQWdtZ0F3SUJBZ0lSQVBqTEJxS1lwcWU0ekhQc0dWdFR6T0F3RFFZSktvWklodmNOQVFFTEJRQXcKRWpFUU1BNEdBMVVFQXhNSFoyOXZaQzFqWVRBZUZ3MHhPVEE0TVRBeE9EUTVOREJhRncweU1UQXlNVEF4TnpRdwpNREZhTUJNeEVUQVBCZ05WQkFNVENIQnZiV1Z5YVhWdE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQTY3S2pxbVFZR3EwTVZ0QUNWcGVDbVhtaW5sUWJEUEdMbXNaQVVFd3VlSFFucnQzV3R2cEQKT202QWxhSk1VblcrSHU1NWpqb2thbEtlVmpUS21nWUdicVV6VkRvTWJQRGFIZWtsdGRCVE1HbE9VRnNQNFVKUwpEck80emROK3pvNDI4VFgyUG5HMkZDZFZLR3k0UEU4aWxIYldMY3I4NzFZalY1MWZ3OENMRFg5UFpKTnU4NjFDCkY3VjlpRUptNnNTZlFsbW5oTjhqMytXelZiUFFOeTFXc1I3aTllOWo2M0VxS3QyMlE5T1hMK1dBY0tza29JU20KQ05WUlVBalU4WVJWY2dRSkIrelEzNEFRUGx6ME9wNU8vUU4vTWVkamFGOHdMUytpdi96dmlTOGNxUGJ4bzZzTApxNkZOVGx0ay9Ra3hlQ2VLS1RRZS8za1BZdlFBZG5sNjVRSURBUUFCbzNFd2J6QU9CZ05WSFE4QkFmOEVCQU1DCkE3Z3dIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUIwR0ExVWREZ1FXQkJRQ1FYbWIKc0hpcS9UQlZUZVhoQ0dpNjhrVy9DakFmQmdOVkhTTUVHREFXZ0JSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOdVhWegpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBcm9XL2trMllleFN5NEhaQXFLNDVZaGQ5ay9QVTFiaDlFK1BRCk5jZFgzTUdEY2NDRUFkc1k4dll3NVE1cnhuMGFzcSt3VGFCcGxoYS9rMi9VVW9IQ1RqUVp1Mk94dEF3UTdPaWIKVE1tMEorU3NWT3d4YnFQTW9rK1RqVE16NFdXaFFUTzVwRmNoZDZXZXNCVHlJNzJ0aG1jcDd1c2NLU2h3YktIegpQY2h1QTQ4SzhPdi96WkxmZnduQVNZb3VCczJjd1ZiRDI3ZXZOMzdoMGFzR1BrR1VXdm1PSDduTHNVeTh3TTdqCkNGL3NwMmJmTC9OYVdNclJnTHZBMGZMS2pwWTQrVEpPbkVxQmxPcCsrbHlJTEZMcC9qMHNybjRNUnlKK0t6UTEKR1RPakVtQ1QvVEFtOS9XSThSL0FlYjcwTjEzTytYNEtaOUJHaDAxTzN3T1Vqd3BZZ3lxSnNoRnNRUG50VmMrSQpKQmF4M2VQU3NicUcwTFkzcHdHUkpRNmMrd1lxdGk2Y0tNTjliYlRkMDhCNUk1N1RRTHhNcUoycTFnWmw1R1VUCmVFZGNWRXltMnZmd0NPd0lrbGNBbThxTm5kZGZKV1FabE5VaHNOVWFBMkVINnlDeXdaZm9aak9hSDEwTXowV20KeTNpZ2NSZFQ3Mi9NR2VkZk93MlV0MVVvRFZmdEcxcysrditUQ1lpNmpUQU05dkZPckJ4UGlOeGFkUENHR2NZZAowakZIc2FWOGFPV1dQQjZBQ1JteHdDVDdRTnRTczM2MlpIOUlFWWR4Q00yMDUrZmluVHhkOUcwSmVRRTd2Kyt6CldoeWo2ZmJBWUIxM2wvN1hkRnpNSW5BOGxpekdrVHB2RHMxeTBCUzlwV3ppYmhqbVFoZGZIejdCZGpGTHVvc2wKZzlNZE5sND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="}, true},
|
||||
{"bad th other client cert empty", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), TLSClientKey: "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", TLSClientCert: ""}, true},
|
||||
{"good root ca pool", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), TLSCustomCA: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUU1RENDQXN5Z0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBREFTTVJBd0RnWURWUVFERXdkbmIyOWsKTFdOaE1CNFhEVEU1TURneE1ERTNOREF3TWxvWERUSXhNREl4TURFM05EQXdNbG93RWpFUU1BNEdBMVVFQXhNSApaMjl2WkMxallUQ0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQUw3b2VldEovNmNFCkdicTcvanNtcU9FM2VyVE1aRHR0eFM4STVGV1c0TkRXbWNpOE5IdWRMZDhlM1JtOEh6Y09jSjRQL0ErcDVsYmsKTjhySzY4OUlsQzhqM28yaEhSdEk2T21saFY3NEoxaUlIOGtkSXU2V2xPMWtOdUx5dGRrbjhRaytJOUNEWjlGSAorZzhRbnVka0tMUWJkZFdDVXJzUjR4cEcyK0VkNWdua0JJNG4zbmNLMFgvWEZocWhDTEU1eFBaQk5OWktGbHJxCm1lYUl4dHoyc2ZvWVY1NmcwMnNGS1QxSUlMNTVFMG14djRUa2JtSWw5Rk9qZEtCdkhFZnJHeXl5OFRGTHErUzMKTXo2em9xNDhuOEhGMUc5cHBLVk9OMUp0Mks1UWEvV2hpbjVrcWNhYTNwNE0vN2tiNmtxU0tMWG1iN0gyN3kvVQpEYjZDUG01d2lodjA2c1FobXN2MHhuS2hqMm8vQzhlcWxzNzZZWDF1Y2NqMzlmSTRlQ1E4cENFbTlVcDh5ZkkvCkxlYVpXbGE0NEZneWw3N1lyc2MvM0U5dk1hS0ZVeGRjR3VtMXQrNUZZYWpkY0EvTlFreTJBeTJqcHRwVXV1SFUKNnhYSzdEcXY5Z01jQS8zM1VYOFpHZklPRk0rY3FlOTQxaTVPT1hGSHJoRDlqeTRQR2M4Z2kxSTRyK1VXd0tCYgoxSGg1clQ3ckJZK1NLTTBzZmtpQlZ1RU9pbnk2dDF1Z2tEdjY4dXNFWFlIWlZXaWl6b1hmcDVHbjZmckUvd1IxCkRkak13TGEvT2tQTnVEVVQ4eU1GS2hWRnFHcXdHQzY2bys1cjQyMlVwa0s4SHJ5K2tsQ3pUTys3U0RodTJiWk4KUVFGT0NLSVVldnR3bGdabVBNck1BNTZ3dzVSSnNhVnhBZ01CQUFHalJUQkRNQTRHQTFVZER3RUIvd1FFQXdJQgpCakFTQmdOVkhSTUJBZjhFQ0RBR0FRSC9BZ0VBTUIwR0ExVWREZ1FXQkJSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOCnVYVnpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBZituUmpBVnZuT0pSckpBQWpKWVY3aVF3bHExUXZYRGcKbHZhY0JoVFJyWFh4OW5GaVRZUzV4MkFMbXZ5WHhubTdIS2VDSUZEclJwOE5MVFkyYjJXR01BcTFxc3JBT0QvegpTNmNSSW1OQ21QNmd0UHNUNDlabzBYajNrZjZyTXBPeHBiSUlnSmZMY056UGZpL25jeC9oRDNBOHl6Zk4wQTZZCnFFd2QvSkZPajdEa3RaQmdlSXZETlJXS0pveEpJRlZ4anJqLzFiVmkxZTRWVjVvWmhOako4SzlyV1FRK1EvK3QKZ3lGK0sycGxDQ1RiRWR6eU9heDY1djh5UDJ5RCs2WkFIRk9sRjI2TnZpUkw4OWJ1VHIwaEpZa0N5VXZ3MmJZaQo4Q3MyWDZkd0NDdXVhZUdVR2VRemszMGxQeUdWSmVKL3ZJMGJRSzlpZ2I5dFozY3d0WHBQdjN6a1B1TDE3d01WCitCMXo2RW1HZVVLNXlTQ0xFWjc2aVliNU0vY3ZjTUVOMWdoeFNIN0FmaDhMS0c0eWszT21SQ253akVqdTFhaWoKZGs3cjJuc0xmYU9KWFBRNU1wMzRYU1ltdTlpTVl0VytMbWZiSDJxMW9vS3dKZDhHNVhhRWRmQmpHUEQ5Q3FkWAphSlh0MDA0cVdsalJOS3p1MFNFRmJ6UldGNHRoeXlUTzE4QVI4eTNHV0Vwak95amdKSzlFeU1sQm9Qa3RYQVVVCjZzTFhqT3ZZU0ovd202NUhxVVZBTTVsRy96WVN3TGdCTDAwc1pJKzVGa0QwblU0Rkx6QWRLV05LWkRXZFVNbUwKVi9lV0ZGNGwwVFBvNTVhM0pUL1BGc2J0RFBLVWxvWVFXeTFybmFqR3J1L0Y5bGRCcHB1bUVUa2FOS2ZWT05Jcgp4cERnc1FhVkVXOD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="}, false},
|
||||
{"bad root ca pool", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), TLSCustomCA: "!"}, true},
|
||||
{"good custom ca file", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), TLSCustomCAFile: "testdata/ca.pem"}, false},
|
||||
{"bad custom ca file", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), TLSCustomCAFile: "testdata/404.pem"}, true},
|
||||
{"good client certificate files", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), TLSClientCertFile: "testdata/example-cert.pem", TLSClientKeyFile: "testdata/example-key.pem"}, false},
|
||||
{"bad certificate file", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), TLSClientCertFile: "testdata/example-cert-404.pem", TLSClientKeyFile: "testdata/example-key.pem"}, true},
|
||||
{"bad key file", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://httpbin.corp.notatld"), TLSClientCertFile: "testdata/example-cert.pem", TLSClientKeyFile: "testdata/example-key-404.pem"}, true},
|
||||
{"good tls server name", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://internal-host-name"), TLSServerName: "httpbin.corp.notatld"}, false},
|
||||
{"good kube service account token file", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://internal-host-name"), KubernetesServiceAccountTokenFile: "testdata/kubeserviceaccount.token"}, false},
|
||||
{"bad kube service account token file", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://internal-host-name"), KubernetesServiceAccountTokenFile: "testdata/missing.token"}, true},
|
||||
{"good kube service account token", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://internal-host-name"), KubernetesServiceAccountToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1OTY1MDk4MjIsImV4cCI6MTYyODA0NTgyMiwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.H0I6ccQrL6sKobsKQj9dqNcLw_INhU9_xJsVyCkgkiY"}, false},
|
||||
{"bad kube service account token and file", Policy{From: "https://httpbin.corp.example", To: NewStringSlice("https://internal-host-name"), KubernetesServiceAccountToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1OTY1MDk4MjIsImV4cCI6MTYyODA0NTgyMiwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.H0I6ccQrL6sKobsKQj9dqNcLw_INhU9_xJsVyCkgkiY", KubernetesServiceAccountTokenFile: "testdata/kubeserviceaccount.token"}, true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
@ -72,7 +72,7 @@ func TestPolicy_String(t *testing.T) {
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
p := &Policy{
|
||||
From: tt.From,
|
||||
To: tt.To,
|
||||
To: NewStringSlice(tt.To),
|
||||
}
|
||||
p.Validate()
|
||||
if got := p.String(); got != tt.want {
|
||||
|
@ -99,20 +99,20 @@ func Test_PolicyRouteID(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
"same",
|
||||
&Policy{From: "https://pomerium.io", To: "http://localhost", AllowedUsers: []string{"foo@bar.com"}},
|
||||
&Policy{From: "https://pomerium.io", To: "http://localhost", AllowedGroups: []string{"allusers"}},
|
||||
&Policy{From: "https://pomerium.io", To: NewStringSlice("http://localhost"), AllowedUsers: []string{"foo@bar.com"}},
|
||||
&Policy{From: "https://pomerium.io", To: NewStringSlice("http://localhost"), AllowedGroups: []string{"allusers"}},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"different from",
|
||||
&Policy{From: "https://pomerium.io", To: "http://localhost"},
|
||||
&Policy{From: "https://notpomerium.io", To: "http://localhost"},
|
||||
&Policy{From: "https://pomerium.io", To: NewStringSlice("http://localhost")},
|
||||
&Policy{From: "https://notpomerium.io", To: NewStringSlice("http://localhost")},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"different path",
|
||||
&Policy{From: "https://pomerium.io", To: "http://localhost"},
|
||||
&Policy{From: "https://pomerium.io", To: "http://localhost", Path: "/foo"},
|
||||
&Policy{From: "https://pomerium.io", To: NewStringSlice("http://localhost")},
|
||||
&Policy{From: "https://pomerium.io", To: NewStringSlice("http://localhost"), Path: "/foo"},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ func Test_PolicyRouteID(t *testing.T) {
|
|||
|
||||
func TestPolicy_Checksum(t *testing.T) {
|
||||
t.Parallel()
|
||||
p := &Policy{From: "https://pomerium.io", To: "http://localhost", AllowedUsers: []string{"foo@bar.com"}}
|
||||
p := &Policy{From: "https://pomerium.io", To: NewStringSlice("http://localhost"), AllowedUsers: []string{"foo@bar.com"}}
|
||||
oldChecksum := p.Checksum()
|
||||
p.AllowedUsers = []string{"foo@pomerium.io"}
|
||||
newChecksum := p.Checksum()
|
||||
|
@ -153,7 +153,7 @@ func TestPolicy_FromToPb(t *testing.T) {
|
|||
t.Parallel()
|
||||
p := &Policy{
|
||||
From: "https://pomerium.io",
|
||||
To: "http://localhost",
|
||||
To: NewStringSlice("http://localhost"),
|
||||
AllowedUsers: []string{"foo@bar.com"},
|
||||
SubPolicies: []SubPolicy{
|
||||
{
|
||||
|
|
|
@ -1273,12 +1273,19 @@ Either `redirect` or `to` must be set.
|
|||
|
||||
### To
|
||||
- `yaml`/`json` setting: `to`
|
||||
- Type: `URL` (must contain a scheme and hostname)
|
||||
- Type: `URL` or list of `URL`s (must contain a scheme and hostname)
|
||||
- Schemes: `http`, `https`, `tcp`
|
||||
- Optional
|
||||
- Example: `http://verify` , `https://192.1.20.12:8080`, `http://neverssl.com`, `https://verify.pomerium.com/anything/`
|
||||
- Example: `http://verify` , `https://192.1.20.12:8080`, `http://neverssl.com`, `https://verify.pomerium.com/anything/`, `["http://a", "http://b"]
|
||||
|
||||
`To` is the destination of a proxied request. It can be an internal resource, or an external resource.
|
||||
`To` is the destination(s) of a proxied request. It can be an internal resource, or an external resource. Multiple upstream resources can be targeted by using a list instead of a single URL:
|
||||
|
||||
```yaml
|
||||
- from: https://example.com
|
||||
to:
|
||||
- https://a.example.com
|
||||
- https://b.example.com
|
||||
```
|
||||
|
||||
Must be `tcp` if `from` is `tcp+https`.
|
||||
|
||||
|
|
|
@ -1401,12 +1401,19 @@ settings:
|
|||
keys: ["to"]
|
||||
attributes: |
|
||||
- `yaml`/`json` setting: `to`
|
||||
- Type: `URL` (must contain a scheme and hostname)
|
||||
- Type: `URL` or list of `URL`s (must contain a scheme and hostname)
|
||||
- Schemes: `http`, `https`, `tcp`
|
||||
- Optional
|
||||
- Example: `http://verify` , `https://192.1.20.12:8080`, `http://neverssl.com`, `https://verify.pomerium.com/anything/`
|
||||
- Example: `http://verify` , `https://192.1.20.12:8080`, `http://neverssl.com`, `https://verify.pomerium.com/anything/`, `["http://a", "http://b"]
|
||||
doc: |
|
||||
`To` is the destination of a proxied request. It can be an internal resource, or an external resource.
|
||||
`To` is the destination(s) of a proxied request. It can be an internal resource, or an external resource. Multiple upstream resources can be targeted by using a list instead of a single URL:
|
||||
|
||||
```yaml
|
||||
- from: https://example.com
|
||||
to:
|
||||
- https://a.example.com
|
||||
- https://b.example.com
|
||||
```
|
||||
|
||||
Must be `tcp` if `from` is `tcp+https`.
|
||||
|
||||
|
|
1
go.mod
1
go.mod
|
@ -35,6 +35,7 @@ require (
|
|||
github.com/lithammer/shortuuid/v3 v3.0.5
|
||||
github.com/martinlindhe/base36 v1.1.0
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.1
|
||||
github.com/mitchellh/mapstructure v1.1.2
|
||||
github.com/natefinch/atomic v0.0.0-20200526193002-18c0533a5b09
|
||||
github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce
|
||||
github.com/onsi/gocleanup v0.0.0-20140331211545-c1a5478700b5
|
||||
|
|
|
@ -145,7 +145,7 @@ func TestConfig(t *testing.T) {
|
|||
_ = li.Close()
|
||||
|
||||
p1 := config.Policy{
|
||||
From: "http://from.example.com", To: "http://to.example.com",
|
||||
From: "http://from.example.com", To: config.NewStringSlice("http://to.example.com"),
|
||||
}
|
||||
_ = p1.Validate()
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ func Test_buildPolicyTransportSocket(t *testing.T) {
|
|||
|
||||
t.Run("insecure", func(t *testing.T) {
|
||||
assert.Nil(t, srv.buildPolicyTransportSocket(&config.Policy{
|
||||
Destination: mustParseURL("http://example.com"),
|
||||
}))
|
||||
Destinations: mustParseURLs("http://example.com"),
|
||||
}, mustParseURL("http://example.com")))
|
||||
})
|
||||
t.Run("host as sni", func(t *testing.T) {
|
||||
testutil.AssertProtoJSONEqual(t, `
|
||||
|
@ -57,8 +57,8 @@ func Test_buildPolicyTransportSocket(t *testing.T) {
|
|||
}
|
||||
}
|
||||
`, srv.buildPolicyTransportSocket(&config.Policy{
|
||||
Destination: mustParseURL("https://example.com"),
|
||||
}))
|
||||
Destinations: mustParseURLs("https://example.com"),
|
||||
}, mustParseURL("https://example.com")))
|
||||
})
|
||||
t.Run("tls_server_name as sni", func(t *testing.T) {
|
||||
testutil.AssertProtoJSONEqual(t, `
|
||||
|
@ -89,9 +89,9 @@ func Test_buildPolicyTransportSocket(t *testing.T) {
|
|||
}
|
||||
}
|
||||
`, srv.buildPolicyTransportSocket(&config.Policy{
|
||||
Destination: mustParseURL("https://example.com"),
|
||||
Destinations: mustParseURLs("https://example.com"),
|
||||
TLSServerName: "use-this-name.example.com",
|
||||
}))
|
||||
}, mustParseURL("https://example.com")))
|
||||
})
|
||||
t.Run("tls_skip_verify", func(t *testing.T) {
|
||||
testutil.AssertProtoJSONEqual(t, `
|
||||
|
@ -123,9 +123,9 @@ func Test_buildPolicyTransportSocket(t *testing.T) {
|
|||
}
|
||||
}
|
||||
`, srv.buildPolicyTransportSocket(&config.Policy{
|
||||
Destination: mustParseURL("https://example.com"),
|
||||
Destinations: mustParseURLs("https://example.com"),
|
||||
TLSSkipVerify: true,
|
||||
}))
|
||||
}, mustParseURL("https://example.com")))
|
||||
})
|
||||
t.Run("custom ca", func(t *testing.T) {
|
||||
testutil.AssertProtoJSONEqual(t, `
|
||||
|
@ -156,9 +156,9 @@ func Test_buildPolicyTransportSocket(t *testing.T) {
|
|||
}
|
||||
}
|
||||
`, srv.buildPolicyTransportSocket(&config.Policy{
|
||||
Destination: mustParseURL("https://example.com"),
|
||||
TLSCustomCA: base64.StdEncoding.EncodeToString([]byte{0, 0, 0, 0}),
|
||||
}))
|
||||
Destinations: mustParseURLs("https://example.com"),
|
||||
TLSCustomCA: base64.StdEncoding.EncodeToString([]byte{0, 0, 0, 0}),
|
||||
}, mustParseURL("https://example.com")))
|
||||
})
|
||||
t.Run("client certificate", func(t *testing.T) {
|
||||
clientCert, _ := cryptutil.CertificateFromBase64(aExampleComCert, aExampleComKey)
|
||||
|
@ -198,9 +198,9 @@ func Test_buildPolicyTransportSocket(t *testing.T) {
|
|||
}
|
||||
}
|
||||
`, srv.buildPolicyTransportSocket(&config.Policy{
|
||||
Destination: mustParseURL("https://example.com"),
|
||||
Destinations: mustParseURLs("https://example.com"),
|
||||
ClientCertificate: clientCert,
|
||||
}))
|
||||
}, mustParseURL("https://example.com")))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,10 @@ func Test_buildCluster(t *testing.T) {
|
|||
rootCAPath, _ := getRootCertificateAuthority()
|
||||
rootCA := srv.filemgr.FileDataSource(rootCAPath).GetFilename()
|
||||
t.Run("insecure", func(t *testing.T) {
|
||||
cluster := buildCluster("example", mustParseURL("http://example.com"), nil, true,
|
||||
endpoints := srv.buildPolicyEndpoints(&config.Policy{
|
||||
Destinations: mustParseURLs("http://example.com"),
|
||||
})
|
||||
cluster := buildCluster("example", endpoints, true,
|
||||
config.GetEnvoyDNSLookupFamily(config.DNSLookupFamilyV4Only),
|
||||
nil)
|
||||
testutil.AssertProtoJSONEqual(t, `
|
||||
|
@ -242,11 +245,13 @@ func Test_buildCluster(t *testing.T) {
|
|||
`, cluster)
|
||||
})
|
||||
t.Run("secure", func(t *testing.T) {
|
||||
u := mustParseURL("https://example.com")
|
||||
transportSocket := srv.buildPolicyTransportSocket(&config.Policy{
|
||||
Destination: u,
|
||||
endpoints := srv.buildPolicyEndpoints(&config.Policy{
|
||||
Destinations: mustParseURLs(
|
||||
"https://example.com",
|
||||
"https://example.com",
|
||||
),
|
||||
})
|
||||
cluster := buildCluster("example", u, transportSocket, true,
|
||||
cluster := buildCluster("example", endpoints, true,
|
||||
config.GetEnvoyDNSLookupFamily(config.DNSLookupFamilyAuto),
|
||||
nil)
|
||||
testutil.AssertProtoJSONEqual(t, `
|
||||
|
@ -255,32 +260,38 @@ func Test_buildCluster(t *testing.T) {
|
|||
"type": "STRICT_DNS",
|
||||
"connectTimeout": "10s",
|
||||
"respectDnsTtl": true,
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"alpnProtocols": ["http/1.1"],
|
||||
"tlsParams": {
|
||||
"ecdhCurves": [
|
||||
"X25519",
|
||||
"P-256",
|
||||
"P-384",
|
||||
"P-521"
|
||||
]
|
||||
},
|
||||
"validationContext": {
|
||||
"matchSubjectAltNames": [{
|
||||
"exact": "example.com"
|
||||
}],
|
||||
"trustedCa": {
|
||||
"filename": "`+rootCA+`"
|
||||
"transportSocketMatches": [{
|
||||
"name": "`+endpoints[0].TransportSocketName()+`",
|
||||
"match": {
|
||||
"`+endpoints[0].TransportSocketName()+`": true
|
||||
},
|
||||
"transportSocket": {
|
||||
"name": "tls",
|
||||
"typedConfig": {
|
||||
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
|
||||
"commonTlsContext": {
|
||||
"alpnProtocols": ["http/1.1"],
|
||||
"tlsParams": {
|
||||
"ecdhCurves": [
|
||||
"X25519",
|
||||
"P-256",
|
||||
"P-384",
|
||||
"P-521"
|
||||
]
|
||||
},
|
||||
"validationContext": {
|
||||
"matchSubjectAltNames": [{
|
||||
"exact": "example.com"
|
||||
}],
|
||||
"trustedCa": {
|
||||
"filename": "`+rootCA+`"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sni": "example.com"
|
||||
},
|
||||
"sni": "example.com"
|
||||
}
|
||||
}
|
||||
},
|
||||
}],
|
||||
"http2ProtocolOptions": {
|
||||
"allowConnect": true
|
||||
},
|
||||
|
@ -296,6 +307,30 @@ func Test_buildCluster(t *testing.T) {
|
|||
"portValue": 443
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"filterMetadata": {
|
||||
"envoy.transport_socket_match": {
|
||||
"`+endpoints[0].TransportSocketName()+`": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},{
|
||||
"endpoint": {
|
||||
"address": {
|
||||
"socketAddress": {
|
||||
"address": "example.com",
|
||||
"ipv4Compat": true,
|
||||
"portValue": 443
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"filterMetadata": {
|
||||
"envoy.transport_socket_match": {
|
||||
"`+endpoints[0].TransportSocketName()+`": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
}]
|
||||
|
@ -304,7 +339,10 @@ func Test_buildCluster(t *testing.T) {
|
|||
`, cluster)
|
||||
})
|
||||
t.Run("ip address", func(t *testing.T) {
|
||||
cluster := buildCluster("example", mustParseURL("http://127.0.0.1"), nil, true,
|
||||
endpoints := srv.buildPolicyEndpoints(&config.Policy{
|
||||
Destinations: mustParseURLs("http://127.0.0.1"),
|
||||
})
|
||||
cluster := buildCluster("example", endpoints, true,
|
||||
config.GetEnvoyDNSLookupFamily(config.DNSLookupFamilyAuto),
|
||||
nil)
|
||||
testutil.AssertProtoJSONEqual(t, `
|
||||
|
@ -336,7 +374,10 @@ func Test_buildCluster(t *testing.T) {
|
|||
`, cluster)
|
||||
})
|
||||
t.Run("localhost", func(t *testing.T) {
|
||||
cluster := buildCluster("example", mustParseURL("http://localhost"), nil, true,
|
||||
endpoints := srv.buildPolicyEndpoints(&config.Policy{
|
||||
Destinations: mustParseURLs("http://localhost"),
|
||||
})
|
||||
cluster := buildCluster("example", endpoints, true,
|
||||
config.GetEnvoyDNSLookupFamily(config.DNSLookupFamilyAuto),
|
||||
nil)
|
||||
testutil.AssertProtoJSONEqual(t, `
|
||||
|
@ -368,7 +409,10 @@ func Test_buildCluster(t *testing.T) {
|
|||
`, cluster)
|
||||
})
|
||||
t.Run("outlier", func(t *testing.T) {
|
||||
cluster := buildCluster("example", mustParseURL("http://example.com"), nil, true,
|
||||
endpoints := srv.buildPolicyEndpoints(&config.Policy{
|
||||
Destinations: mustParseURLs("http://example.com"),
|
||||
})
|
||||
cluster := buildCluster("example", endpoints, true,
|
||||
config.GetEnvoyDNSLookupFamily(config.DNSLookupFamilyV4Only),
|
||||
&envoy_config_cluster_v3.OutlierDetection{
|
||||
EnforcingConsecutive_5Xx: wrapperspb.UInt32(17),
|
||||
|
|
|
@ -13,12 +13,35 @@ import (
|
|||
envoy_extensions_transport_sockets_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3"
|
||||
envoy_type_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"github.com/martinlindhe/base36"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
"github.com/pomerium/pomerium/config"
|
||||
"github.com/pomerium/pomerium/internal/log"
|
||||
"github.com/pomerium/pomerium/internal/urlutil"
|
||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||
)
|
||||
|
||||
// An Endpoint is a URL with its corresponding Transport Socket.
|
||||
type Endpoint struct {
|
||||
url *url.URL
|
||||
transportSocket *envoy_config_core_v3.TransportSocket
|
||||
}
|
||||
|
||||
// NewEndpoint creates a new Endpoint.
|
||||
func NewEndpoint(u *url.URL, ts *envoy_config_core_v3.TransportSocket) Endpoint {
|
||||
return Endpoint{url: u, transportSocket: ts}
|
||||
}
|
||||
|
||||
// TransportSocketName return the name for this endpoint.
|
||||
func (e Endpoint) TransportSocketName() string {
|
||||
if e.transportSocket == nil {
|
||||
return ""
|
||||
}
|
||||
h := cryptutil.HashProto(e.transportSocket)
|
||||
return "ts-" + base36.EncodeBytes(h)
|
||||
}
|
||||
|
||||
func (srv *Server) buildClusters(options *config.Options) []*envoy_config_cluster_v3.Cluster {
|
||||
grpcURL := &url.URL{
|
||||
Scheme: "http",
|
||||
|
@ -43,7 +66,7 @@ func (srv *Server) buildClusters(options *config.Options) []*envoy_config_cluste
|
|||
if config.IsProxy(options.Services) {
|
||||
for i := range options.Policies {
|
||||
policy := options.Policies[i]
|
||||
if policy.Destination != nil {
|
||||
if len(policy.Destinations) > 0 {
|
||||
clusters = append(clusters, srv.buildPolicyCluster(options, &policy))
|
||||
}
|
||||
}
|
||||
|
@ -52,22 +75,29 @@ func (srv *Server) buildClusters(options *config.Options) []*envoy_config_cluste
|
|||
return clusters
|
||||
}
|
||||
|
||||
func (srv *Server) buildInternalCluster(options *config.Options, name string, endpoint *url.URL, forceHTTP2 bool) *envoy_config_cluster_v3.Cluster {
|
||||
func (srv *Server) buildInternalCluster(options *config.Options, name string, dst *url.URL, forceHTTP2 bool) *envoy_config_cluster_v3.Cluster {
|
||||
endpoints := []Endpoint{NewEndpoint(dst, srv.buildInternalTransportSocket(options, dst))}
|
||||
dnsLookupFamily := config.GetEnvoyDNSLookupFamily(options.DNSLookupFamily)
|
||||
return buildCluster(name, endpoint, srv.buildInternalTransportSocket(options, endpoint), forceHTTP2,
|
||||
dnsLookupFamily,
|
||||
nil)
|
||||
return buildCluster(name, endpoints, forceHTTP2, dnsLookupFamily, nil)
|
||||
}
|
||||
|
||||
func (srv *Server) buildPolicyCluster(options *config.Options, policy *config.Policy) *envoy_config_cluster_v3.Cluster {
|
||||
name := getPolicyName(policy)
|
||||
endpoints := srv.buildPolicyEndpoints(policy)
|
||||
dnsLookupFamily := config.GetEnvoyDNSLookupFamily(options.DNSLookupFamily)
|
||||
if policy.EnableGoogleCloudServerlessAuthentication {
|
||||
dnsLookupFamily = envoy_config_cluster_v3.Cluster_V4_ONLY
|
||||
}
|
||||
return buildCluster(name, policy.Destination, srv.buildPolicyTransportSocket(policy), false,
|
||||
dnsLookupFamily,
|
||||
(*envoy_config_cluster_v3.OutlierDetection)(policy.OutlierDetection))
|
||||
outlierDetection := (*envoy_config_cluster_v3.OutlierDetection)(policy.OutlierDetection)
|
||||
return buildCluster(name, endpoints, false, dnsLookupFamily, outlierDetection)
|
||||
}
|
||||
|
||||
func (srv *Server) buildPolicyEndpoints(policy *config.Policy) []Endpoint {
|
||||
var endpoints []Endpoint
|
||||
for _, dst := range policy.Destinations {
|
||||
endpoints = append(endpoints, NewEndpoint(dst, srv.buildPolicyTransportSocket(policy, dst)))
|
||||
}
|
||||
return endpoints
|
||||
}
|
||||
|
||||
func (srv *Server) buildInternalTransportSocket(options *config.Options, endpoint *url.URL) *envoy_config_core_v3.TransportSocket {
|
||||
|
@ -119,12 +149,12 @@ func (srv *Server) buildInternalTransportSocket(options *config.Options, endpoin
|
|||
}
|
||||
}
|
||||
|
||||
func (srv *Server) buildPolicyTransportSocket(policy *config.Policy) *envoy_config_core_v3.TransportSocket {
|
||||
if policy.Destination == nil || policy.Destination.Scheme != "https" {
|
||||
func (srv *Server) buildPolicyTransportSocket(policy *config.Policy, dst *url.URL) *envoy_config_core_v3.TransportSocket {
|
||||
if dst == nil || dst.Scheme != "https" {
|
||||
return nil
|
||||
}
|
||||
|
||||
sni := policy.Destination.Hostname()
|
||||
sni := dst.Hostname()
|
||||
if policy.TLSServerName != "" {
|
||||
sni = policy.TLSServerName
|
||||
}
|
||||
|
@ -140,7 +170,7 @@ func (srv *Server) buildPolicyTransportSocket(policy *config.Policy) *envoy_conf
|
|||
},
|
||||
AlpnProtocols: []string{"http/1.1"},
|
||||
ValidationContextType: &envoy_extensions_transport_sockets_tls_v3.CommonTlsContext_ValidationContext{
|
||||
ValidationContext: srv.buildPolicyValidationContext(policy),
|
||||
ValidationContext: srv.buildPolicyValidationContext(policy, dst),
|
||||
},
|
||||
},
|
||||
Sni: sni,
|
||||
|
@ -159,12 +189,12 @@ func (srv *Server) buildPolicyTransportSocket(policy *config.Policy) *envoy_conf
|
|||
}
|
||||
}
|
||||
|
||||
func (srv *Server) buildPolicyValidationContext(policy *config.Policy) *envoy_extensions_transport_sockets_tls_v3.CertificateValidationContext {
|
||||
if policy.Destination == nil {
|
||||
func (srv *Server) buildPolicyValidationContext(policy *config.Policy, dst *url.URL) *envoy_extensions_transport_sockets_tls_v3.CertificateValidationContext {
|
||||
if dst == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
sni := policy.Destination.Hostname()
|
||||
sni := dst.Hostname()
|
||||
if policy.TLSServerName != "" {
|
||||
sni = policy.TLSServerName
|
||||
}
|
||||
|
@ -201,47 +231,29 @@ func (srv *Server) buildPolicyValidationContext(policy *config.Policy) *envoy_ex
|
|||
|
||||
func buildCluster(
|
||||
name string,
|
||||
endpoint *url.URL,
|
||||
transportSocket *envoy_config_core_v3.TransportSocket,
|
||||
endpoints []Endpoint,
|
||||
forceHTTP2 bool,
|
||||
dnsLookupFamily envoy_config_cluster_v3.Cluster_DnsLookupFamily,
|
||||
outlierDetection *envoy_config_cluster_v3.OutlierDetection,
|
||||
) *envoy_config_cluster_v3.Cluster {
|
||||
if endpoint == nil {
|
||||
if len(endpoints) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
defaultPort := 80
|
||||
if transportSocket != nil && transportSocket.Name == "tls" {
|
||||
defaultPort = 443
|
||||
}
|
||||
|
||||
if endpoint.Hostname() == "localhost" {
|
||||
u := new(url.URL)
|
||||
*u = *endpoint
|
||||
u.Host = strings.Replace(endpoint.Host, "localhost", "127.0.0.1", -1)
|
||||
endpoint = u
|
||||
}
|
||||
|
||||
lbEndpoints := buildLbEndpoints(endpoints)
|
||||
cluster := &envoy_config_cluster_v3.Cluster{
|
||||
Name: name,
|
||||
ConnectTimeout: ptypes.DurationProto(time.Second * 10),
|
||||
LoadAssignment: &envoy_config_endpoint_v3.ClusterLoadAssignment{
|
||||
ClusterName: name,
|
||||
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: buildAddress(endpoint.Host, defaultPort),
|
||||
},
|
||||
},
|
||||
}},
|
||||
LbEndpoints: lbEndpoints,
|
||||
}},
|
||||
},
|
||||
RespectDnsTtl: true,
|
||||
TransportSocket: transportSocket,
|
||||
DnsLookupFamily: dnsLookupFamily,
|
||||
OutlierDetection: outlierDetection,
|
||||
RespectDnsTtl: true,
|
||||
TransportSocketMatches: buildTransportSocketMatches(endpoints),
|
||||
DnsLookupFamily: dnsLookupFamily,
|
||||
OutlierDetection: outlierDetection,
|
||||
}
|
||||
|
||||
if forceHTTP2 {
|
||||
|
@ -251,7 +263,13 @@ func buildCluster(
|
|||
}
|
||||
|
||||
// for IPs we use a static discovery type, otherwise we use DNS
|
||||
if net.ParseIP(urlutil.StripPort(endpoint.Host)) != nil {
|
||||
isIP := false
|
||||
for _, lbe := range lbEndpoints {
|
||||
if net.ParseIP(urlutil.StripPort(lbe.GetEndpoint().GetAddress().GetSocketAddress().GetAddress())) != nil {
|
||||
isIP = true
|
||||
}
|
||||
}
|
||||
if isIP {
|
||||
cluster.ClusterDiscoveryType = &envoy_config_cluster_v3.Cluster_Type{Type: envoy_config_cluster_v3.Cluster_STATIC}
|
||||
} else {
|
||||
cluster.ClusterDiscoveryType = &envoy_config_cluster_v3.Cluster_Type{Type: envoy_config_cluster_v3.Cluster_STRICT_DNS}
|
||||
|
@ -259,3 +277,70 @@ func buildCluster(
|
|||
|
||||
return cluster
|
||||
}
|
||||
|
||||
func buildLbEndpoints(endpoints []Endpoint) []*envoy_config_endpoint_v3.LbEndpoint {
|
||||
var lbes []*envoy_config_endpoint_v3.LbEndpoint
|
||||
for _, e := range endpoints {
|
||||
defaultPort := 80
|
||||
if e.transportSocket != nil && e.transportSocket.Name == "tls" {
|
||||
defaultPort = 443
|
||||
}
|
||||
|
||||
u := e.url
|
||||
if e.url.Hostname() == "localhost" {
|
||||
u = new(url.URL)
|
||||
*u = *e.url
|
||||
u.Host = strings.Replace(e.url.Host, "localhost", "127.0.0.1", -1)
|
||||
}
|
||||
|
||||
lbe := &envoy_config_endpoint_v3.LbEndpoint{
|
||||
HostIdentifier: &envoy_config_endpoint_v3.LbEndpoint_Endpoint{
|
||||
Endpoint: &envoy_config_endpoint_v3.Endpoint{
|
||||
Address: buildAddress(u.Host, defaultPort),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if e.transportSocket != nil {
|
||||
lbe.Metadata = &envoy_config_core_v3.Metadata{
|
||||
FilterMetadata: map[string]*structpb.Struct{
|
||||
"envoy.transport_socket_match": {
|
||||
Fields: map[string]*structpb.Value{
|
||||
e.TransportSocketName(): structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
lbes = append(lbes, lbe)
|
||||
}
|
||||
return lbes
|
||||
}
|
||||
|
||||
func buildTransportSocketMatches(endpoints []Endpoint) []*envoy_config_cluster_v3.Cluster_TransportSocketMatch {
|
||||
var tsms []*envoy_config_cluster_v3.Cluster_TransportSocketMatch
|
||||
seen := map[string]struct{}{}
|
||||
for _, e := range endpoints {
|
||||
if e.transportSocket == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// only add unique transport sockets
|
||||
nm := e.TransportSocketName()
|
||||
if _, ok := seen[nm]; ok {
|
||||
continue
|
||||
}
|
||||
seen[nm] = struct{}{}
|
||||
|
||||
tsms = append(tsms, &envoy_config_cluster_v3.Cluster_TransportSocketMatch{
|
||||
Name: nm,
|
||||
Match: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
nm: structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
TransportSocket: e.transportSocket,
|
||||
})
|
||||
}
|
||||
return tsms
|
||||
}
|
||||
|
|
|
@ -404,8 +404,8 @@ func getRewriteOptions(policy *config.Policy) (prefixRewrite string, regexRewrit
|
|||
},
|
||||
Substitution: policy.RegexRewriteSubstitution,
|
||||
}
|
||||
} else if policy.Destination != nil && policy.Destination.Path != "" {
|
||||
prefixRewrite = policy.Destination.Path
|
||||
} else if len(policy.Destinations) > 0 && policy.Destinations[0].Path != "" {
|
||||
prefixRewrite = policy.Destinations[0].Path
|
||||
}
|
||||
|
||||
return prefixRewrite, regexRewrite
|
||||
|
@ -460,3 +460,11 @@ func mustParseURL(str string) *url.URL {
|
|||
}
|
||||
return u
|
||||
}
|
||||
|
||||
func mustParseURLs(strs ...string) []*url.URL {
|
||||
var us []*url.URL
|
||||
for _, str := range strs {
|
||||
us = append(us, mustParseURL(str))
|
||||
}
|
||||
return us
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ func Test_buildPomeriumHTTPRoutes(t *testing.T) {
|
|||
ForwardAuthURL: mustParseURL("https://forward-auth.example.com"),
|
||||
Policies: []config.Policy{{
|
||||
From: "https://from.example.com",
|
||||
To: "https://to.example.com",
|
||||
To: config.NewStringSlice("https://to.example.com"),
|
||||
}},
|
||||
}
|
||||
_ = options.Policies[0].Validate()
|
||||
|
@ -129,7 +129,7 @@ func Test_buildPomeriumHTTPRoutes(t *testing.T) {
|
|||
ForwardAuthURL: mustParseURL("https://forward-auth.example.com"),
|
||||
Policies: []config.Policy{{
|
||||
From: "https://from.example.com",
|
||||
To: "https://to.example.com",
|
||||
To: config.NewStringSlice("https://to.example.com"),
|
||||
AllowPublicUnauthenticatedAccess: true,
|
||||
}},
|
||||
}
|
||||
|
@ -615,37 +615,37 @@ func Test_buildPolicyRoutesRewrite(t *testing.T) {
|
|||
Policies: []config.Policy{
|
||||
{
|
||||
Source: &config.StringURL{URL: mustParseURL("https://example.com")},
|
||||
Destination: mustParseURL("https://foo.example.com/bar"),
|
||||
Destinations: mustParseURLs("https://foo.example.com/bar"),
|
||||
PassIdentityHeaders: true,
|
||||
},
|
||||
{
|
||||
Source: &config.StringURL{URL: mustParseURL("https://example.com")},
|
||||
Destination: mustParseURL("https://foo.example.com/bar"),
|
||||
Destinations: mustParseURLs("https://foo.example.com/bar"),
|
||||
PassIdentityHeaders: true,
|
||||
PrefixRewrite: "/foo",
|
||||
},
|
||||
{
|
||||
Source: &config.StringURL{URL: mustParseURL("https://example.com")},
|
||||
Destination: mustParseURL("https://foo.example.com/bar"),
|
||||
Destinations: mustParseURLs("https://foo.example.com/bar"),
|
||||
PassIdentityHeaders: true,
|
||||
RegexRewritePattern: "^/service/([^/]+)(/.*)$",
|
||||
RegexRewriteSubstitution: "\\2/instance/\\1",
|
||||
},
|
||||
{
|
||||
Source: &config.StringURL{URL: mustParseURL("https://example.com")},
|
||||
Destination: mustParseURL("https://foo.example.com/bar"),
|
||||
Destinations: mustParseURLs("https://foo.example.com/bar"),
|
||||
PassIdentityHeaders: true,
|
||||
HostRewrite: "literal.example.com",
|
||||
},
|
||||
{
|
||||
Source: &config.StringURL{URL: mustParseURL("https://example.com")},
|
||||
Destination: mustParseURL("https://foo.example.com/bar"),
|
||||
Destinations: mustParseURLs("https://foo.example.com/bar"),
|
||||
PassIdentityHeaders: true,
|
||||
HostRewriteHeader: "HOST_HEADER",
|
||||
},
|
||||
{
|
||||
Source: &config.StringURL{URL: mustParseURL("https://example.com")},
|
||||
Destination: mustParseURL("https://foo.example.com/bar"),
|
||||
Destinations: mustParseURLs("https://foo.example.com/bar"),
|
||||
PassIdentityHeaders: true,
|
||||
HostPathRegexRewritePattern: "^/(.+)/.+$",
|
||||
HostPathRegexRewriteSubstitution: "\\1",
|
||||
|
|
|
@ -50,7 +50,7 @@ func TestConfigSource(t *testing.T) {
|
|||
Routes: []*configpb.Route{
|
||||
{
|
||||
From: "https://from.example.com",
|
||||
To: "https://to.example.com",
|
||||
To: []string{"https://to.example.com"},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
|
@ -400,7 +400,7 @@ type Route struct {
|
|||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"`
|
||||
To string `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"`
|
||||
To []string `protobuf:"bytes,3,rep,name=to,proto3" json:"to,omitempty"`
|
||||
Redirect *RouteRedirect `protobuf:"bytes,34,opt,name=redirect,proto3" json:"redirect,omitempty"`
|
||||
// Deprecated: Do not use.
|
||||
AllowedUsers []string `protobuf:"bytes,4,rep,name=allowed_users,json=allowedUsers,proto3" json:"allowed_users,omitempty"`
|
||||
|
@ -485,11 +485,11 @@ func (x *Route) GetFrom() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *Route) GetTo() string {
|
||||
func (x *Route) GetTo() []string {
|
||||
if x != nil {
|
||||
return x.To
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Route) GetRedirect() *RouteRedirect {
|
||||
|
@ -1577,7 +1577,7 @@ var file_config_proto_rawDesc = []byte{
|
|||
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x3a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x3a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69,
|
||||
0x72, 0x65, 0x63, 0x74, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x6f, 0x6d,
|
||||
0x65, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x6f, 0x75,
|
||||
0x74, 0x65, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69,
|
||||
|
|
|
@ -51,7 +51,7 @@ message Route {
|
|||
string name = 1;
|
||||
|
||||
string from = 2;
|
||||
string to = 3;
|
||||
repeated string to = 3;
|
||||
|
||||
RouteRedirect redirect = 34;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ func testOptions(t *testing.T) *config.Options {
|
|||
opts := config.NewDefaultOptions()
|
||||
opts.AuthenticateURLString = "https://authenticate.example"
|
||||
|
||||
testPolicy := config.Policy{From: "https://corp.example.example", To: "https://example.example"}
|
||||
testPolicy := config.Policy{From: "https://corp.example.example", To: config.NewStringSlice("https://example.example")}
|
||||
opts.Policies = []config.Policy{testPolicy}
|
||||
opts.InsecureServer = true
|
||||
opts.CookieSecure = false
|
||||
|
@ -112,52 +112,52 @@ func Test_UpdateOptions(t *testing.T) {
|
|||
t.Parallel()
|
||||
|
||||
good := testOptions(t)
|
||||
newPolicy := config.Policy{To: "http://foo.example", From: "http://bar.example"}
|
||||
newPolicy := config.Policy{To: config.NewStringSlice("http://foo.example"), From: "http://bar.example"}
|
||||
newPolicies := testOptions(t)
|
||||
newPolicies.Policies = []config.Policy{newPolicy}
|
||||
err := newPolicy.Validate()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
badPolicyURL := config.Policy{To: "http://", From: "http://bar.example"}
|
||||
badPolicyURL := config.Policy{To: config.NewStringSlice("http://"), From: "http://bar.example"}
|
||||
badNewPolicy := testOptions(t)
|
||||
badNewPolicy.Policies = []config.Policy{
|
||||
badPolicyURL,
|
||||
}
|
||||
disableTLSPolicy := config.Policy{To: "http://foo.example", From: "http://bar.example", TLSSkipVerify: true}
|
||||
disableTLSPolicy := config.Policy{To: config.NewStringSlice("http://foo.example"), From: "http://bar.example", TLSSkipVerify: true}
|
||||
disableTLSPolicies := testOptions(t)
|
||||
disableTLSPolicies.Policies = []config.Policy{disableTLSPolicy}
|
||||
|
||||
customCAPolicies := testOptions(t)
|
||||
customCAPolicies.Policies = []config.Policy{{To: "http://foo.example", From: "http://bar.example", TLSCustomCA: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURlVENDQW1HZ0F3SUJBZ0lKQUszMmhoR0JIcmFtTUEwR0NTcUdTSWIzRFFFQkN3VUFNR0l4Q3pBSkJnTlYKQkFZVEFsVlRNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJZd0ZBWURWUVFIREExVFlXNGdSbkpoYm1OcApjMk52TVE4d0RRWURWUVFLREFaQ1lXUlRVMHd4RlRBVEJnTlZCQU1NRENvdVltRmtjM05zTG1OdmJUQWVGdzB4Ck9UQTJNVEl4TlRNeE5UbGFGdzB5TVRBMk1URXhOVE14TlRsYU1HSXhDekFKQmdOVkJBWVRBbFZUTVJNd0VRWUQKVlFRSURBcERZV3hwWm05eWJtbGhNUll3RkFZRFZRUUhEQTFUWVc0Z1JuSmhibU5wYzJOdk1ROHdEUVlEVlFRSwpEQVpDWVdSVFUwd3hGVEFUQmdOVkJBTU1EQ291WW1Ga2MzTnNMbU52YlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCCkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1JRTdQaU03Z1RDczloUTFYQll6Sk1ZNjF5b2FFbXdJclg1bFo2eEt5eDIKUG16QVMyQk1UT3F5dE1BUGdMYXcrWExKaGdMNVhFRmRFeXQvY2NSTHZPbVVMbEEzcG1jY1lZejJRVUxGUnRNVwpoeWVmZE9zS25SRlNKaUZ6YklSTWVWWGswV3ZvQmoxSUZWS3RzeWpicXY5dS8yQ1ZTbmRyT2ZFazBURzIzVTNBCnhQeFR1VzFDcmJWOC9xNzFGZEl6U09jaWNjZkNGSHBzS09vM1N0L3FiTFZ5dEg1YW9oYmNhYkZYUk5zS0VxdmUKd3c5SGRGeEJJdUdhK1J1VDVxMGlCaWt1c2JwSkhBd25ucVA3aS9kQWNnQ3NrZ2paakZlRVU0RUZ5K2IrYTFTWQpRQ2VGeHhDN2MzRHZhUmhCQjBWVmZQbGtQejBzdzZsODY1TWFUSWJSeW9VQ0F3RUFBYU15TURBd0NRWURWUjBUCkJBSXdBREFqQmdOVkhSRUVIREFhZ2d3cUxtSmhaSE56YkM1amIyMkNDbUpoWkhOemJDNWpiMjB3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dFQkFJaTV1OXc4bWdUNnBwQ2M3eHNHK0E5ZkkzVzR6K3FTS2FwaHI1bHM3MEdCS2JpWQpZTEpVWVpoUGZXcGgxcXRra1UwTEhGUG04M1ZhNTJlSUhyalhUMFZlNEt0TzFuMElBZkl0RmFXNjJDSmdoR1luCmp6dzByeXpnQzRQeUZwTk1uTnRCcm9QdS9iUGdXaU1nTE9OcEVaaGlneDRROHdmMVkvVTlzK3pDQ3hvSmxhS1IKTVhidVE4N1g3bS85VlJueHhvNk56NVpmN09USFRwTk9JNlZqYTBCeGJtSUFVNnlyaXc5VXJnaWJYZk9qM2o2bgpNVExCdWdVVklCMGJCYWFzSnNBTUsrdzRMQU52YXBlWjBET1NuT1I0S0syNEowT3lvRjVmSG1wNTllTTE3SW9GClFxQmh6cG1RVWd1bmVjRVc4QlRxck5wRzc5UjF1K1YrNHd3Y2tQYz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="}}
|
||||
customCAPolicies.Policies = []config.Policy{{To: config.NewStringSlice("http://foo.example"), From: "http://bar.example", TLSCustomCA: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURlVENDQW1HZ0F3SUJBZ0lKQUszMmhoR0JIcmFtTUEwR0NTcUdTSWIzRFFFQkN3VUFNR0l4Q3pBSkJnTlYKQkFZVEFsVlRNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJZd0ZBWURWUVFIREExVFlXNGdSbkpoYm1OcApjMk52TVE4d0RRWURWUVFLREFaQ1lXUlRVMHd4RlRBVEJnTlZCQU1NRENvdVltRmtjM05zTG1OdmJUQWVGdzB4Ck9UQTJNVEl4TlRNeE5UbGFGdzB5TVRBMk1URXhOVE14TlRsYU1HSXhDekFKQmdOVkJBWVRBbFZUTVJNd0VRWUQKVlFRSURBcERZV3hwWm05eWJtbGhNUll3RkFZRFZRUUhEQTFUWVc0Z1JuSmhibU5wYzJOdk1ROHdEUVlEVlFRSwpEQVpDWVdSVFUwd3hGVEFUQmdOVkJBTU1EQ291WW1Ga2MzTnNMbU52YlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCCkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1JRTdQaU03Z1RDczloUTFYQll6Sk1ZNjF5b2FFbXdJclg1bFo2eEt5eDIKUG16QVMyQk1UT3F5dE1BUGdMYXcrWExKaGdMNVhFRmRFeXQvY2NSTHZPbVVMbEEzcG1jY1lZejJRVUxGUnRNVwpoeWVmZE9zS25SRlNKaUZ6YklSTWVWWGswV3ZvQmoxSUZWS3RzeWpicXY5dS8yQ1ZTbmRyT2ZFazBURzIzVTNBCnhQeFR1VzFDcmJWOC9xNzFGZEl6U09jaWNjZkNGSHBzS09vM1N0L3FiTFZ5dEg1YW9oYmNhYkZYUk5zS0VxdmUKd3c5SGRGeEJJdUdhK1J1VDVxMGlCaWt1c2JwSkhBd25ucVA3aS9kQWNnQ3NrZ2paakZlRVU0RUZ5K2IrYTFTWQpRQ2VGeHhDN2MzRHZhUmhCQjBWVmZQbGtQejBzdzZsODY1TWFUSWJSeW9VQ0F3RUFBYU15TURBd0NRWURWUjBUCkJBSXdBREFqQmdOVkhSRUVIREFhZ2d3cUxtSmhaSE56YkM1amIyMkNDbUpoWkhOemJDNWpiMjB3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dFQkFJaTV1OXc4bWdUNnBwQ2M3eHNHK0E5ZkkzVzR6K3FTS2FwaHI1bHM3MEdCS2JpWQpZTEpVWVpoUGZXcGgxcXRra1UwTEhGUG04M1ZhNTJlSUhyalhUMFZlNEt0TzFuMElBZkl0RmFXNjJDSmdoR1luCmp6dzByeXpnQzRQeUZwTk1uTnRCcm9QdS9iUGdXaU1nTE9OcEVaaGlneDRROHdmMVkvVTlzK3pDQ3hvSmxhS1IKTVhidVE4N1g3bS85VlJueHhvNk56NVpmN09USFRwTk9JNlZqYTBCeGJtSUFVNnlyaXc5VXJnaWJYZk9qM2o2bgpNVExCdWdVVklCMGJCYWFzSnNBTUsrdzRMQU52YXBlWjBET1NuT1I0S0syNEowT3lvRjVmSG1wNTllTTE3SW9GClFxQmh6cG1RVWd1bmVjRVc4QlRxck5wRzc5UjF1K1YrNHd3Y2tQYz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="}}
|
||||
|
||||
badCustomCAPolicies := testOptions(t)
|
||||
badCustomCAPolicies.Policies = []config.Policy{{To: "http://foo.example", From: "http://bar.example", TLSCustomCA: "=@@"}}
|
||||
badCustomCAPolicies.Policies = []config.Policy{{To: config.NewStringSlice("http://foo.example"), From: "http://bar.example", TLSCustomCA: "=@@"}}
|
||||
|
||||
goodClientCertPolicies := testOptions(t)
|
||||
goodClientCertPolicies.Policies = []config.Policy{{To: "http://foo.example", From: "http://bar.example", TLSClientKey: "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", TLSClientCert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJVENDQWdtZ0F3SUJBZ0lSQVBqTEJxS1lwcWU0ekhQc0dWdFR6T0F3RFFZSktvWklodmNOQVFFTEJRQXcKRWpFUU1BNEdBMVVFQXhNSFoyOXZaQzFqWVRBZUZ3MHhPVEE0TVRBeE9EUTVOREJhRncweU1UQXlNVEF4TnpRdwpNREZhTUJNeEVUQVBCZ05WQkFNVENIQnZiV1Z5YVhWdE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQTY3S2pxbVFZR3EwTVZ0QUNWcGVDbVhtaW5sUWJEUEdMbXNaQVVFd3VlSFFucnQzV3R2cEQKT202QWxhSk1VblcrSHU1NWpqb2thbEtlVmpUS21nWUdicVV6VkRvTWJQRGFIZWtsdGRCVE1HbE9VRnNQNFVKUwpEck80emROK3pvNDI4VFgyUG5HMkZDZFZLR3k0UEU4aWxIYldMY3I4NzFZalY1MWZ3OENMRFg5UFpKTnU4NjFDCkY3VjlpRUptNnNTZlFsbW5oTjhqMytXelZiUFFOeTFXc1I3aTllOWo2M0VxS3QyMlE5T1hMK1dBY0tza29JU20KQ05WUlVBalU4WVJWY2dRSkIrelEzNEFRUGx6ME9wNU8vUU4vTWVkamFGOHdMUytpdi96dmlTOGNxUGJ4bzZzTApxNkZOVGx0ay9Ra3hlQ2VLS1RRZS8za1BZdlFBZG5sNjVRSURBUUFCbzNFd2J6QU9CZ05WSFE4QkFmOEVCQU1DCkE3Z3dIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUIwR0ExVWREZ1FXQkJRQ1FYbWIKc0hpcS9UQlZUZVhoQ0dpNjhrVy9DakFmQmdOVkhTTUVHREFXZ0JSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOdVhWegpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBcm9XL2trMllleFN5NEhaQXFLNDVZaGQ5ay9QVTFiaDlFK1BRCk5jZFgzTUdEY2NDRUFkc1k4dll3NVE1cnhuMGFzcSt3VGFCcGxoYS9rMi9VVW9IQ1RqUVp1Mk94dEF3UTdPaWIKVE1tMEorU3NWT3d4YnFQTW9rK1RqVE16NFdXaFFUTzVwRmNoZDZXZXNCVHlJNzJ0aG1jcDd1c2NLU2h3YktIegpQY2h1QTQ4SzhPdi96WkxmZnduQVNZb3VCczJjd1ZiRDI3ZXZOMzdoMGFzR1BrR1VXdm1PSDduTHNVeTh3TTdqCkNGL3NwMmJmTC9OYVdNclJnTHZBMGZMS2pwWTQrVEpPbkVxQmxPcCsrbHlJTEZMcC9qMHNybjRNUnlKK0t6UTEKR1RPakVtQ1QvVEFtOS9XSThSL0FlYjcwTjEzTytYNEtaOUJHaDAxTzN3T1Vqd3BZZ3lxSnNoRnNRUG50VmMrSQpKQmF4M2VQU3NicUcwTFkzcHdHUkpRNmMrd1lxdGk2Y0tNTjliYlRkMDhCNUk1N1RRTHhNcUoycTFnWmw1R1VUCmVFZGNWRXltMnZmd0NPd0lrbGNBbThxTm5kZGZKV1FabE5VaHNOVWFBMkVINnlDeXdaZm9aak9hSDEwTXowV20KeTNpZ2NSZFQ3Mi9NR2VkZk93MlV0MVVvRFZmdEcxcysrditUQ1lpNmpUQU05dkZPckJ4UGlOeGFkUENHR2NZZAowakZIc2FWOGFPV1dQQjZBQ1JteHdDVDdRTnRTczM2MlpIOUlFWWR4Q00yMDUrZmluVHhkOUcwSmVRRTd2Kyt6CldoeWo2ZmJBWUIxM2wvN1hkRnpNSW5BOGxpekdrVHB2RHMxeTBCUzlwV3ppYmhqbVFoZGZIejdCZGpGTHVvc2wKZzlNZE5sND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="}}
|
||||
goodClientCertPolicies.Policies = []config.Policy{{To: config.NewStringSlice("http://foo.example"), From: "http://bar.example", TLSClientKey: "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBNjdLanFtUVlHcTBNVnRBQ1ZwZUNtWG1pbmxRYkRQR0xtc1pBVUV3dWVIUW5ydDNXCnR2cERPbTZBbGFKTVVuVytIdTU1ampva2FsS2VWalRLbWdZR2JxVXpWRG9NYlBEYUhla2x0ZEJUTUdsT1VGc1AKNFVKU0RyTzR6ZE4rem80MjhUWDJQbkcyRkNkVktHeTRQRThpbEhiV0xjcjg3MVlqVjUxZnc4Q0xEWDlQWkpOdQo4NjFDRjdWOWlFSm02c1NmUWxtbmhOOGozK1d6VmJQUU55MVdzUjdpOWU5ajYzRXFLdDIyUTlPWEwrV0FjS3NrCm9JU21DTlZSVUFqVThZUlZjZ1FKQit6UTM0QVFQbHowT3A1Ty9RTi9NZWRqYUY4d0xTK2l2L3p2aVM4Y3FQYngKbzZzTHE2Rk5UbHRrL1FreGVDZUtLVFFlLzNrUFl2UUFkbmw2NVFJREFRQUJBb0lCQVFEQVQ0eXN2V2pSY3pxcgpKcU9SeGFPQTJEY3dXazJML1JXOFhtQWhaRmRTWHV2MkNQbGxhTU1yelBmTG41WUlmaHQzSDNzODZnSEdZc3pnClo4aWJiYWtYNUdFQ0t5N3lRSDZuZ3hFS3pRVGpiampBNWR3S0h0UFhQUnJmamQ1Y2FMczVpcDcxaWxCWEYxU3IKWERIaXUycnFtaC9kVTArWGRMLzNmK2VnVDl6bFQ5YzRyUm84dnZueWNYejFyMnVhRVZ2VExsWHVsb2NpeEVrcgoySjlTMmxveWFUb2tFTnNlMDNpSVdaWnpNNElZcVowOGJOeG9IWCszQXVlWExIUStzRkRKMlhaVVdLSkZHMHUyClp3R2w3YlZpRTFQNXdiQUdtZzJDeDVCN1MrdGQyUEpSV3Frb2VxY3F2RVdCc3RFL1FEcDFpVThCOHpiQXd0Y3IKZHc5TXZ6Q2hBb0dCQVBObzRWMjF6MGp6MWdEb2tlTVN5d3JnL2E4RkJSM2R2Y0xZbWV5VXkybmd3eHVucnFsdwo2U2IrOWdrOGovcXEvc3VQSDhVdzNqSHNKYXdGSnNvTkVqNCt2b1ZSM3UrbE5sTEw5b21rMXBoU0dNdVp0b3huCm5nbUxVbkJUMGI1M3BURkJ5WGsveE5CbElreWdBNlg5T2MreW5na3RqNlRyVnMxUERTdnVJY0s1QW9HQkFQZmoKcEUzR2F6cVFSemx6TjRvTHZmQWJBdktCZ1lPaFNnemxsK0ZLZkhzYWJGNkdudFd1dWVhY1FIWFpYZTA1c2tLcApXN2xYQ3dqQU1iUXI3QmdlazcrOSszZElwL1RnYmZCYnN3Syt6Vng3Z2doeWMrdytXRWExaHByWTZ6YXdxdkFaCkhRU2lMUEd1UGp5WXBQa1E2ZFdEczNmWHJGZ1dlTmd4SkhTZkdaT05Bb0dCQUt5WTF3MUM2U3Y2c3VuTC8vNTcKQ2Z5NTAwaXlqNUZBOWRqZkRDNWt4K1JZMnlDV0ExVGsybjZyVmJ6dzg4czBTeDMrYS9IQW1CM2dMRXBSRU5NKwo5NHVwcENFWEQ3VHdlcGUxUnlrTStKbmp4TzlDSE41c2J2U25sUnBQWlMvZzJRTVhlZ3grK2trbkhXNG1ITkFyCndqMlRrMXBBczFXbkJ0TG9WaGVyY01jSkFvR0JBSTYwSGdJb0Y5SysvRUcyY21LbUg5SDV1dGlnZFU2eHEwK0IKWE0zMWMzUHE0amdJaDZlN3pvbFRxa2d0dWtTMjBraE45dC9ibkI2TmhnK1N1WGVwSXFWZldVUnlMejVwZE9ESgo2V1BMTTYzcDdCR3cwY3RPbU1NYi9VRm5Yd0U4OHlzRlNnOUF6VjdVVUQvU0lDYkI5ZHRVMWh4SHJJK0pZRWdWCkFrZWd6N2lCQW9HQkFJRncrQVFJZUIwM01UL0lCbGswNENQTDJEak0rNDhoVGRRdjgwMDBIQU9mUWJrMEVZUDEKQ2FLR3RDbTg2MXpBZjBzcS81REtZQ0l6OS9HUzNYRk00Qm1rRk9nY1NXVENPNmZmTGdLM3FmQzN4WDJudlpIOQpYZGNKTDQrZndhY0x4c2JJKzhhUWNOVHRtb3pkUjEzQnNmUmIrSGpUL2o3dkdrYlFnSkhCT0syegotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=", TLSClientCert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVJVENDQWdtZ0F3SUJBZ0lSQVBqTEJxS1lwcWU0ekhQc0dWdFR6T0F3RFFZSktvWklodmNOQVFFTEJRQXcKRWpFUU1BNEdBMVVFQXhNSFoyOXZaQzFqWVRBZUZ3MHhPVEE0TVRBeE9EUTVOREJhRncweU1UQXlNVEF4TnpRdwpNREZhTUJNeEVUQVBCZ05WQkFNVENIQnZiV1Z5YVhWdE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBCk1JSUJDZ0tDQVFFQTY3S2pxbVFZR3EwTVZ0QUNWcGVDbVhtaW5sUWJEUEdMbXNaQVVFd3VlSFFucnQzV3R2cEQKT202QWxhSk1VblcrSHU1NWpqb2thbEtlVmpUS21nWUdicVV6VkRvTWJQRGFIZWtsdGRCVE1HbE9VRnNQNFVKUwpEck80emROK3pvNDI4VFgyUG5HMkZDZFZLR3k0UEU4aWxIYldMY3I4NzFZalY1MWZ3OENMRFg5UFpKTnU4NjFDCkY3VjlpRUptNnNTZlFsbW5oTjhqMytXelZiUFFOeTFXc1I3aTllOWo2M0VxS3QyMlE5T1hMK1dBY0tza29JU20KQ05WUlVBalU4WVJWY2dRSkIrelEzNEFRUGx6ME9wNU8vUU4vTWVkamFGOHdMUytpdi96dmlTOGNxUGJ4bzZzTApxNkZOVGx0ay9Ra3hlQ2VLS1RRZS8za1BZdlFBZG5sNjVRSURBUUFCbzNFd2J6QU9CZ05WSFE4QkFmOEVCQU1DCkE3Z3dIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUIwR0ExVWREZ1FXQkJRQ1FYbWIKc0hpcS9UQlZUZVhoQ0dpNjhrVy9DakFmQmdOVkhTTUVHREFXZ0JSNTRKQ3pMRlg0T0RTQ1J0dWNBUGZOdVhWegpuREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBcm9XL2trMllleFN5NEhaQXFLNDVZaGQ5ay9QVTFiaDlFK1BRCk5jZFgzTUdEY2NDRUFkc1k4dll3NVE1cnhuMGFzcSt3VGFCcGxoYS9rMi9VVW9IQ1RqUVp1Mk94dEF3UTdPaWIKVE1tMEorU3NWT3d4YnFQTW9rK1RqVE16NFdXaFFUTzVwRmNoZDZXZXNCVHlJNzJ0aG1jcDd1c2NLU2h3YktIegpQY2h1QTQ4SzhPdi96WkxmZnduQVNZb3VCczJjd1ZiRDI3ZXZOMzdoMGFzR1BrR1VXdm1PSDduTHNVeTh3TTdqCkNGL3NwMmJmTC9OYVdNclJnTHZBMGZMS2pwWTQrVEpPbkVxQmxPcCsrbHlJTEZMcC9qMHNybjRNUnlKK0t6UTEKR1RPakVtQ1QvVEFtOS9XSThSL0FlYjcwTjEzTytYNEtaOUJHaDAxTzN3T1Vqd3BZZ3lxSnNoRnNRUG50VmMrSQpKQmF4M2VQU3NicUcwTFkzcHdHUkpRNmMrd1lxdGk2Y0tNTjliYlRkMDhCNUk1N1RRTHhNcUoycTFnWmw1R1VUCmVFZGNWRXltMnZmd0NPd0lrbGNBbThxTm5kZGZKV1FabE5VaHNOVWFBMkVINnlDeXdaZm9aak9hSDEwTXowV20KeTNpZ2NSZFQ3Mi9NR2VkZk93MlV0MVVvRFZmdEcxcysrditUQ1lpNmpUQU05dkZPckJ4UGlOeGFkUENHR2NZZAowakZIc2FWOGFPV1dQQjZBQ1JteHdDVDdRTnRTczM2MlpIOUlFWWR4Q00yMDUrZmluVHhkOUcwSmVRRTd2Kyt6CldoeWo2ZmJBWUIxM2wvN1hkRnpNSW5BOGxpekdrVHB2RHMxeTBCUzlwV3ppYmhqbVFoZGZIejdCZGpGTHVvc2wKZzlNZE5sND0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="}}
|
||||
goodClientCertPolicies.Validate()
|
||||
|
||||
customServerName := testOptions(t)
|
||||
customServerName.Policies = []config.Policy{{To: "http://foo.example", From: "http://bar.example", TLSServerName: "test"}}
|
||||
customServerName.Policies = []config.Policy{{To: config.NewStringSlice("http://foo.example"), From: "http://bar.example", TLSServerName: "test"}}
|
||||
|
||||
emptyPolicies := testOptions(t)
|
||||
emptyPolicies.Policies = nil
|
||||
|
||||
allowWebSockets := testOptions(t)
|
||||
allowWebSockets.Policies = []config.Policy{{To: "http://foo.example", From: "http://bar.example", AllowWebsockets: true}}
|
||||
allowWebSockets.Policies = []config.Policy{{To: config.NewStringSlice("http://foo.example"), From: "http://bar.example", AllowWebsockets: true}}
|
||||
customTimeout := testOptions(t)
|
||||
customTimeout.Policies = []config.Policy{{To: "http://foo.example", From: "http://bar.example", UpstreamTimeout: 10 * time.Second}}
|
||||
customTimeout.Policies = []config.Policy{{To: config.NewStringSlice("http://foo.example"), From: "http://bar.example", UpstreamTimeout: 10 * time.Second}}
|
||||
corsPreflight := testOptions(t)
|
||||
corsPreflight.Policies = []config.Policy{{To: "http://foo.example", From: "http://bar.example", CORSAllowPreflight: true}}
|
||||
corsPreflight.Policies = []config.Policy{{To: config.NewStringSlice("http://foo.example"), From: "http://bar.example", CORSAllowPreflight: true}}
|
||||
disableAuth := testOptions(t)
|
||||
disableAuth.Policies = []config.Policy{{To: "http://foo.example", From: "http://bar.example", AllowPublicUnauthenticatedAccess: true}}
|
||||
disableAuth.Policies = []config.Policy{{To: config.NewStringSlice("http://foo.example"), From: "http://bar.example", AllowPublicUnauthenticatedAccess: true}}
|
||||
fwdAuth := testOptions(t)
|
||||
fwdAuth.ForwardAuthURL = &url.URL{Scheme: "https", Host: "corp.example.example"}
|
||||
reqHeaders := testOptions(t)
|
||||
reqHeaders.Policies = []config.Policy{{To: "http://foo.example", From: "http://bar.example", SetRequestHeaders: map[string]string{"x": "y"}}}
|
||||
reqHeaders.Policies = []config.Policy{{To: config.NewStringSlice("http://foo.example"), From: "http://bar.example", SetRequestHeaders: map[string]string{"x": "y"}}}
|
||||
preserveHostHeader := testOptions(t)
|
||||
preserveHostHeader.Policies = []config.Policy{{To: "http://foo.example", From: "http://bar.example", PreserveHostHeader: true}}
|
||||
preserveHostHeader.Policies = []config.Policy{{To: config.NewStringSlice("http://foo.example"), From: "http://bar.example", PreserveHostHeader: true}}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue