mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 11:08:10 +00:00
Added flag to disable X-Vault-Token header proxy if client passes the token (#8101)
* Added flag to disable X-Vault-Token header proxy if client passes the token * Reveresed the flag value to better match the name intent * Introduced UseAutoAuthTokenRaw for Cache to support triplicate value of true/false/force Co-authored-by: Clint <catsby@users.noreply.github.com>
This commit is contained in:
@@ -464,8 +464,10 @@ func (c *AgentCommand) Run(args []string) int {
|
||||
})
|
||||
}
|
||||
|
||||
var proxyVaultToken = !config.Cache.UseAutoAuthTokenEnforce
|
||||
|
||||
// Create the request handler
|
||||
cacheHandler := cache.Handler(ctx, cacheLogger, leaseCache, inmemSink)
|
||||
cacheHandler := cache.Handler(ctx, cacheLogger, leaseCache, inmemSink, proxyVaultToken)
|
||||
|
||||
var listeners []net.Listener
|
||||
for i, lnConfig := range config.Listeners {
|
||||
|
61
command/agent/cache/cache_test.go
vendored
61
command/agent/cache/cache_test.go
vendored
@@ -152,7 +152,7 @@ func setupClusterAndAgentCommon(ctx context.Context, t *testing.T, coreConfig *v
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/agent/v1/cache-clear", leaseCache.HandleCacheClear(ctx))
|
||||
|
||||
mux.Handle("/", Handler(ctx, cacheLogger, leaseCache, nil))
|
||||
mux.Handle("/", Handler(ctx, cacheLogger, leaseCache, nil, true))
|
||||
server := &http.Server{
|
||||
Handler: mux,
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
@@ -243,7 +243,7 @@ func TestCache_AutoAuthTokenStripping(t *testing.T) {
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle(consts.AgentPathCacheClear, leaseCache.HandleCacheClear(ctx))
|
||||
|
||||
mux.Handle("/", Handler(ctx, cacheLogger, leaseCache, mock.NewSink("testid")))
|
||||
mux.Handle("/", Handler(ctx, cacheLogger, leaseCache, mock.NewSink("testid"), true))
|
||||
server := &http.Server{
|
||||
Handler: mux,
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
@@ -281,6 +281,63 @@ func TestCache_AutoAuthTokenStripping(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCache_AutoAuthClientTokenProxyStripping(t *testing.T) {
|
||||
leaseCache := &mockTokenVerifierProxier{}
|
||||
dummyToken := "DUMMY"
|
||||
realToken := "testid"
|
||||
|
||||
cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{
|
||||
HandlerFunc: vaulthttp.Handler,
|
||||
})
|
||||
cluster.Start()
|
||||
defer cluster.Cleanup()
|
||||
|
||||
cores := cluster.Cores
|
||||
vault.TestWaitActive(t, cores[0].Core)
|
||||
client := cores[0].Client
|
||||
|
||||
cacheLogger := logging.NewVaultLogger(hclog.Trace).Named("cache")
|
||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ctx := namespace.RootContext(nil)
|
||||
|
||||
// Create a muxer and add paths relevant for the lease cache layer
|
||||
mux := http.NewServeMux()
|
||||
//mux.Handle(consts.AgentPathCacheClear, leaseCache.HandleCacheClear(ctx))
|
||||
|
||||
mux.Handle("/", Handler(ctx, cacheLogger, leaseCache, mock.NewSink(realToken), false))
|
||||
server := &http.Server{
|
||||
Handler: mux,
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
ReadTimeout: 30 * time.Second,
|
||||
IdleTimeout: 5 * time.Minute,
|
||||
ErrorLog: cacheLogger.StandardLogger(nil),
|
||||
}
|
||||
go server.Serve(listener)
|
||||
|
||||
testClient, err := client.Clone()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := testClient.SetAddress("http://" + listener.Addr().String()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Empty the token in the client. Auto-auth token should be put to use.
|
||||
testClient.SetToken(dummyToken)
|
||||
_, err = testClient.Auth().Token().LookupSelf()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if leaseCache.currentToken != realToken {
|
||||
t.Fatalf("failed to use real token from auto-auth")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCache_ConcurrentRequests(t *testing.T) {
|
||||
coreConfig := &vault.CoreConfig{
|
||||
DisableMlock: true,
|
||||
|
7
command/agent/cache/handler.go
vendored
7
command/agent/cache/handler.go
vendored
@@ -20,11 +20,16 @@ import (
|
||||
"github.com/hashicorp/vault/sdk/logical"
|
||||
)
|
||||
|
||||
func Handler(ctx context.Context, logger hclog.Logger, proxier Proxier, inmemSink sink.Sink) http.Handler {
|
||||
func Handler(ctx context.Context, logger hclog.Logger, proxier Proxier, inmemSink sink.Sink, proxyVaultToken bool) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
logger.Info("received request", "method", r.Method, "path", r.URL.Path)
|
||||
|
||||
if !proxyVaultToken {
|
||||
r.Header.Del(consts.AuthHeaderName)
|
||||
}
|
||||
|
||||
token := r.Header.Get(consts.AuthHeaderName)
|
||||
|
||||
if token == "" && inmemSink != nil {
|
||||
logger.Debug("using auto auth token", "method", r.Method, "path", r.URL.Path)
|
||||
token = inmemSink.(sink.SinkReader).Token()
|
||||
|
16
command/agent/cache/testing.go
vendored
16
command/agent/cache/testing.go
vendored
@@ -64,3 +64,19 @@ func newTestSendResponse(status int, body string) *SendResponse {
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
type mockTokenVerifierProxier struct {
|
||||
currentToken string
|
||||
}
|
||||
|
||||
func (p *mockTokenVerifierProxier) Send(ctx context.Context, req *SendRequest) (*SendResponse, error) {
|
||||
p.currentToken = req.Token
|
||||
resp := newTestSendResponse(http.StatusOK,
|
||||
`{"data": {"id": "` + p.currentToken + `"}}`)
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (p *mockTokenVerifierProxier) GetCurrentRequestToken() (string) {
|
||||
return p.currentToken
|
||||
}
|
@@ -298,7 +298,7 @@ func TestCache_UsingAutoAuthToken(t *testing.T) {
|
||||
mux.Handle(consts.AgentPathCacheClear, leaseCache.HandleCacheClear(ctx))
|
||||
|
||||
// Passing a non-nil inmemsink tells the agent to use the auto-auth token
|
||||
mux.Handle("/", cache.Handler(ctx, cacheLogger, leaseCache, inmemSink))
|
||||
mux.Handle("/", cache.Handler(ctx, cacheLogger, leaseCache, inmemSink, true))
|
||||
server := &http.Server{
|
||||
Handler: mux,
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
|
@@ -43,7 +43,9 @@ type Vault struct {
|
||||
|
||||
// Cache contains any configuration needed for Cache mode
|
||||
type Cache struct {
|
||||
UseAutoAuthToken bool `hcl:"use_auto_auth_token"`
|
||||
UseAutoAuthTokenRaw interface{} `hcl:"use_auto_auth_token"`
|
||||
UseAutoAuthToken bool `hcl:"-"`
|
||||
UseAutoAuthTokenEnforce bool `hcl:"-"`
|
||||
}
|
||||
|
||||
// Listener contains configuration for any Vault Agent listeners
|
||||
@@ -219,6 +221,26 @@ func parseCache(result *Config, list *ast.ObjectList) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.UseAutoAuthTokenRaw != nil {
|
||||
c.UseAutoAuthToken, err = parseutil.ParseBool(c.UseAutoAuthTokenRaw)
|
||||
if err != nil {
|
||||
// Could be a value of "force" instead of "true"/"false"
|
||||
switch c.UseAutoAuthTokenRaw.(type) {
|
||||
case string:
|
||||
v := c.UseAutoAuthTokenRaw.(string)
|
||||
|
||||
if !strings.EqualFold(v, "force") {
|
||||
return fmt.Errorf("value of 'use_auto_auth_token' can be either true/false/force, %q is an invalid option", c.UseAutoAuthTokenRaw)
|
||||
}
|
||||
c.UseAutoAuthToken = true
|
||||
c.UseAutoAuthTokenEnforce = true
|
||||
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.Cache = &c
|
||||
return nil
|
||||
}
|
||||
|
@@ -39,6 +39,8 @@ func TestLoadConfigFile_AgentCache(t *testing.T) {
|
||||
},
|
||||
Cache: &Cache{
|
||||
UseAutoAuthToken: true,
|
||||
UseAutoAuthTokenEnforce: false,
|
||||
UseAutoAuthTokenRaw: true,
|
||||
},
|
||||
Listeners: []*Listener{
|
||||
&Listener{
|
||||
@@ -269,6 +271,133 @@ func TestLoadConfigFile_AgentCache_AutoAuth_NoSink(t *testing.T) {
|
||||
},
|
||||
Cache: &Cache{
|
||||
UseAutoAuthToken: true,
|
||||
UseAutoAuthTokenEnforce: false,
|
||||
UseAutoAuthTokenRaw: true,
|
||||
},
|
||||
Listeners: []*Listener{
|
||||
&Listener{
|
||||
Type: "tcp",
|
||||
Config: map[string]interface{}{
|
||||
"address": "127.0.0.1:8300",
|
||||
"tls_disable": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
PidFile: "./pidfile",
|
||||
}
|
||||
|
||||
if diff := deep.Equal(config, expected); diff != nil {
|
||||
t.Fatal(diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfigFile_AgentCache_AutoAuth_Force(t *testing.T) {
|
||||
config, err := LoadConfig("./test-fixtures/config-cache-auto_auth-force.hcl")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
expected := &Config{
|
||||
AutoAuth: &AutoAuth{
|
||||
Method: &Method{
|
||||
Type: "aws",
|
||||
MountPath: "auth/aws",
|
||||
Config: map[string]interface{}{
|
||||
"role": "foobar",
|
||||
},
|
||||
},
|
||||
},
|
||||
Cache: &Cache{
|
||||
UseAutoAuthToken: true,
|
||||
UseAutoAuthTokenEnforce: true,
|
||||
UseAutoAuthTokenRaw: "force",
|
||||
},
|
||||
Listeners: []*Listener{
|
||||
&Listener{
|
||||
Type: "tcp",
|
||||
Config: map[string]interface{}{
|
||||
"address": "127.0.0.1:8300",
|
||||
"tls_disable": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
PidFile: "./pidfile",
|
||||
}
|
||||
|
||||
if diff := deep.Equal(config, expected); diff != nil {
|
||||
t.Fatal(diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfigFile_AgentCache_AutoAuth_True(t *testing.T) {
|
||||
config, err := LoadConfig("./test-fixtures/config-cache-auto_auth-true.hcl")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
expected := &Config{
|
||||
AutoAuth: &AutoAuth{
|
||||
Method: &Method{
|
||||
Type: "aws",
|
||||
MountPath: "auth/aws",
|
||||
Config: map[string]interface{}{
|
||||
"role": "foobar",
|
||||
},
|
||||
},
|
||||
},
|
||||
Cache: &Cache{
|
||||
UseAutoAuthToken: true,
|
||||
UseAutoAuthTokenEnforce: false,
|
||||
UseAutoAuthTokenRaw: "true",
|
||||
},
|
||||
Listeners: []*Listener{
|
||||
&Listener{
|
||||
Type: "tcp",
|
||||
Config: map[string]interface{}{
|
||||
"address": "127.0.0.1:8300",
|
||||
"tls_disable": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
PidFile: "./pidfile",
|
||||
}
|
||||
|
||||
if diff := deep.Equal(config, expected); diff != nil {
|
||||
t.Fatal(diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfigFile_AgentCache_AutoAuth_False(t *testing.T) {
|
||||
config, err := LoadConfig("./test-fixtures/config-cache-auto_auth-false.hcl")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
expected := &Config{
|
||||
AutoAuth: &AutoAuth{
|
||||
Method: &Method{
|
||||
Type: "aws",
|
||||
MountPath: "auth/aws",
|
||||
Config: map[string]interface{}{
|
||||
"role": "foobar",
|
||||
},
|
||||
},
|
||||
Sinks: []*Sink{
|
||||
&Sink{
|
||||
Type: "file",
|
||||
DHType: "curve25519",
|
||||
DHPath: "/tmp/file-foo-dhpath",
|
||||
AAD: "foobar",
|
||||
Config: map[string]interface{}{
|
||||
"path": "/tmp/file-foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Cache: &Cache{
|
||||
UseAutoAuthToken: false,
|
||||
UseAutoAuthTokenEnforce: false,
|
||||
UseAutoAuthTokenRaw: "false",
|
||||
},
|
||||
Listeners: []*Listener{
|
||||
&Listener{
|
||||
|
@@ -0,0 +1,30 @@
|
||||
pid_file = "./pidfile"
|
||||
|
||||
auto_auth {
|
||||
method {
|
||||
type = "aws"
|
||||
config = {
|
||||
role = "foobar"
|
||||
}
|
||||
}
|
||||
|
||||
sink {
|
||||
type = "file"
|
||||
config = {
|
||||
path = "/tmp/file-foo"
|
||||
}
|
||||
aad = "foobar"
|
||||
dh_type = "curve25519"
|
||||
dh_path = "/tmp/file-foo-dhpath"
|
||||
}
|
||||
}
|
||||
|
||||
cache {
|
||||
use_auto_auth_token = "false"
|
||||
}
|
||||
|
||||
listener "tcp" {
|
||||
address = "127.0.0.1:8300"
|
||||
tls_disable = true
|
||||
}
|
||||
|
@@ -0,0 +1,20 @@
|
||||
pid_file = "./pidfile"
|
||||
|
||||
auto_auth {
|
||||
method {
|
||||
type = "aws"
|
||||
config = {
|
||||
role = "foobar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cache {
|
||||
use_auto_auth_token = "force"
|
||||
}
|
||||
|
||||
listener "tcp" {
|
||||
address = "127.0.0.1:8300"
|
||||
tls_disable = true
|
||||
}
|
||||
|
@@ -0,0 +1,20 @@
|
||||
pid_file = "./pidfile"
|
||||
|
||||
auto_auth {
|
||||
method {
|
||||
type = "aws"
|
||||
config = {
|
||||
role = "foobar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cache {
|
||||
use_auto_auth_token = "true"
|
||||
}
|
||||
|
||||
listener "tcp" {
|
||||
address = "127.0.0.1:8300"
|
||||
tls_disable = true
|
||||
}
|
||||
|
Reference in New Issue
Block a user