raft join tls (#6932)

This commit is contained in:
Vishal Nayak
2019-06-21 17:41:07 -04:00
committed by GitHub
parent ab2abca8c5
commit c356df69a1
3 changed files with 73 additions and 14 deletions

View File

@@ -15,8 +15,10 @@ type RaftJoinResponse struct {
// RaftJoinRequest represents the parameters consumed by the raft join API // RaftJoinRequest represents the parameters consumed by the raft join API
type RaftJoinRequest struct { type RaftJoinRequest struct {
LeaderAddr string `json:"leader_api_addr"` LeaderAPIAddr string `json:"leader_api_addr"`
CACert string `json:"ca_cert":` LeaderCACert string `json:"leader_ca_cert":`
LeaderClientCert string `json:"leader_client_cert"`
LeaderClientKey string `json:"leader_client_key"`
Retry bool `json:"retry"` Retry bool `json:"retry"`
} }

View File

@@ -14,7 +14,9 @@ var _ cli.CommandAutocomplete = (*OperatorRaftJoinCommand)(nil)
type OperatorRaftJoinCommand struct { type OperatorRaftJoinCommand struct {
flagRaftRetry bool flagRaftRetry bool
flagRaftCACert string flagLeaderCACert string
flagLeaderClientCert string
flagLeaderClientKey string
*BaseCommand *BaseCommand
} }
@@ -42,12 +44,26 @@ func (c *OperatorRaftJoinCommand) Flags() *FlagSets {
f := set.NewFlagSet("Command Options") f := set.NewFlagSet("Command Options")
f.StringVar(&StringVar{ f.StringVar(&StringVar{
Name: "raft-ca-cert", Name: "leader-ca-cert",
Target: &c.flagRaftCACert, Target: &c.flagLeaderCACert,
Completion: complete.PredictNothing, Completion: complete.PredictNothing,
Usage: "CA cert to communicate with raft leader.", Usage: "CA cert to communicate with raft leader.",
}) })
f.StringVar(&StringVar{
Name: "leader-client-cert",
Target: &c.flagLeaderClientCert,
Completion: complete.PredictNothing,
Usage: "Client cert to to authenticate to raft leader.",
})
f.StringVar(&StringVar{
Name: "leader-client-key",
Target: &c.flagLeaderClientKey,
Completion: complete.PredictNothing,
Usage: "Client key to to authenticate to raft leader.",
})
f.BoolVar(&BoolVar{ f.BoolVar(&BoolVar{
Name: "retry", Name: "retry",
Target: &c.flagRaftRetry, Target: &c.flagRaftRetry,
@@ -97,9 +113,11 @@ func (c *OperatorRaftJoinCommand) Run(args []string) int {
} }
resp, err := client.Sys().RaftJoin(&api.RaftJoinRequest{ resp, err := client.Sys().RaftJoin(&api.RaftJoinRequest{
LeaderAddr: leaderAPIAddr, LeaderAPIAddr: leaderAPIAddr,
LeaderCACert: c.flagLeaderCACert,
LeaderClientCert: c.flagLeaderClientCert,
LeaderClientKey: c.flagLeaderClientKey,
Retry: c.flagRaftRetry, Retry: c.flagRaftRetry,
CACert: c.flagRaftCACert,
}) })
if err != nil { if err != nil {
c.UI.Error(fmt.Sprintf("Error joining the node to the raft cluster: %s", err)) c.UI.Error(fmt.Sprintf("Error joining the node to the raft cluster: %s", err))

View File

@@ -2,6 +2,10 @@ package http
import ( import (
"context" "context"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io" "io"
"net/http" "net/http"
@@ -27,7 +31,40 @@ func handleSysRaftJoinPost(core *vault.Core, w http.ResponseWriter, r *http.Requ
return return
} }
joined, err := core.JoinRaftCluster(context.Background(), req.LeaderAddr, nil, req.Retry) var tlsConfig *tls.Config
switch {
case req.LeaderCACert != "" && req.LeaderClientCert != "" && req.LeaderClientKey != "":
// Create TLS Config
pool := x509.NewCertPool()
pool.AppendCertsFromPEM([]byte(req.LeaderCACert))
cert, err := tls.X509KeyPair([]byte(req.LeaderClientCert), []byte(req.LeaderClientKey))
if err != nil {
respondError(w, http.StatusBadRequest, fmt.Errorf("invalid key pair: %v", err))
return
}
tlsConfig = &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: pool,
ClientAuth: tls.RequireAndVerifyClientCert,
MinVersion: tls.VersionTLS12,
}
tlsConfig.BuildNameToCertificate()
case req.LeaderCACert != "":
respondError(w, http.StatusBadRequest, errors.New("ca_cert, client_key, client_cert must all be set; or none should be set"))
return
case req.LeaderClientCert != "":
respondError(w, http.StatusBadRequest, errors.New("ca_cert, client_key, client_cert must all be set; or none should be set"))
return
case req.LeaderClientKey != "":
respondError(w, http.StatusBadRequest, errors.New("ca_cert, client_key, client_cert must all be set; or none should be set"))
return
}
joined, err := core.JoinRaftCluster(context.Background(), req.LeaderAPIAddr, tlsConfig, req.Retry)
if err != nil { if err != nil {
respondError(w, http.StatusInternalServerError, err) respondError(w, http.StatusInternalServerError, err)
return return
@@ -44,7 +81,9 @@ type JoinResponse struct {
} }
type JoinRequest struct { type JoinRequest struct {
LeaderAddr string `json:"leader_api_addr"` LeaderAPIAddr string `json:"leader_api_addr"`
CACert string `json:"ca_cert":` LeaderCACert string `json:"leader_ca_cert":`
LeaderClientCert string `json:"leader_client_cert"`
LeaderClientKey string `json:"leader_client_key"`
Retry bool `json:"retry"` Retry bool `json:"retry"`
} }