Mlock the plugin process

This commit is contained in:
Brian Kassouf 2017-04-10 17:12:52 -07:00
parent f6ff3b1146
commit 8071aed758
8 changed files with 64 additions and 6 deletions

View File

@ -76,6 +76,8 @@ func (b *databaseBackend) closeAllDBs() {
for _, db := range b.connections {
db.Close()
}
b.connections = nil
}
// This function is used to retrieve a database object either from the cached

View File

@ -1,6 +1,8 @@
package dbplugin
import (
"fmt"
"github.com/hashicorp/go-plugin"
"github.com/hashicorp/vault/helper/pluginutil"
)
@ -18,6 +20,12 @@ func NewPluginServer(db DatabaseType) {
"database": dbPlugin,
}
err := pluginutil.OptionallyEnableMlock()
if err != nil {
fmt.Println(err)
return
}
plugin.Serve(&plugin.ServeConfig{
HandshakeConfig: handshakeConfig,
Plugins: pluginMap,

View File

@ -3,15 +3,29 @@ package pluginutil
import (
"crypto/sha256"
"fmt"
"os"
"os/exec"
"time"
plugin "github.com/hashicorp/go-plugin"
"github.com/hashicorp/vault/helper/mlock"
)
var (
// PluginUnwrapTokenEnv is the ENV name used to pass unwrap tokens to the
// plugin.
PluginMlockEnabled = "VAULT_PLUGIN_MLOCK_ENABLED"
)
type Looker interface {
LookupPlugin(string) (*PluginRunner, error)
}
type Wrapper interface {
ResponseWrapData(data map[string]interface{}, ttl time.Duration, jwt bool) (string, error)
MlockDisabled() bool
}
type LookWrapper interface {
Looker
Wrapper
@ -22,6 +36,7 @@ type PluginRunner struct {
Command string `json:"command"`
Args []string `json:"args"`
Sha256 []byte `json:"sha256"`
Builtin bool `json:"builtin"`
}
func (r *PluginRunner) Run(wrapper Wrapper, pluginMap map[string]plugin.Plugin, hs plugin.HandshakeConfig, env []string) (*plugin.Client, error) {
@ -44,10 +59,17 @@ func (r *PluginRunner) Run(wrapper Wrapper, pluginMap map[string]plugin.Plugin,
return nil, err
}
// Add the response wrap token to the ENV of the plugin
mlock := "true"
if wrapper.MlockDisabled() {
mlock = "false"
}
cmd := exec.Command(r.Command, r.Args...)
cmd.Env = append(cmd.Env, env...)
// Add the response wrap token to the ENV of the plugin
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", PluginUnwrapTokenEnv, wrapToken))
// Add the mlock setting to the ENV of the plugin
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", PluginMlockEnabled, mlock))
secureConfig := &plugin.SecureConfig{
Checksum: r.Sha256,
@ -64,3 +86,11 @@ func (r *PluginRunner) Run(wrapper Wrapper, pluginMap map[string]plugin.Plugin,
return client, nil
}
func OptionallyEnableMlock() error {
if os.Getenv(PluginMlockEnabled) == "true" {
return mlock.LockMemory()
}
return nil
}

View File

@ -29,10 +29,6 @@ var (
PluginUnwrapTokenEnv = "VAULT_UNWRAP_TOKEN"
)
type Wrapper interface {
ResponseWrapData(data map[string]interface{}, ttl time.Duration, jwt bool) (string, error)
}
// GenerateCACert returns a CA cert used to later sign the certificates for the
// plugin client and server.
func GenerateCACert() ([]byte, *x509.Certificate, *ecdsa.PrivateKey, error) {

View File

@ -44,7 +44,12 @@ type SystemView interface {
// token used to unwrap.
ResponseWrapData(data map[string]interface{}, ttl time.Duration, jwt bool) (string, error)
// LookupPlugin looks into the plugin catalog for a plugin with the given
// name. Returns a PluginRunner or an error if a plugin can not be found.
LookupPlugin(string) (*pluginutil.PluginRunner, error)
// MlockDisabled returns the configuration setting for DisableMlock.
MlockDisabled() bool
}
type StaticSystemView struct {
@ -54,6 +59,7 @@ type StaticSystemView struct {
TaintedVal bool
CachingDisabledVal bool
Primary bool
DisableMlock bool
ReplicationStateVal consts.ReplicationState
}
@ -88,3 +94,7 @@ func (d StaticSystemView) ResponseWrapData(data map[string]interface{}, ttl time
func (d StaticSystemView) LookupPlugin(name string) (*pluginutil.PluginRunner, error) {
return nil, errors.New("LookupPlugin is not implimented in StaticSystemView")
}
func (d StaticSystemView) MlockDisabled() bool {
return d.DisableMlock
}

View File

@ -332,7 +332,7 @@ type Core struct {
// uiEnabled indicates whether Vault Web UI is enabled or not
uiEnabled bool
// pluginDirectory is the location vault will look for plugins
// pluginDirectory is the location vault will look for plugin binaries
pluginDirectory string
// vaultBinaryLocation is used to run builtin plugins in secure mode
@ -343,6 +343,8 @@ type Core struct {
// pluginCatalog is used to manage plugin configurations
pluginCatalog *PluginCatalog
disableMlock bool
}
// CoreConfig is used to parameterize a core
@ -449,6 +451,7 @@ func NewCore(conf *CoreConfig) (*Core, error) {
clusterListenerShutdownSuccessCh: make(chan struct{}),
vaultBinaryLocation: conf.VaultBinaryLocation,
vaultBinarySHA256: conf.VaultBinarySHA256,
disableMlock: conf.DisableMlock,
}
// Wrap the physical backend in a cache layer if enabled and not already wrapped

View File

@ -116,6 +116,13 @@ func (d dynamicSystemView) ResponseWrapData(data map[string]interface{}, ttl tim
return resp.WrapInfo.Token, nil
}
// LookupPlugin looks for a plugin with the given name in the plugin catalog. It
// returns a PluginRunner or an error if no plugin was found.
func (d dynamicSystemView) LookupPlugin(name string) (*pluginutil.PluginRunner, error) {
return d.core.pluginCatalog.Get(name)
}
// MlockDisabled returns the configuration setting "DisableMlock".
func (d dynamicSystemView) MlockDisabled() bool {
return d.core.disableMlock
}

View File

@ -63,6 +63,7 @@ func (c *PluginCatalog) Get(name string) (*pluginutil.PluginRunner, error) {
Command: c.vaultCommand,
Args: []string{"plugin-exec", name},
Sha256: c.vaultSHA256,
Builtin: true,
}, nil
}
@ -93,6 +94,7 @@ func (c *PluginCatalog) Set(name, command string, sha256 []byte) error {
Command: command,
Args: args,
Sha256: sha256,
Builtin: false,
}
buf, err := json.Marshal(entry)