mirror of
https://github.com/minio/minio.git
synced 2025-05-21 01:23:57 -04:00
ssl: Set a global boolean to enable SSL across Minio (#3558)
We have been using `isSSL()` everywhere we can set a global value once and re-use it again.
This commit is contained in:
parent
12a7a15daa
commit
08b6cfb082
@ -125,7 +125,7 @@ func makeAdminPeers(eps []*url.URL) adminPeers {
|
|||||||
accessKey: serverCred.AccessKey,
|
accessKey: serverCred.AccessKey,
|
||||||
secretKey: serverCred.SecretKey,
|
secretKey: serverCred.SecretKey,
|
||||||
serverAddr: ep.Host,
|
serverAddr: ep.Host,
|
||||||
secureConn: isSSL(),
|
secureConn: globalIsSSL,
|
||||||
serviceEndpoint: path.Join(reservedBucket, adminPath),
|
serviceEndpoint: path.Join(reservedBucket, adminPath),
|
||||||
serviceName: "Admin",
|
serviceName: "Admin",
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ func updateCredsOnPeers(creds credential) map[string]error {
|
|||||||
accessKey: serverCred.AccessKey,
|
accessKey: serverCred.AccessKey,
|
||||||
secretKey: serverCred.SecretKey,
|
secretKey: serverCred.SecretKey,
|
||||||
serverAddr: peers[ix],
|
serverAddr: peers[ix],
|
||||||
secureConn: isSSL(),
|
secureConn: globalIsSSL,
|
||||||
serviceEndpoint: path.Join(reservedBucket, browserPeerPath),
|
serviceEndpoint: path.Join(reservedBucket, browserPeerPath),
|
||||||
serviceName: "Browser",
|
serviceName: "Browser",
|
||||||
})
|
})
|
||||||
|
@ -90,6 +90,9 @@ var (
|
|||||||
// CA root certificates, a nil value means system certs pool will be used
|
// CA root certificates, a nil value means system certs pool will be used
|
||||||
globalRootCAs *x509.CertPool
|
globalRootCAs *x509.CertPool
|
||||||
|
|
||||||
|
// IsSSL indicates if the server is configured with SSL.
|
||||||
|
globalIsSSL bool
|
||||||
|
|
||||||
// List of admin peers.
|
// List of admin peers.
|
||||||
globalAdminPeers = adminPeers{}
|
globalAdminPeers = adminPeers{}
|
||||||
|
|
||||||
@ -124,4 +127,7 @@ func setGlobalsFromContext(c *cli.Context) {
|
|||||||
}
|
}
|
||||||
// Set global quiet flag.
|
// Set global quiet flag.
|
||||||
globalQuiet = c.Bool("quiet") || c.GlobalBool("quiet")
|
globalQuiet = c.Bool("quiet") || c.GlobalBool("quiet")
|
||||||
|
|
||||||
|
// Is TLS configured?.
|
||||||
|
globalIsSSL = isSSL()
|
||||||
}
|
}
|
||||||
|
@ -289,7 +289,7 @@ func (l *lockServer) lockMaintenance(interval time.Duration) {
|
|||||||
secretKey: serverCred.SecretKey,
|
secretKey: serverCred.SecretKey,
|
||||||
serverAddr: nlrip.lri.node,
|
serverAddr: nlrip.lri.node,
|
||||||
serviceEndpoint: nlrip.lri.rpcPath,
|
serviceEndpoint: nlrip.lri.rpcPath,
|
||||||
secureConn: isSSL(),
|
secureConn: globalIsSSL,
|
||||||
serviceName: "Dsync",
|
serviceName: "Dsync",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -164,7 +164,10 @@ func checkUpdate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generic Minio initialization to create/load config, prepare loggers, etc..
|
// Generic Minio initialization to create/load config, prepare loggers, etc..
|
||||||
func minioInit() {
|
func minioInit(ctx *cli.Context) {
|
||||||
|
// Set global variables after parsing passed arguments
|
||||||
|
setGlobalsFromContext(ctx)
|
||||||
|
|
||||||
// Sets new config directory.
|
// Sets new config directory.
|
||||||
setGlobalConfigPath(globalConfigDir)
|
setGlobalConfigPath(globalConfigDir)
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ func initDsyncNodes(eps []*url.URL) error {
|
|||||||
secretKey: cred.SecretKey,
|
secretKey: cred.SecretKey,
|
||||||
serverAddr: ep.Host,
|
serverAddr: ep.Host,
|
||||||
serviceEndpoint: pathutil.Join(lockRPCPath, getPath(ep)),
|
serviceEndpoint: pathutil.Join(lockRPCPath, getPath(ep)),
|
||||||
secureConn: isSSL(),
|
secureConn: globalIsSSL,
|
||||||
serviceName: "Dsync",
|
serviceName: "Dsync",
|
||||||
})
|
})
|
||||||
if isLocalStorage(ep) && myNode == -1 {
|
if isLocalStorage(ep) && myNode == -1 {
|
||||||
|
@ -99,11 +99,7 @@ func getHealEndpoint(tls bool, firstEndpoint *url.URL) (cEndpoint *url.URL) {
|
|||||||
func getHealMsg(endpoints []*url.URL, storageDisks []StorageAPI) string {
|
func getHealMsg(endpoints []*url.URL, storageDisks []StorageAPI) string {
|
||||||
msg := fmt.Sprintln("\nData volume requires HEALING. Healing is not implemented yet stay tuned:")
|
msg := fmt.Sprintln("\nData volume requires HEALING. Healing is not implemented yet stay tuned:")
|
||||||
// FIXME: Enable this after we bring in healing.
|
// FIXME: Enable this after we bring in healing.
|
||||||
// msg += "MINIO_ACCESS_KEY=%s "
|
// msg := "mc admin heal myminio"
|
||||||
// msg += "MINIO_SECRET_KEY=%s "
|
|
||||||
// msg += "minio control heal %s"
|
|
||||||
// creds := serverConfig.GetCredential()
|
|
||||||
// msg = fmt.Sprintf(msg, creds.AccessKey, creds.SecretKey, getHealEndpoint(isSSL(), endpoints[0]))
|
|
||||||
disksInfo, _, _ := getDisksInfo(storageDisks)
|
disksInfo, _, _ := getDisksInfo(storageDisks)
|
||||||
for i, info := range disksInfo {
|
for i, info := range disksInfo {
|
||||||
if storageDisks[i] == nil {
|
if storageDisks[i] == nil {
|
||||||
|
@ -67,7 +67,7 @@ func makeS3Peers(eps []*url.URL) s3Peers {
|
|||||||
secretKey: serverCred.SecretKey,
|
secretKey: serverCred.SecretKey,
|
||||||
serverAddr: ep.Host,
|
serverAddr: ep.Host,
|
||||||
serviceEndpoint: path.Join(reservedBucket, s3Path),
|
serviceEndpoint: path.Join(reservedBucket, s3Path),
|
||||||
secureConn: isSSL(),
|
secureConn: globalIsSSL,
|
||||||
serviceName: "S3",
|
serviceName: "S3",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,12 +17,14 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -296,11 +298,10 @@ func checkServerSyntax(c *cli.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tls := isSSL()
|
|
||||||
for _, ep := range endpoints {
|
for _, ep := range endpoints {
|
||||||
if ep.Scheme == "https" && !tls {
|
if ep.Scheme == "https" && !globalIsSSL {
|
||||||
// Certificates should be provided for https configuration.
|
// Certificates should be provided for https configuration.
|
||||||
fatalIf(errInvalidArgument, "Certificates not provided for https")
|
fatalIf(errInvalidArgument, "Certificates not provided for secure configuration")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,17 +318,47 @@ func isAnyEndpointLocal(eps []*url.URL) bool {
|
|||||||
return anyLocalEp
|
return anyLocalEp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returned when there are no ports.
|
||||||
|
var errEmptyPort = errors.New("Port cannot be empty or '0', please use `--address` to pick a specific port")
|
||||||
|
|
||||||
|
// Convert an input address of form host:port into, host and port, returns if any.
|
||||||
|
func getHostPort(address string) (host, port string, err error) {
|
||||||
|
// Check if requested port is available.
|
||||||
|
host, port, err = net.SplitHostPort(address)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty ports.
|
||||||
|
if port == "0" || port == "" {
|
||||||
|
// Port zero or empty means use requested to choose any freely available
|
||||||
|
// port. Avoid this since it won't work with any configured clients,
|
||||||
|
// can lead to serious loss of availability.
|
||||||
|
return "", "", errEmptyPort
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse port.
|
||||||
|
if _, err = strconv.Atoi(port); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if port is available.
|
||||||
|
if err = checkPortAvailability(port); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Success.
|
||||||
|
return host, port, nil
|
||||||
|
}
|
||||||
|
|
||||||
// serverMain handler called for 'minio server' command.
|
// serverMain handler called for 'minio server' command.
|
||||||
func serverMain(c *cli.Context) {
|
func serverMain(c *cli.Context) {
|
||||||
if !c.Args().Present() || c.Args().First() == "help" {
|
if !c.Args().Present() || c.Args().First() == "help" {
|
||||||
cli.ShowCommandHelpAndExit(c, "server", 1)
|
cli.ShowCommandHelpAndExit(c, "server", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set global variables after parsing passed arguments
|
|
||||||
setGlobalsFromContext(c)
|
|
||||||
|
|
||||||
// Initialization routine, such as config loading, enable logging, ..
|
// Initialization routine, such as config loading, enable logging, ..
|
||||||
minioInit()
|
minioInit(c)
|
||||||
|
|
||||||
// Check for minio updates from dl.minio.io
|
// Check for minio updates from dl.minio.io
|
||||||
checkUpdate()
|
checkUpdate()
|
||||||
@ -335,20 +366,9 @@ func serverMain(c *cli.Context) {
|
|||||||
// Server address.
|
// Server address.
|
||||||
serverAddr := c.String("address")
|
serverAddr := c.String("address")
|
||||||
|
|
||||||
// Check if requested port is available.
|
var err error
|
||||||
host, portStr, err := net.SplitHostPort(serverAddr)
|
globalMinioHost, globalMinioPort, err = getHostPort(serverAddr)
|
||||||
fatalIf(err, "Unable to parse %s.", serverAddr)
|
fatalIf(err, "Unable to extract host and port %s", serverAddr)
|
||||||
if portStr == "0" || portStr == "" {
|
|
||||||
// Port zero or empty means use requested to choose any freely available
|
|
||||||
// port. Avoid this since it won't work with any configured clients,
|
|
||||||
// can lead to serious loss of availability.
|
|
||||||
fatalIf(errInvalidArgument, "Invalid port `%s`, please use `--address` to pick a specific port", portStr)
|
|
||||||
}
|
|
||||||
globalMinioHost = host
|
|
||||||
|
|
||||||
// Check if requested port is available.
|
|
||||||
fatalIf(checkPortAvailability(portStr), "Port unavailable %s", portStr)
|
|
||||||
globalMinioPort = portStr
|
|
||||||
|
|
||||||
// Check server syntax and exit in case of errors.
|
// Check server syntax and exit in case of errors.
|
||||||
// Done after globalMinioHost and globalMinioPort is set as parseStorageEndpoints()
|
// Done after globalMinioHost and globalMinioPort is set as parseStorageEndpoints()
|
||||||
@ -365,9 +385,6 @@ func serverMain(c *cli.Context) {
|
|||||||
fatalIf(errInvalidArgument, "None of the disks passed as command line args are local to this server.")
|
fatalIf(errInvalidArgument, "None of the disks passed as command line args are local to this server.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is TLS configured?.
|
|
||||||
tls := isSSL()
|
|
||||||
|
|
||||||
// Sort endpoints for consistent ordering across multiple
|
// Sort endpoints for consistent ordering across multiple
|
||||||
// nodes in a distributed setup. This is to avoid format.json
|
// nodes in a distributed setup. This is to avoid format.json
|
||||||
// corruption if the disks aren't supplied in the same order
|
// corruption if the disks aren't supplied in the same order
|
||||||
@ -415,7 +432,8 @@ func serverMain(c *cli.Context) {
|
|||||||
globalMinioAddr = getLocalAddress(srvConfig)
|
globalMinioAddr = getLocalAddress(srvConfig)
|
||||||
|
|
||||||
// Determine API endpoints where we are going to serve the S3 API from.
|
// Determine API endpoints where we are going to serve the S3 API from.
|
||||||
apiEndPoints := finalizeAPIEndpoints(tls, apiServer.Server)
|
apiEndPoints, err := finalizeAPIEndpoints(apiServer.Server)
|
||||||
|
fatalIf(err, "Unable to finalize API endpoints for %s", apiServer.Server.Addr)
|
||||||
|
|
||||||
// Set the global API endpoints value.
|
// Set the global API endpoints value.
|
||||||
globalAPIEndpoints = apiEndPoints
|
globalAPIEndpoints = apiEndPoints
|
||||||
@ -427,15 +445,13 @@ func serverMain(c *cli.Context) {
|
|||||||
initGlobalAdminPeers(endpoints)
|
initGlobalAdminPeers(endpoints)
|
||||||
|
|
||||||
// Start server, automatically configures TLS if certs are available.
|
// Start server, automatically configures TLS if certs are available.
|
||||||
go func(tls bool) {
|
go func() {
|
||||||
var lerr error
|
|
||||||
cert, key := "", ""
|
cert, key := "", ""
|
||||||
if tls {
|
if globalIsSSL {
|
||||||
cert, key = mustGetCertFile(), mustGetKeyFile()
|
cert, key = mustGetCertFile(), mustGetKeyFile()
|
||||||
}
|
}
|
||||||
lerr = apiServer.ListenAndServe(cert, key)
|
fatalIf(apiServer.ListenAndServe(cert, key), "Failed to start minio server.")
|
||||||
fatalIf(lerr, "Failed to start minio server.")
|
}()
|
||||||
}(tls)
|
|
||||||
|
|
||||||
// Wait for formatting of disks.
|
// Wait for formatting of disks.
|
||||||
formattedDisks, err := waitForFormatDisks(firstDisk, endpoints, storageDisks)
|
formattedDisks, err := waitForFormatDisks(firstDisk, endpoints, storageDisks)
|
||||||
|
@ -63,20 +63,66 @@ func TestGetListenIPs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests get host port.
|
||||||
|
func TestGetHostPort(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
addr string
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
// Test 1 - successful.
|
||||||
|
{
|
||||||
|
addr: ":" + getFreePort(),
|
||||||
|
err: nil,
|
||||||
|
},
|
||||||
|
// Test 2 port empty.
|
||||||
|
{
|
||||||
|
addr: ":0",
|
||||||
|
err: errEmptyPort,
|
||||||
|
},
|
||||||
|
// Test 3 port empty.
|
||||||
|
{
|
||||||
|
addr: ":",
|
||||||
|
err: errEmptyPort,
|
||||||
|
},
|
||||||
|
// Test 4 invalid port.
|
||||||
|
{
|
||||||
|
addr: "linux:linux",
|
||||||
|
err: errors.New("strconv.ParseInt: parsing \"linux\": invalid syntax"),
|
||||||
|
},
|
||||||
|
// Test 5 port not present.
|
||||||
|
{
|
||||||
|
addr: "hostname",
|
||||||
|
err: errors.New("missing port in address hostname"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate all tests.
|
||||||
|
for i, testCase := range testCases {
|
||||||
|
_, _, err := getHostPort(testCase.addr)
|
||||||
|
if err != nil {
|
||||||
|
if err.Error() != testCase.err.Error() {
|
||||||
|
t.Fatalf("Test %d: Error: %s", i+1, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests finalize api endpoints.
|
||||||
func TestFinalizeAPIEndpoints(t *testing.T) {
|
func TestFinalizeAPIEndpoints(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
tls bool
|
|
||||||
addr string
|
addr string
|
||||||
}{
|
}{
|
||||||
{false, ":80"},
|
{":80"},
|
||||||
{true, ":80"},
|
{":80"},
|
||||||
{false, "localhost:80"},
|
{"localhost:80"},
|
||||||
{true, "localhost:80"},
|
{"localhost:80"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range testCases {
|
for i, test := range testCases {
|
||||||
endPoints := finalizeAPIEndpoints(test.tls, &http.Server{Addr: test.addr})
|
endPoints, err := finalizeAPIEndpoints(&http.Server{
|
||||||
if len(endPoints) <= 0 {
|
Addr: test.addr,
|
||||||
|
})
|
||||||
|
if err != nil && len(endPoints) <= 0 {
|
||||||
t.Errorf("Test case %d returned with no API end points for %s",
|
t.Errorf("Test case %d returned with no API end points for %s",
|
||||||
i+1, test.addr)
|
i+1, test.addr)
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ func printStartupMessage(apiEndPoints []string) {
|
|||||||
|
|
||||||
// SSL is configured reads certification chain, prints
|
// SSL is configured reads certification chain, prints
|
||||||
// authority and expiry.
|
// authority and expiry.
|
||||||
if isSSL() {
|
if globalIsSSL {
|
||||||
certs, err := readCertificateChain()
|
certs, err := readCertificateChain()
|
||||||
fatalIf(err, "Unable to read certificate chain.")
|
fatalIf(err, "Unable to read certificate chain.")
|
||||||
printCertificateMsg(certs)
|
printCertificateMsg(certs)
|
||||||
|
@ -40,22 +40,27 @@ func getListenIPs(serverAddr string) (hosts []string, port string, err error) {
|
|||||||
}
|
}
|
||||||
return hosts, port, nil
|
return hosts, port, nil
|
||||||
} // if host != "" {
|
} // if host != "" {
|
||||||
|
|
||||||
// Proceed to append itself, since user requested a specific endpoint.
|
// Proceed to append itself, since user requested a specific endpoint.
|
||||||
hosts = append(hosts, host)
|
hosts = append(hosts, host)
|
||||||
|
|
||||||
|
// Success.
|
||||||
return hosts, port, nil
|
return hosts, port, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalizes the API endpoints based on the host list and port.
|
// Finalizes the API endpoints based on the host list and port.
|
||||||
func finalizeAPIEndpoints(tls bool, apiServer *http.Server) (endPoints []string) {
|
func finalizeAPIEndpoints(apiServer *http.Server) (endPoints []string, err error) {
|
||||||
// Verify current scheme.
|
// Verify current scheme.
|
||||||
scheme := "http"
|
scheme := "http"
|
||||||
if tls {
|
if globalIsSSL {
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get list of listen ips and port.
|
// Get list of listen ips and port.
|
||||||
hosts, port, err := getListenIPs(apiServer.Addr)
|
hosts, port, err1 := getListenIPs(apiServer.Addr)
|
||||||
fatalIf(err, "Unable to get list of ips to listen on")
|
if err1 != nil {
|
||||||
|
return nil, err1
|
||||||
|
}
|
||||||
|
|
||||||
// Construct proper endpoints.
|
// Construct proper endpoints.
|
||||||
for _, host := range hosts {
|
for _, host := range hosts {
|
||||||
@ -63,5 +68,5 @@ func finalizeAPIEndpoints(tls bool, apiServer *http.Server) (endPoints []string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Success.
|
// Success.
|
||||||
return endPoints
|
return endPoints, nil
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ func newStorageRPC(ep *url.URL) (StorageAPI, error) {
|
|||||||
secretKey: secretKey,
|
secretKey: secretKey,
|
||||||
serverAddr: rpcAddr,
|
serverAddr: rpcAddr,
|
||||||
serviceEndpoint: rpcPath,
|
serviceEndpoint: rpcPath,
|
||||||
secureConn: isSSL(),
|
secureConn: globalIsSSL,
|
||||||
serviceName: "Storage",
|
serviceName: "Storage",
|
||||||
disableReconnect: true,
|
disableReconnect: true,
|
||||||
}),
|
}),
|
||||||
|
@ -265,12 +265,8 @@ func getReleaseUpdate(updateURL string, duration time.Duration) (updateMsg updat
|
|||||||
|
|
||||||
// main entry point for update command.
|
// main entry point for update command.
|
||||||
func mainUpdate(ctx *cli.Context) {
|
func mainUpdate(ctx *cli.Context) {
|
||||||
|
|
||||||
// Set global variables after parsing passed arguments
|
|
||||||
setGlobalsFromContext(ctx)
|
|
||||||
|
|
||||||
// Initialization routine, such as config loading, enable logging, ..
|
// Initialization routine, such as config loading, enable logging, ..
|
||||||
minioInit()
|
minioInit(ctx)
|
||||||
|
|
||||||
if globalQuiet {
|
if globalQuiet {
|
||||||
return
|
return
|
||||||
|
@ -44,11 +44,8 @@ func mainVersion(ctx *cli.Context) {
|
|||||||
cli.ShowCommandHelpAndExit(ctx, "version", 1)
|
cli.ShowCommandHelpAndExit(ctx, "version", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set global variables after parsing passed arguments
|
|
||||||
setGlobalsFromContext(ctx)
|
|
||||||
|
|
||||||
// Initialization routine, such as config loading, enable logging, ..
|
// Initialization routine, such as config loading, enable logging, ..
|
||||||
minioInit()
|
minioInit(ctx)
|
||||||
|
|
||||||
if globalQuiet {
|
if globalQuiet {
|
||||||
return
|
return
|
||||||
|
Loading…
x
Reference in New Issue
Block a user