Add support for stored shares and skip-init in dev mode (#3364)

This commit is contained in:
Calvin Leung Huang 2017-09-21 15:23:29 -04:00 committed by GitHub
parent 516cc8bd6b
commit b7413325dd

View File

@ -72,7 +72,7 @@ type ServerCommand struct {
} }
func (c *ServerCommand) Run(args []string) int { func (c *ServerCommand) Run(args []string) int {
var dev, verifyOnly, devHA, devTransactional, devLeasedKV, devThreeNode bool var dev, verifyOnly, devHA, devTransactional, devLeasedKV, devThreeNode, devSkipInit bool
var configPath []string var configPath []string
var logLevel, devRootTokenID, devListenAddress, devPluginDir string var logLevel, devRootTokenID, devListenAddress, devPluginDir string
var devLatency, devLatencyJitter int var devLatency, devLatencyJitter int
@ -89,6 +89,7 @@ func (c *ServerCommand) Run(args []string) int {
flags.BoolVar(&devTransactional, "dev-transactional", false, "") flags.BoolVar(&devTransactional, "dev-transactional", false, "")
flags.BoolVar(&devLeasedKV, "dev-leased-kv", false, "") flags.BoolVar(&devLeasedKV, "dev-leased-kv", false, "")
flags.BoolVar(&devThreeNode, "dev-three-node", false, "") flags.BoolVar(&devThreeNode, "dev-three-node", false, "")
flags.BoolVar(&devSkipInit, "dev-skip-init", false, "")
flags.Usage = func() { c.Ui.Output(c.Help()) } flags.Usage = func() { c.Ui.Output(c.Help()) }
flags.Var((*sliceflag.StringFlag)(&configPath), "config", "config") flags.Var((*sliceflag.StringFlag)(&configPath), "config", "config")
if err := flags.Parse(args); err != nil { if err := flags.Parse(args); err != nil {
@ -606,7 +607,7 @@ CLUSTER_SYNTHESIS_COMPLETE:
core.SetClusterHandler(handler) core.SetClusterHandler(handler)
// If we're in Dev mode, then initialize the core // If we're in Dev mode, then initialize the core
if dev { if dev && !devSkipInit {
init, err := c.enableDev(core, coreConfig) init, err := c.enableDev(core, coreConfig)
if err != nil { if err != nil {
c.Ui.Output(fmt.Sprintf( c.Ui.Output(fmt.Sprintf(
@ -621,19 +622,36 @@ CLUSTER_SYNTHESIS_COMPLETE:
quote = "" quote = ""
} }
c.Ui.Output(fmt.Sprint(
"==> WARNING: Dev mode is enabled!\n\n" +
"In this mode, Vault is completely in-memory and unsealed.\n" +
"Vault is configured to only have a single unseal key. The root\n" +
"token has already been authenticated with the CLI, so you can\n" +
"immediately begin using the Vault CLI.\n\n" +
"The only step you need to take is to set the following\n" +
"environment variables:\n\n" +
" " + export + " VAULT_ADDR=" + quote + "http://" + config.Listeners[0].Config["address"].(string) + quote + "\n\n" +
"The unseal key and root token are reproduced below in case you\n" +
"want to seal/unseal the Vault or play with authentication.\n",
))
// Unseal key is not returned if stored shares is supported
if len(init.SecretShares) > 0 {
c.Ui.Output(fmt.Sprintf(
"Unseal Key: %s",
base64.StdEncoding.EncodeToString(init.SecretShares[0]),
))
}
if len(init.RecoveryShares) > 0 {
c.Ui.Output(fmt.Sprintf(
"Recovery Key: %s",
base64.StdEncoding.EncodeToString(init.RecoveryShares[0]),
))
}
c.Ui.Output(fmt.Sprintf( c.Ui.Output(fmt.Sprintf(
"==> WARNING: Dev mode is enabled!\n\n"+ "Root Token: %s\n",
"In this mode, Vault is completely in-memory and unsealed.\n"+
"Vault is configured to only have a single unseal key. The root\n"+
"token has already been authenticated with the CLI, so you can\n"+
"immediately begin using the Vault CLI.\n\n"+
"The only step you need to take is to set the following\n"+
"environment variables:\n\n"+
" "+export+" VAULT_ADDR="+quote+"http://"+config.Listeners[0].Config["address"].(string)+quote+"\n\n"+
"The unseal key and root token are reproduced below in case you\n"+
"want to seal/unseal the Vault or play with authentication.\n\n"+
"Unseal Key: %s\nRoot Token: %s\n",
base64.StdEncoding.EncodeToString(init.SecretShares[0]),
init.RootToken, init.RootToken,
)) ))
} }
@ -706,29 +724,51 @@ CLUSTER_SYNTHESIS_COMPLETE:
} }
func (c *ServerCommand) enableDev(core *vault.Core, coreConfig *vault.CoreConfig) (*vault.InitResult, error) { func (c *ServerCommand) enableDev(core *vault.Core, coreConfig *vault.CoreConfig) (*vault.InitResult, error) {
// Initialize it with a basic single key var recoveryConfig *vault.SealConfig
init, err := core.Initialize(&vault.InitParams{ barrierConfig := &vault.SealConfig{
BarrierConfig: &vault.SealConfig{ SecretShares: 1,
SecretThreshold: 1,
}
if core.SealAccess().RecoveryKeySupported() {
recoveryConfig = &vault.SealConfig{
SecretShares: 1, SecretShares: 1,
SecretThreshold: 1, SecretThreshold: 1,
}, }
RecoveryConfig: nil, }
if core.SealAccess().StoredKeysSupported() {
barrierConfig.StoredShares = 1
}
// Initialize it with a basic single key
init, err := core.Initialize(&vault.InitParams{
BarrierConfig: barrierConfig,
RecoveryConfig: recoveryConfig,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Copy the key so that it can be zeroed // Handle unseal with stored keys
key := make([]byte, len(init.SecretShares[0])) if core.SealAccess().StoredKeysSupported() {
copy(key, init.SecretShares[0]) err := core.UnsealWithStoredKeys()
if err != nil {
return nil, err
}
} else {
// Copy the key so that it can be zeroed
key := make([]byte, len(init.SecretShares[0]))
copy(key, init.SecretShares[0])
// Unseal the core // Unseal the core
unsealed, err := core.Unseal(key) unsealed, err := core.Unseal(key)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !unsealed { if !unsealed {
return nil, fmt.Errorf("failed to unseal Vault for dev mode") return nil, fmt.Errorf("failed to unseal Vault for dev mode")
}
} }
isLeader, _, _, err := core.Leader() isLeader, _, _, err := core.Leader()
@ -752,6 +792,7 @@ func (c *ServerCommand) enableDev(core *vault.Core, coreConfig *vault.CoreConfig
} }
} }
// Generate a dev root token if one is provided in the flag
if coreConfig.DevToken != "" { if coreConfig.DevToken != "" {
req := &logical.Request{ req := &logical.Request{
ID: "dev-gen-root", ID: "dev-gen-root",