From a87af4e863be0d2ba67f2ccad60ccce4fc55647d Mon Sep 17 00:00:00 2001 From: Karl Gutwin Date: Thu, 30 Jul 2015 09:42:49 -0400 Subject: [PATCH] Add configuration options for default lease duration and max lease duration. --- command/server.go | 16 +++--- command/server/config.go | 31 ++++++++-- command/server/config_test.go | 11 ++++ .../server/test-fixtures/config-dir/bar.json | 4 +- .../server/test-fixtures/config-dir/baz.hcl | 2 + .../server/test-fixtures/config-dir/foo.hcl | 2 + command/server/test-fixtures/config.hcl | 3 + command/server/test-fixtures/config.hcl.json | 5 +- vault/core.go | 56 ++++++++++++------- vault/core_test.go | 8 +-- vault/expiration.go | 4 +- website/source/docs/auth/token.html.md | 5 +- website/source/docs/config/index.html.md | 9 +++ 13 files changed, 116 insertions(+), 40 deletions(-) diff --git a/command/server.go b/command/server.go index 00d949d6ea..cd716d3770 100644 --- a/command/server.go +++ b/command/server.go @@ -125,13 +125,15 @@ func (c *ServerCommand) Run(args []string) int { // Initialize the core core, err := vault.NewCore(&vault.CoreConfig{ - AdvertiseAddr: config.Backend.AdvertiseAddr, - Physical: backend, - AuditBackends: c.AuditBackends, - CredentialBackends: c.CredentialBackends, - LogicalBackends: c.LogicalBackends, - Logger: logger, - DisableMlock: config.DisableMlock, + AdvertiseAddr: config.Backend.AdvertiseAddr, + Physical: backend, + AuditBackends: c.AuditBackends, + CredentialBackends: c.CredentialBackends, + LogicalBackends: c.LogicalBackends, + Logger: logger, + DisableMlock: config.DisableMlock, + MaxLeaseDuration: time.Duration(config.MaxLeaseDuration) * time.Hour, + DefaultLeaseDuration: time.Duration(config.DefaultLeaseDuration) * time.Hour, }) if err != nil { c.Ui.Error(fmt.Sprintf("Error initializing core: %s", err)) diff --git a/command/server/config.go b/command/server/config.go index a1b992344e..6b656c15fc 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -14,12 +14,15 @@ import ( // Config is the configuration for the vault server. type Config struct { - Listeners []*Listener `hcl:"-"` - Backend *Backend `hcl:"-"` + Listeners []*Listener `hcl:"-"` + Backend *Backend `hcl:"-"` - DisableMlock bool `hcl:"disable_mlock"` + DisableMlock bool `hcl:"disable_mlock"` - Telemetry *Telemetry `hcl:"telemetry"` + Telemetry *Telemetry `hcl:"telemetry"` + + MaxLeaseDuration int `hcl:"max_lease_duration"` + DefaultLeaseDuration int `hcl:"default_lease_duration"` } // DevConfig is a Config that is used for dev mode of Vault. @@ -41,6 +44,9 @@ func DevConfig() *Config { }, Telemetry: &Telemetry{}, + + MaxLeaseDuration: 30 * 24, + DefaultLeaseDuration: 30 * 24, } } @@ -97,6 +103,23 @@ func (c *Config) Merge(c2 *Config) *Config { result.Telemetry = c2.Telemetry } + // merging this boolean via an OR operation + result.DisableMlock = c.DisableMlock + if c2.DisableMlock { + result.DisableMlock = c2.DisableMlock + } + + // merge these integers via a MAX operation + result.MaxLeaseDuration = c.MaxLeaseDuration + if c2.MaxLeaseDuration > result.MaxLeaseDuration { + result.MaxLeaseDuration = c2.MaxLeaseDuration + } + + result.DefaultLeaseDuration = c.DefaultLeaseDuration + if c2.DefaultLeaseDuration > result.DefaultLeaseDuration { + result.DefaultLeaseDuration = c2.DefaultLeaseDuration + } + return result } diff --git a/command/server/config_test.go b/command/server/config_test.go index c1a38733d7..04acabe4e7 100644 --- a/command/server/config_test.go +++ b/command/server/config_test.go @@ -36,6 +36,9 @@ func TestLoadConfigFile(t *testing.T) { }, DisableMlock: true, + + MaxLeaseDuration: 10, + DefaultLeaseDuration: 10, } if !reflect.DeepEqual(config, expected) { t.Fatalf("bad: %#v", config) @@ -70,6 +73,9 @@ func TestLoadConfigFile_json(t *testing.T) { StatsdAddr: "", DisableHostname: false, }, + + MaxLeaseDuration: 10, + DefaultLeaseDuration: 10, } if !reflect.DeepEqual(config, expected) { t.Fatalf("bad: %#v", config) @@ -117,6 +123,8 @@ func TestLoadConfigDir(t *testing.T) { } expected := &Config{ + DisableMlock: true, + Listeners: []*Listener{ &Listener{ Type: "tcp", @@ -138,6 +146,9 @@ func TestLoadConfigDir(t *testing.T) { StatsdAddr: "baz", DisableHostname: true, }, + + MaxLeaseDuration: 10, + DefaultLeaseDuration: 10, } if !reflect.DeepEqual(config, expected) { t.Fatalf("bad: %#v", config) diff --git a/command/server/test-fixtures/config-dir/bar.json b/command/server/test-fixtures/config-dir/bar.json index 3d76653564..5d18d28a39 100644 --- a/command/server/test-fixtures/config-dir/bar.json +++ b/command/server/test-fixtures/config-dir/bar.json @@ -3,5 +3,7 @@ "tcp": { "address": "127.0.0.1:443" } - } + }, + + "max_lease_duration": 10 } diff --git a/command/server/test-fixtures/config-dir/baz.hcl b/command/server/test-fixtures/config-dir/baz.hcl index e826dec4b4..7c733d1736 100644 --- a/command/server/test-fixtures/config-dir/baz.hcl +++ b/command/server/test-fixtures/config-dir/baz.hcl @@ -3,3 +3,5 @@ telemetry { statsite_address = "qux" disable_hostname = true } + +default_lease_duration = 10 \ No newline at end of file diff --git a/command/server/test-fixtures/config-dir/foo.hcl b/command/server/test-fixtures/config-dir/foo.hcl index 5ab1d72b92..068e9ee1c3 100644 --- a/command/server/test-fixtures/config-dir/foo.hcl +++ b/command/server/test-fixtures/config-dir/foo.hcl @@ -1,3 +1,5 @@ +disable_mlock = true + backend "consul" { foo = "bar" } diff --git a/command/server/test-fixtures/config.hcl b/command/server/test-fixtures/config.hcl index 50538a51b6..04d005bd21 100644 --- a/command/server/test-fixtures/config.hcl +++ b/command/server/test-fixtures/config.hcl @@ -10,3 +10,6 @@ backend "consul" { foo = "bar" advertise_addr = "foo" } + +max_lease_duration = 10 +default_lease_duration = 10 \ No newline at end of file diff --git a/command/server/test-fixtures/config.hcl.json b/command/server/test-fixtures/config.hcl.json index f5596f5f17..7785b92af1 100644 --- a/command/server/test-fixtures/config.hcl.json +++ b/command/server/test-fixtures/config.hcl.json @@ -13,5 +13,8 @@ "telemetry": { "statsite_address": "baz" - } + }, + + "max_lease_duration": 10, + "default_lease_duration": 10 } diff --git a/vault/core.go b/vault/core.go index 3c0d539878..9a2ce5e0ec 100644 --- a/vault/core.go +++ b/vault/core.go @@ -213,23 +213,28 @@ type Core struct { // metricsCh is used to stop the metrics streaming metricsCh chan struct{} + defaultLeaseDuration time.Duration + maxLeaseDuration time.Duration + logger *log.Logger } // CoreConfig is used to parameterize a core type CoreConfig struct { - LogicalBackends map[string]logical.Factory - CredentialBackends map[string]logical.Factory - AuditBackends map[string]audit.Factory - Physical physical.Backend - Logger *log.Logger - DisableCache bool // Disables the LRU cache on the physical backend - DisableMlock bool // Disables mlock syscall - CacheSize int // Custom cache size of zero for default - AdvertiseAddr string // Set as the leader address for HA + LogicalBackends map[string]logical.Factory + CredentialBackends map[string]logical.Factory + AuditBackends map[string]audit.Factory + Physical physical.Backend + Logger *log.Logger + DisableCache bool // Disables the LRU cache on the physical backend + DisableMlock bool // Disables mlock syscall + CacheSize int // Custom cache size of zero for default + AdvertiseAddr string // Set as the leader address for HA + DefaultLeaseDuration time.Duration + MaxLeaseDuration time.Duration } -// NewCore isk used to construct a new core +// NewCore is used to construct a new core func NewCore(conf *CoreConfig) (*Core, error) { // Check if this backend supports an HA configuraiton var haBackend physical.HABackend @@ -240,6 +245,17 @@ func NewCore(conf *CoreConfig) (*Core, error) { return nil, fmt.Errorf("missing advertisement address") } + if conf.DefaultLeaseDuration == 0 { + conf.DefaultLeaseDuration = defaultLeaseDuration + } + if conf.MaxLeaseDuration == 0 { + conf.MaxLeaseDuration = maxLeaseDuration + } + + if conf.DefaultLeaseDuration > conf.MaxLeaseDuration { + return nil, fmt.Errorf("cannot have DefaultLeaseDuration larger than MaxLeaseDuration") + } + // Validate the advertise addr if its given to us if conf.AdvertiseAddr != "" { u, err := url.Parse(conf.AdvertiseAddr) @@ -299,6 +315,8 @@ func NewCore(conf *CoreConfig) (*Core, error) { sealed: true, standby: true, logger: conf.Logger, + defaultLeaseDuration: conf.DefaultLeaseDuration, + maxLeaseDuration: conf.MaxLeaseDuration, } // Setup the backends @@ -424,12 +442,12 @@ func (c *Core) handleRequest(req *logical.Request) (*logical.Response, *logical. if resp != nil && resp.Secret != nil && !strings.HasPrefix(req.Path, "sys/renew/") { // Apply the default lease if none given if resp.Secret.Lease == 0 { - resp.Secret.Lease = defaultLeaseDuration + resp.Secret.Lease = c.defaultLeaseDuration } // Limit the lease duration - if resp.Secret.Lease > maxLeaseDuration { - resp.Secret.Lease = maxLeaseDuration + if resp.Secret.Lease > c.maxLeaseDuration { + resp.Secret.Lease = c.maxLeaseDuration } // Register the lease @@ -456,12 +474,12 @@ func (c *Core) handleRequest(req *logical.Request) (*logical.Response, *logical. // Set the default lease if non-provided, root tokens are exempt if resp.Auth.Lease == 0 && !strListContains(resp.Auth.Policies, "root") { - resp.Auth.Lease = defaultLeaseDuration + resp.Auth.Lease = c.defaultLeaseDuration } // Limit the lease duration - if resp.Auth.Lease > maxLeaseDuration { - resp.Auth.Lease = maxLeaseDuration + if resp.Auth.Lease > c.maxLeaseDuration { + resp.Auth.Lease = c.maxLeaseDuration } // Register with the expiration manager @@ -528,12 +546,12 @@ func (c *Core) handleLoginRequest(req *logical.Request) (*logical.Response, *log // Set the default lease if non-provided, root tokens are exempt if auth.Lease == 0 && !strListContains(auth.Policies, "root") { - auth.Lease = defaultLeaseDuration + auth.Lease = c.defaultLeaseDuration } // Limit the lease duration - if resp.Auth.Lease > maxLeaseDuration { - resp.Auth.Lease = maxLeaseDuration + if resp.Auth.Lease > c.maxLeaseDuration { + resp.Auth.Lease = c.maxLeaseDuration } // Register with the expiration manager diff --git a/vault/core_test.go b/vault/core_test.go index 207d3d4f28..194cdc98a8 100644 --- a/vault/core_test.go +++ b/vault/core_test.go @@ -442,7 +442,7 @@ func TestCore_HandleRequest_Lease_MaxLength(t *testing.T) { if resp == nil || resp.Secret == nil || resp.Data == nil { t.Fatalf("bad: %#v", resp) } - if resp.Secret.Lease != maxLeaseDuration { + if resp.Secret.Lease != c.maxLeaseDuration { t.Fatalf("bad: %#v", resp.Secret) } if resp.Secret.LeaseID == "" { @@ -483,7 +483,7 @@ func TestCore_HandleRequest_Lease_DefaultLength(t *testing.T) { if resp == nil || resp.Secret == nil || resp.Data == nil { t.Fatalf("bad: %#v", resp) } - if resp.Secret.Lease != defaultLeaseDuration { + if resp.Secret.Lease != c.defaultLeaseDuration { t.Fatalf("bad: %#v", resp.Secret) } if resp.Secret.LeaseID == "" { @@ -829,7 +829,7 @@ func TestCore_HandleLogin_Token(t *testing.T) { } // Check that we have a lease with default duration - if lresp.Auth.Lease != defaultLeaseDuration { + if lresp.Auth.Lease != c.defaultLeaseDuration { t.Fatalf("bad: %#v", lresp.Auth) } } @@ -1016,7 +1016,7 @@ func TestCore_HandleRequest_CreateToken_Lease(t *testing.T) { } // Check that we have a lease with default duration - if resp.Auth.Lease != defaultLeaseDuration { + if resp.Auth.Lease != c.defaultLeaseDuration { t.Fatalf("bad: %#v", resp.Auth) } } diff --git a/vault/expiration.go b/vault/expiration.go index 681609f9e7..69dca6f84b 100644 --- a/vault/expiration.go +++ b/vault/expiration.go @@ -35,10 +35,10 @@ const ( // minRevokeDelay is used to prevent an instant revoke on restore minRevokeDelay = 5 * time.Second - // maxLeaseDuration is the maximum lease duration + // maxLeaseDuration is the default maximum lease duration maxLeaseDuration = 30 * 24 * time.Hour - // defaultLeaseDuration is the lease duration used when no lease is specified + // defaultLeaseDuration is the default lease duration used when no lease is specified defaultLeaseDuration = maxLeaseDuration ) diff --git a/website/source/docs/auth/token.html.md b/website/source/docs/auth/token.html.md index 896ba8f955..83763cd23f 100644 --- a/website/source/docs/auth/token.html.md +++ b/website/source/docs/auth/token.html.md @@ -88,8 +88,9 @@ of the cookie should be "token" and the value should be the token. lease optional The lease period of the token, provided as "1h", where hour is - the largest suffix. If not provided, the token is valid for the default - lease duration (30 days), or indefinitely if the root policy is used. + the largest suffix. If not provided, the token is valid for the + [default lease duration](/docs/config/index.html), or + indefinitely if the root policy is used.
  • display_name diff --git a/website/source/docs/config/index.html.md b/website/source/docs/config/index.html.md index 271081758a..08445001de 100644 --- a/website/source/docs/config/index.html.md +++ b/website/source/docs/config/index.html.md @@ -49,6 +49,15 @@ to specify where the configuration is. * `telemetry` (optional) - Configures the telemetry reporting system (see below). +* `default_lease_duration` (optional) - Configures the default lease + duration for tokens and secrets, specified in hours. Default value + is 30 * 24 hours. This value cannot be larger than + `max_lease_duration`. + +* `max_lease_duration` (optional) - Configures the maximum possible + lease duration for tokens and secrets, specified in hours. Default + value is 30 * 24 hours. + In production, you should only consider setting the `disable_mlock` option on Linux systems that only use encrypted swap or do not use swap at all. Vault does not currently support memory locking on Mac OS X and Windows