agent: clean up keyring file implementation
This commit is contained in:
parent
2e92e19760
commit
3e64ed70df
|
@ -19,6 +19,11 @@ import (
|
||||||
"github.com/hashicorp/serf/serf"
|
"github.com/hashicorp/serf/serf"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
serfLANKeyring = "serf/local.keyring"
|
||||||
|
serfWANKeyring = "serf/remote.keyring"
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The agent is the long running process that is run on every machine.
|
The agent is the long running process that is run on every machine.
|
||||||
It exposes an RPC interface that is used by the CLI to control the
|
It exposes an RPC interface that is used by the CLI to control the
|
||||||
|
@ -116,37 +121,14 @@ func Create(config *Config, logOutput io.Writer) (*Agent, error) {
|
||||||
|
|
||||||
// Setup encryption keyring files
|
// Setup encryption keyring files
|
||||||
if config.PersistKeyring && config.EncryptKey != "" {
|
if config.PersistKeyring && config.EncryptKey != "" {
|
||||||
serfDir := filepath.Join(config.DataDir, "serf")
|
if config.Server {
|
||||||
if err := os.MkdirAll(serfDir, 0700); err != nil {
|
if err := agent.initKeyringFile(serfWANKeyring); err != nil {
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
keys := []string{config.EncryptKey}
|
|
||||||
keyringBytes, err := json.MarshalIndent(keys, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
paths := []string{
|
|
||||||
filepath.Join(serfDir, "keyring_lan"),
|
|
||||||
filepath.Join(serfDir, "keyring_wan"),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, path := range paths {
|
|
||||||
if _, err := os.Stat(path); err == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fh, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer fh.Close()
|
|
||||||
|
|
||||||
if _, err := fh.Write(keyringBytes); err != nil {
|
|
||||||
os.Remove(path)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := agent.initKeyringFile(serfLANKeyring); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup either the client or the server
|
// Setup either the client or the server
|
||||||
|
@ -206,9 +188,8 @@ func (a *Agent) consulConfig() *consul.Config {
|
||||||
base.SerfWANConfig.MemberlistConfig.SecretKey = key
|
base.SerfWANConfig.MemberlistConfig.SecretKey = key
|
||||||
}
|
}
|
||||||
if a.config.PersistKeyring {
|
if a.config.PersistKeyring {
|
||||||
lanKeyring := filepath.Join(base.DataDir, "serf", "keyring_lan")
|
lanKeyring := filepath.Join(base.DataDir, serfLANKeyring)
|
||||||
wanKeyring := filepath.Join(base.DataDir, "serf", "keyring_wan")
|
wanKeyring := filepath.Join(base.DataDir, serfWANKeyring)
|
||||||
|
|
||||||
base.SerfLANConfig.KeyringFile = lanKeyring
|
base.SerfLANConfig.KeyringFile = lanKeyring
|
||||||
base.SerfWANConfig.KeyringFile = wanKeyring
|
base.SerfWANConfig.KeyringFile = wanKeyring
|
||||||
}
|
}
|
||||||
|
@ -825,3 +806,39 @@ func (a *Agent) RemoveKeyLAN(key string) (*serf.KeyResponse, error) {
|
||||||
km := a.client.KeyManagerLAN()
|
km := a.client.KeyManagerLAN()
|
||||||
return km.RemoveKey(key)
|
return km.RemoveKey(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initKeyringFile is used to create and initialize a persistent keyring file
|
||||||
|
// for gossip encryption keys. It is used at agent startup to dump the initial
|
||||||
|
// encryption key into a keyfile if persistence is enabled.
|
||||||
|
func (a *Agent) initKeyringFile(path string) error {
|
||||||
|
serfDir := filepath.Join(a.config.DataDir, "serf")
|
||||||
|
if err := os.MkdirAll(serfDir, 0700); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keys := []string{a.config.EncryptKey}
|
||||||
|
keyringBytes, err := json.MarshalIndent(keys, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyringFile := filepath.Join(a.config.DataDir, path)
|
||||||
|
|
||||||
|
// If the keyring file already exists, don't re-initialize
|
||||||
|
if _, err := os.Stat(keyringFile); err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fh, err := os.OpenFile(keyringFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fh.Close()
|
||||||
|
|
||||||
|
if _, err := fh.Write(keyringBytes); err != nil {
|
||||||
|
os.Remove(keyringFile)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -220,7 +220,7 @@ func (c *Command) readConfig() *Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warn if an encryption key is passed while a keyring already exists
|
// Warn if an encryption key is passed while a keyring already exists
|
||||||
if config.EncryptKey != "" && config.CheckKeyringFiles() {
|
if config.EncryptKey != "" && (config.PersistKeyring && config.CheckKeyringFiles()) {
|
||||||
c.Ui.Error(fmt.Sprintf(
|
c.Ui.Error(fmt.Sprintf(
|
||||||
"WARNING: Keyring already exists, ignoring new key %s",
|
"WARNING: Keyring already exists, ignoring new key %s",
|
||||||
config.EncryptKey))
|
config.EncryptKey))
|
||||||
|
@ -594,7 +594,10 @@ func (c *Command) Run(args []string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if gossip is encrypted
|
// Determine if gossip is encrypted
|
||||||
gossipEncrypted := (config.EncryptKey != "" || config.CheckKeyringFiles())
|
gossipEncrypted := false
|
||||||
|
if config.EncryptKey != "" || (config.PersistKeyring && config.CheckKeyringFiles()) {
|
||||||
|
gossipEncrypted = true
|
||||||
|
}
|
||||||
|
|
||||||
// Let the agent know we've finished registration
|
// Let the agent know we've finished registration
|
||||||
c.agent.StartSync()
|
c.agent.StartSync()
|
||||||
|
|
|
@ -418,12 +418,13 @@ func (c *Config) ClientListenerAddr(override string, port int) (string, error) {
|
||||||
|
|
||||||
// CheckKeyringFiles checks for existence of the keyring files for Serf
|
// CheckKeyringFiles checks for existence of the keyring files for Serf
|
||||||
func (c *Config) CheckKeyringFiles() bool {
|
func (c *Config) CheckKeyringFiles() bool {
|
||||||
serfDir := filepath.Join(c.DataDir, "serf")
|
if _, err := os.Stat(filepath.Join(c.DataDir, serfLANKeyring)); err != nil {
|
||||||
if _, err := os.Stat(filepath.Join(serfDir, "keyring_lan")); err != nil {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if _, err := os.Stat(filepath.Join(serfDir, "keyring_wan")); err != nil {
|
if c.Server {
|
||||||
return false
|
if _, err := os.Stat(filepath.Join(c.DataDir, serfWANKeyring)); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue