Adds gossip encryption key; copies Config.Gossip{Port,Seed} to Config.Gossip.{Port,Seed}, deprecates --gossip-port and --gossip-seed. Use --gossip.port and --gossip.seed

This commit is contained in:
Yuce Tekol 2017-10-13 13:30:41 +03:00
parent 2c5a8d9125
commit eec739c331
No known key found for this signature in database
GPG key ID: CB59E46D2FB90573
5 changed files with 80 additions and 25 deletions

View file

@ -60,11 +60,19 @@ type TLSConfig struct {
// Config represents the configuration for the command.
type Config struct {
DataDir string `toml:"data-dir"`
Bind string `toml:"bind"`
DataDir string `toml:"data-dir"`
Bind string `toml:"bind"`
// GossipPort DEPRECATED
GossipPort string `toml:"gossip-port"`
// GossipSeed DEPRECATED
GossipSeed string `toml:"gossip-seed"`
Gossip struct {
Port string `toml:"port"`
Seed string `toml:"seed"`
Key string `toml:"key"`
} `toml:"gossip"`
Cluster struct {
ReplicaN int `toml:"replicas"`
Type string `toml:"type"`

View file

@ -26,8 +26,11 @@ func BuildServerFlags(cmd *cobra.Command, srv *server.Command) {
flags := cmd.Flags()
flags.StringVarP(&srv.Config.DataDir, "data-dir", "d", "~/.pilosa", "Directory to store pilosa data files.")
flags.StringVarP(&srv.Config.Bind, "bind", "b", ":10101", "Default URI on which pilosa should listen.")
flags.StringVarP(&srv.Config.GossipPort, "gossip-port", "", "", "Port to which pilosa should bind for internal state sharing.")
flags.StringVarP(&srv.Config.GossipSeed, "gossip-seed", "", "", "Host with which to seed the gossip membership.")
flags.StringVarP(&srv.Config.GossipPort, "gossip-port", "", "", "(DEPRECATED) Port to which pilosa should bind for internal state sharing.")
flags.StringVarP(&srv.Config.GossipSeed, "gossip-seed", "", "", "(DEPRECATED) Host with which to seed the gossip membership.")
flags.StringVarP(&srv.Config.Gossip.Port, "gossip.port", "", "", "Port to which pilosa should bind for internal state sharing.")
flags.StringVarP(&srv.Config.Gossip.Seed, "gossip.seed", "", "", "Host with which to seed the gossip membership.")
flags.StringVarP(&srv.Config.Gossip.Key, "gossip.key", "", "", "The path to file of the encryption key for gossip. The contents of the file should be either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.")
flags.IntVarP(&srv.Config.MaxWritesPerRequest, "max-writes-per-request", "", srv.Config.MaxWritesPerRequest, "Number of write commands per request.")
flags.IntVarP(&srv.Config.Cluster.ReplicaN, "cluster.replicas", "", 1, "Number of hosts each piece of data should be stored on.")
flags.StringSliceVarP(&srv.Config.Cluster.Hosts, "cluster.hosts", "", []string{}, "Comma separated list of hosts in cluster.")

View file

@ -79,23 +79,36 @@ Any flag that has a value that is a comma separated list on the command line bec
#### Gossip Port
* Description: Port to which Pilosa should bind for internal communication.
* Flag: `--gossip-port=11101`
* Flag: `--gossip.port=11101`
* Env: `PILOSA_GOSSIP_PORT=11101`
* Config:
```toml
gossip-port = 11101
[gossip]
port = 11101
```
#### Gossip Seed
* Description: When using the gossip [Cluster Type]({{< ref "#cluster-type" >}}), this specifies which internal host should be used to initialize membership in the cluster. Typcially this can be the address of any available host in the cluster. For example, when starting a three-node cluster made up of `node0`, `node1`, and `node2`, the `gossip-seed` for all three nodes can be configured to be the address of `node0`.
* Flag: `--gossip-seed="localhost:11101"`
* Flag: `--gossip.seed="localhost:11101"`
* Env: `PILOSA_GOSSIP_SEED="localhost:11101"`
* Config:
```toml
gossip-seed = "localhost:11101"
[gossip]
seed = "localhost:11101"
```
#### Gossip Key
* Description: Path to the file which contains the key to encrypt gossip communication. The contents of the file should be either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256 encryption. You can read from `/dev/random` device on UNIX-like systems to create the key file; e.g., `head -c 32 /dev/random > gossip.key32` creates a key file to use AES-256.
* Flag: `--gossip.key="/var/secret/gossip.key32"`
* Env: `PILOSA_GOSSIP_KEY="/var/secret/gossip.key32"`
* Config:
```toml
[gossip]
key = "/var/secret/gossip.key32"
```
#### Cluster Hosts
@ -250,8 +263,10 @@ A three node cluster could be minimally configured as follows:
data-dir = "/home/pilosa/data"
bind = "node0.pilosa.com:10101"
gossip-port = 12000
gossip-seed = "node0.pilosa.com:12000"
[gossip]
port = 12000
seed = "node0.pilosa.com:12000"
[cluster]
replicas = 1
@ -262,8 +277,10 @@ A three node cluster could be minimally configured as follows:
data-dir = "/home/pilosa/data"
bind = "node1.pilosa.com:10101"
gossip-port = 12000
gossip-seed = "node0.pilosa.com:12000"
[gossip]
port = 12000
seed = "node0.pilosa.com:12000"
[cluster]
replicas = 1
@ -274,8 +291,10 @@ A three node cluster could be minimally configured as follows:
data-dir = "/home/pilosa/data"
bind = "node2.pilosa.com:10101"
gossip-port = 12000
gossip-seed = "node0.pilosa.com:12000"
[gossip]
port = 12000
seed = "node0.pilosa.com:12000"
[cluster]
replicas = 1
@ -285,14 +304,17 @@ A three node cluster could be minimally configured as follows:
### Example Cluster Configuration (HTTPS)
The same cluster which uses HTTPS instead of HTTP can be configured as follows. Note that we explicitly specify `https` as the protocol in `bind` and `cluster.hosts` configuration:
The same cluster which uses HTTPS instead of HTTP can be configured as follows. Note that we explicitly specify `https` as the protocol in `bind` and `cluster.hosts` configuration. It is not required to use a gossip key but it is highly recommended:
#### Node 0
data-dir = "/home/pilosa/data"
bind = "https://node0.pilosa.com:10101"
gossip-port = 12000
gossip-seed = "node0.pilosa.com:12000"
[gossip]
port = 12000
seed = "node0.pilosa.com:12000"
key = "/home/pilosa/private/gossip.key32"
[cluster]
replicas = 1
@ -307,8 +329,11 @@ The same cluster which uses HTTPS instead of HTTP can be configured as follows.
data-dir = "/home/pilosa/data"
bind = "https://node1.pilosa.com:10101"
gossip-port = 12000
gossip-seed = "node0.pilosa.com:12000"
[gossip]
port = 12000
seed = "node0.pilosa.com:12000"
key = "/home/pilosa/private/gossip.key32"
[cluster]
replicas = 1
@ -323,8 +348,11 @@ The same cluster which uses HTTPS instead of HTTP can be configured as follows.
data-dir = "/home/pilosa/data"
bind = "https://node2.pilosa.com:10101"
gossip-port = 12000
gossip-seed = "node0.pilosa.com:12000"
[gossip]
port = 12000
seed = "node0.pilosa.com:12000"
key = "/home/pilosa/private/gossip.key32"
[cluster]
replicas = 1

View file

@ -123,7 +123,7 @@ type gossipConfig struct {
}
// NewGossipNodeSet returns a new instance of GossipNodeSet.
func NewGossipNodeSet(name string, gossipHost string, gossipPort int, gossipSeed string, server *pilosa.Server) *GossipNodeSet {
func NewGossipNodeSet(name string, gossipHost string, gossipPort int, gossipSeed string, server *pilosa.Server, secretKey []byte) *GossipNodeSet {
g := &GossipNodeSet{
LogOutput: server.LogOutput,
}
@ -139,6 +139,7 @@ func NewGossipNodeSet(name string, gossipHost string, gossipPort int, gossipSeed
g.config.memberlistConfig.AdvertiseAddr = pilosa.HostToIP(gossipHost)
g.config.memberlistConfig.AdvertisePort = gossipPort
g.config.memberlistConfig.Delegate = g
g.config.memberlistConfig.SecretKey = secretKey
g.statusHandler = server

View file

@ -33,6 +33,7 @@ import (
"github.com/pilosa/pilosa"
"github.com/pilosa/pilosa/gossip"
"github.com/pilosa/pilosa/statsd"
"io/ioutil"
)
func init() {
@ -173,7 +174,10 @@ func (m *Command) SetupServer() error {
// Set internal port (string).
gossipPortStr := pilosa.DefaultGossipPort
if m.Config.GossipPort != "" {
// Config.GossipPort is deprecated, so Config.Gossip.Port has priority
if m.Config.Gossip.Port != "" {
gossipPortStr = m.Config.Gossip.Port
} else if m.Config.GossipPort != "" {
gossipPortStr = m.Config.GossipPort
}
@ -184,13 +188,24 @@ func (m *Command) SetupServer() error {
return err
}
gossipSeed := pilosa.DefaultHost + ":" + pilosa.DefaultGossipPort
if m.Config.GossipSeed != "" {
// Config.GossipSeed is deprecated, so Config.Gossip.Seed has priority
if m.Config.Gossip.Seed != "" {
gossipSeed = m.Config.Gossip.Seed
} else if m.Config.GossipSeed != "" {
gossipSeed = m.Config.GossipSeed
}
var gossipKey []byte
if m.Config.Gossip.Key != "" {
gossipKey, err = ioutil.ReadFile(m.Config.Gossip.Key)
if err != nil {
return err
}
}
// get the host portion of addr to use for binding
gossipHost := uri.Host()
gossipNodeSet := gossip.NewGossipNodeSet(uri.HostPort(), gossipHost, gossipPort, gossipSeed, m.Server)
gossipNodeSet := gossip.NewGossipNodeSet(uri.HostPort(), gossipHost, gossipPort, gossipSeed, m.Server, gossipKey)
m.Server.Cluster.NodeSet = gossipNodeSet
m.Server.Broadcaster = gossipNodeSet
m.Server.BroadcastReceiver = gossipNodeSet