mirror of
https://github.com/minio/minio.git
synced 2024-12-24 22:25:54 -05:00
Add TLS encryption capability to RPC clients (#2789)
This commit is contained in:
parent
1e6afac3bd
commit
9fb1c89f81
@ -83,6 +83,7 @@ func isRPCTokenValid(tokenStr string) bool {
|
|||||||
type authConfig struct {
|
type authConfig struct {
|
||||||
accessKey string // Username for the server.
|
accessKey string // Username for the server.
|
||||||
secretKey string // Password for the server.
|
secretKey string // Password for the server.
|
||||||
|
secureConn bool // Ask for a secured connection
|
||||||
address string // Network address path of RPC server.
|
address string // Network address path of RPC server.
|
||||||
path string // Network path for HTTP dial.
|
path string // Network path for HTTP dial.
|
||||||
loginMethod string // RPC service name for authenticating using JWT
|
loginMethod string // RPC service name for authenticating using JWT
|
||||||
@ -104,7 +105,7 @@ func newAuthClient(cfg *authConfig) *AuthRPCClient {
|
|||||||
// Save the config.
|
// Save the config.
|
||||||
config: cfg,
|
config: cfg,
|
||||||
// Initialize a new reconnectable rpc client.
|
// Initialize a new reconnectable rpc client.
|
||||||
rpc: newClient(cfg.address, cfg.path),
|
rpc: newClient(cfg.address, cfg.path, cfg.secureConn),
|
||||||
// Allocated auth client not logged in yet.
|
// Allocated auth client not logged in yet.
|
||||||
isLoggedIn: false,
|
isLoggedIn: false,
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,7 @@ func healControl(ctx *cli.Context) {
|
|||||||
authCfg := &authConfig{
|
authCfg := &authConfig{
|
||||||
accessKey: serverConfig.GetCredential().AccessKeyID,
|
accessKey: serverConfig.GetCredential().AccessKeyID,
|
||||||
secretKey: serverConfig.GetCredential().SecretAccessKey,
|
secretKey: serverConfig.GetCredential().SecretAccessKey,
|
||||||
|
secureConn: parsedURL.Scheme == "https",
|
||||||
address: parsedURL.Host,
|
address: parsedURL.Host,
|
||||||
path: path.Join(reservedBucket, controlPath),
|
path: path.Join(reservedBucket, controlPath),
|
||||||
loginMethod: "Controller.LoginHandler",
|
loginMethod: "Controller.LoginHandler",
|
||||||
|
@ -126,6 +126,7 @@ func lockControl(c *cli.Context) {
|
|||||||
authCfg := &authConfig{
|
authCfg := &authConfig{
|
||||||
accessKey: serverConfig.GetCredential().AccessKeyID,
|
accessKey: serverConfig.GetCredential().AccessKeyID,
|
||||||
secretKey: serverConfig.GetCredential().SecretAccessKey,
|
secretKey: serverConfig.GetCredential().SecretAccessKey,
|
||||||
|
secureConn: parsedURL.Scheme == "https",
|
||||||
address: parsedURL.Host,
|
address: parsedURL.Host,
|
||||||
path: path.Join(reservedBucket, controlPath),
|
path: path.Join(reservedBucket, controlPath),
|
||||||
loginMethod: "Controller.LoginHandler",
|
loginMethod: "Controller.LoginHandler",
|
||||||
|
@ -66,6 +66,7 @@ func shutdownControl(c *cli.Context) {
|
|||||||
authCfg := &authConfig{
|
authCfg := &authConfig{
|
||||||
accessKey: serverConfig.GetCredential().AccessKeyID,
|
accessKey: serverConfig.GetCredential().AccessKeyID,
|
||||||
secretKey: serverConfig.GetCredential().SecretAccessKey,
|
secretKey: serverConfig.GetCredential().SecretAccessKey,
|
||||||
|
secureConn: parsedURL.Scheme == "https",
|
||||||
address: parsedURL.Host,
|
address: parsedURL.Host,
|
||||||
path: path.Join(reservedBucket, controlPath),
|
path: path.Join(reservedBucket, controlPath),
|
||||||
loginMethod: "Controller.LoginHandler",
|
loginMethod: "Controller.LoginHandler",
|
||||||
|
@ -294,7 +294,7 @@ func (l *lockServer) lockMaintenance(interval time.Duration) {
|
|||||||
// Validate if long lived locks are indeed clean.
|
// Validate if long lived locks are indeed clean.
|
||||||
for _, nlrip := range nlripLongLived {
|
for _, nlrip := range nlripLongLived {
|
||||||
// Initialize client based on the long live locks.
|
// Initialize client based on the long live locks.
|
||||||
c := newClient(nlrip.lri.node, nlrip.lri.rpcPath)
|
c := newClient(nlrip.lri.node, nlrip.lri.rpcPath, isSSL())
|
||||||
|
|
||||||
var expired bool
|
var expired bool
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ func initDsyncNodes(disks []string, port int) error {
|
|||||||
accessKey: cred.AccessKeyID,
|
accessKey: cred.AccessKeyID,
|
||||||
secretKey: cred.SecretAccessKey,
|
secretKey: cred.SecretAccessKey,
|
||||||
// Construct a new dsync server addr.
|
// Construct a new dsync server addr.
|
||||||
|
secureConn: isSSL(),
|
||||||
address: disk[:idx] + ":" + serverPort,
|
address: disk[:idx] + ":" + serverPort,
|
||||||
// Construct a new rpc path for the disk.
|
// Construct a new rpc path for the disk.
|
||||||
path: pathutil.Join(lockRPCPath, disk[idx+1:]),
|
path: pathutil.Join(lockRPCPath, disk[idx+1:]),
|
||||||
|
@ -17,7 +17,12 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
"net/rpc"
|
"net/rpc"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
@ -28,15 +33,17 @@ type RPCClient struct {
|
|||||||
rpcPrivate *rpc.Client
|
rpcPrivate *rpc.Client
|
||||||
node string
|
node string
|
||||||
rpcPath string
|
rpcPath string
|
||||||
|
secureConn bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// newClient constructs a RPCClient object with node and rpcPath initialized.
|
// newClient constructs a RPCClient object with node and rpcPath initialized.
|
||||||
// It _doesn't_ connect to the remote endpoint. See Call method to see when the
|
// It _doesn't_ connect to the remote endpoint. See Call method to see when the
|
||||||
// connect happens.
|
// connect happens.
|
||||||
func newClient(node, rpcPath string) *RPCClient {
|
func newClient(node, rpcPath string, secureConn bool) *RPCClient {
|
||||||
return &RPCClient{
|
return &RPCClient{
|
||||||
node: node,
|
node: node,
|
||||||
rpcPath: rpcPath,
|
rpcPath: rpcPath,
|
||||||
|
secureConn: secureConn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,14 +70,41 @@ func (rpcClient *RPCClient) dialRPCClient() (*rpc.Client, error) {
|
|||||||
if rpcClient.rpcPrivate != nil {
|
if rpcClient.rpcPrivate != nil {
|
||||||
return rpcClient.rpcPrivate, nil
|
return rpcClient.rpcPrivate, nil
|
||||||
}
|
}
|
||||||
rpc, err := rpc.DialHTTPPath("tcp", rpcClient.node, rpcClient.rpcPath)
|
|
||||||
|
var err error
|
||||||
|
var conn net.Conn
|
||||||
|
|
||||||
|
if rpcClient.secureConn {
|
||||||
|
conn, err = tls.Dial("tcp", rpcClient.node, &tls.Config{})
|
||||||
|
} else {
|
||||||
|
conn, err = net.Dial("tcp", rpcClient.node)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if rpc == nil {
|
}
|
||||||
|
io.WriteString(conn, "CONNECT "+rpcClient.rpcPath+" HTTP/1.0\n\n")
|
||||||
|
|
||||||
|
// Require successful HTTP response
|
||||||
|
// before switching to RPC protocol.
|
||||||
|
resp, err := http.ReadResponse(bufio.NewReader(conn), &http.Request{Method: "CONNECT"})
|
||||||
|
if err == nil && resp.Status == "200 Connected to Go RPC" {
|
||||||
|
rpc := rpc.NewClient(conn)
|
||||||
|
if rpc == nil {
|
||||||
return nil, errors.New("No valid RPC Client created after dial")
|
return nil, errors.New("No valid RPC Client created after dial")
|
||||||
}
|
}
|
||||||
rpcClient.rpcPrivate = rpc
|
rpcClient.rpcPrivate = rpc
|
||||||
return rpcClient.rpcPrivate, nil
|
return rpc, nil
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
err = errors.New("unexpected HTTP response: " + resp.Status)
|
||||||
|
}
|
||||||
|
conn.Close()
|
||||||
|
return nil, &net.OpError{
|
||||||
|
Op: "dial-http",
|
||||||
|
Net: rpcClient.node + " " + rpcClient.rpcPath,
|
||||||
|
Addr: nil,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call makes a RPC call to the remote endpoint using the default codec, namely encoding/gob.
|
// Call makes a RPC call to the remote endpoint using the default codec, namely encoding/gob.
|
||||||
|
@ -107,6 +107,7 @@ func newRPCClient(networkPath string) (StorageAPI, error) {
|
|||||||
rpcClient := newAuthClient(&authConfig{
|
rpcClient := newAuthClient(&authConfig{
|
||||||
accessKey: cred.AccessKeyID,
|
accessKey: cred.AccessKeyID,
|
||||||
secretKey: cred.SecretAccessKey,
|
secretKey: cred.SecretAccessKey,
|
||||||
|
secureConn: isSSL(),
|
||||||
address: rpcAddr,
|
address: rpcAddr,
|
||||||
path: rpcPath,
|
path: rpcPath,
|
||||||
loginMethod: "Storage.LoginHandler",
|
loginMethod: "Storage.LoginHandler",
|
||||||
|
Loading…
Reference in New Issue
Block a user