Support etcd TLS certficates (#6719)

This PR supports two models for etcd certs

- Client-to-server transport security with HTTPS
- Client-to-server authentication with HTTPS client certificates
master
Harshavardhana 6 years ago committed by kannappanr
parent 7e879a45d5
commit 9fe51e392b
  1. 17
      cmd/common-main.go
  2. 16
      cmd/gateway-main.go
  3. 3
      cmd/gateway/s3/gateway-s3.go
  4. 12
      cmd/server-main.go
  5. 6
      docs/sts/etcd.md

@ -17,6 +17,7 @@
package cmd package cmd
import ( import (
"crypto/tls"
"errors" "errors"
"net" "net"
"os" "os"
@ -157,11 +158,27 @@ func handleCommonEnvVars() {
etcdEndpointsEnv, ok := os.LookupEnv("MINIO_ETCD_ENDPOINTS") etcdEndpointsEnv, ok := os.LookupEnv("MINIO_ETCD_ENDPOINTS")
if ok { if ok {
etcdEndpoints := strings.Split(etcdEndpointsEnv, ",") etcdEndpoints := strings.Split(etcdEndpointsEnv, ",")
// This is only to support client side certificate authentication
// https://coreos.com/etcd/docs/latest/op-guide/security.html
etcdClientCertFile, ok1 := os.LookupEnv("MINIO_ETCD_CLIENT_CERT")
etcdClientCertKey, ok2 := os.LookupEnv("MINIO_ETCD_CLIENT_CERT_KEY")
var getClientCertificate func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
if ok1 && ok2 {
getClientCertificate = func(unused *tls.CertificateRequestInfo) (*tls.Certificate, error) {
cert, err := tls.LoadX509KeyPair(etcdClientCertFile, etcdClientCertKey)
return &cert, err
}
}
var err error var err error
globalEtcdClient, err = etcd.New(etcd.Config{ globalEtcdClient, err = etcd.New(etcd.Config{
Endpoints: etcdEndpoints, Endpoints: etcdEndpoints,
DialTimeout: defaultDialTimeout, DialTimeout: defaultDialTimeout,
DialKeepAliveTime: defaultDialKeepAlive, DialKeepAliveTime: defaultDialKeepAlive,
TLS: &tls.Config{
RootCAs: globalRootCAs,
GetClientCertificate: getClientCertificate,
},
}) })
logger.FatalIf(err, "Unable to initialize etcd with %s", etcdEndpoints) logger.FatalIf(err, "Unable to initialize etcd with %s", etcdEndpoints)
} }

@ -134,9 +134,6 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
// Handle common command args. // Handle common command args.
handleCommonCmdArgs(ctx) handleCommonCmdArgs(ctx)
// Handle common env vars.
handleCommonEnvVars()
// Get port to listen on from gateway address // Get port to listen on from gateway address
_, gatewayPort, pErr := net.SplitHostPort(gatewayAddr) _, gatewayPort, pErr := net.SplitHostPort(gatewayAddr)
if pErr != nil { if pErr != nil {
@ -149,11 +146,6 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
// To avoid this error situation we check for port availability. // To avoid this error situation we check for port availability.
logger.FatalIf(checkPortAvailability(gatewayPort), "Unable to start the gateway") logger.FatalIf(checkPortAvailability(gatewayPort), "Unable to start the gateway")
// Validate if we have access, secret set through environment.
if !globalIsEnvCreds {
logger.Fatal(uiErrEnvCredentialsMissingGateway(nil), "Unable to start gateway")
}
// Create certs path. // Create certs path.
logger.FatalIf(createConfigDir(), "Unable to create configuration directories") logger.FatalIf(createConfigDir(), "Unable to create configuration directories")
@ -166,6 +158,14 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
globalRootCAs, err = getRootCAs(getCADir()) globalRootCAs, err = getRootCAs(getCADir())
logger.FatalIf(err, "Failed to read root CAs (%v)", err) logger.FatalIf(err, "Failed to read root CAs (%v)", err)
// Handle common env vars.
handleCommonEnvVars()
// Validate if we have access, secret set through environment.
if !globalIsEnvCreds {
logger.Fatal(uiErrEnvCredentialsMissingGateway(nil), "Unable to start gateway")
}
// Set system resources to maximum. // Set system resources to maximum.
logger.LogIf(context.Background(), setMaxResources()) logger.LogIf(context.Background(), setMaxResources())

@ -203,6 +203,9 @@ func newS3(url string) (*miniogo.Core, error) {
return nil, err return nil, err
} }
// Set custom transport
clnt.SetCustomTransport(minio.NewCustomHTTPTransport())
probeBucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "probe-bucket-sign-") probeBucketName := randString(60, rand.NewSource(time.Now().UnixNano()), "probe-bucket-sign-")
// Check if the provided keys are valid. // Check if the provided keys are valid.
if _, err = clnt.BucketExists(probeBucketName); err != nil { if _, err = clnt.BucketExists(probeBucketName); err != nil {

@ -218,12 +218,6 @@ func serverMain(ctx *cli.Context) {
logger.EnableQuiet() logger.EnableQuiet()
} }
// Handle all server command args.
serverHandleCmdArgs(ctx)
// Handle all server environment vars.
serverHandleEnvVars()
// Create certs path. // Create certs path.
logger.FatalIf(createConfigDir(), "Unable to initialize configuration files") logger.FatalIf(createConfigDir(), "Unable to initialize configuration files")
@ -236,6 +230,12 @@ func serverMain(ctx *cli.Context) {
globalRootCAs, err = getRootCAs(getCADir()) globalRootCAs, err = getRootCAs(getCADir())
logger.FatalIf(err, "Failed to read root CAs (%v)", err) logger.FatalIf(err, "Failed to read root CAs (%v)", err)
// Handle all server command args.
serverHandleCmdArgs(ctx)
// Handle all server environment vars.
serverHandleEnvVars()
// Is distributed setup, error out if no certificates are found for HTTPS endpoints. // Is distributed setup, error out if no certificates are found for HTTPS endpoints.
if globalIsDistXL { if globalIsDistXL {
if globalEndpoints.IsHTTPS() && !globalIsSSL { if globalEndpoints.IsHTTPS() && !globalIsSSL {

@ -29,6 +29,8 @@ rm -rf /tmp/etcd-data.tmp && mkdir -p /tmp/etcd-data.tmp && \
--initial-cluster-state new --initial-cluster-state new
``` ```
You may also setup etcd with TLS following this documentation [here](https://coreos.com/etcd/docs/latest/op-guide/security.html)
### 3. Setup Minio with etcd ### 3. Setup Minio with etcd
Minio server expects environment variable for etcd as `MINIO_ETCD_ENDPOINTS`, this environment variable takes many comma separated entries. Minio server expects environment variable for etcd as `MINIO_ETCD_ENDPOINTS`, this environment variable takes many comma separated entries.
``` ```
@ -36,7 +38,9 @@ export MINIO_ETCD_ENDPOINTS=localhost:2379
minio server /data minio server /data
``` ```
### 5. Test with Minio STS API NOTE: If `etcd` is configured with `Client-to-server authentication with HTTPS client certificates` then you need to use additional envs such as `MINIO_ETCD_CLIENT_CERT` pointing to path to `etcd-client.crt` and `MINIO_ETCD_CLIENT_CERT_KEY` path to `etcd-client.key` .
### 4. Test with Minio STS API
Assuming that you have configured Minio server to support STS API by following the doc [Minio STS Quickstart Guide](https://docs.minio.io/docs/minio-sts-quickstart-guide) and once you have obtained the JWT from WSO2 as mentioned in [WSO2 Quickstart Guide](https://github.com/minio/minio/blob/master/docs/sts/wso2.md). Assuming that you have configured Minio server to support STS API by following the doc [Minio STS Quickstart Guide](https://docs.minio.io/docs/minio-sts-quickstart-guide) and once you have obtained the JWT from WSO2 as mentioned in [WSO2 Quickstart Guide](https://github.com/minio/minio/blob/master/docs/sts/wso2.md).
``` ```
go run full-example.go -cid PoEgXP6uVO45IsENRngDXj5Au5Ya -csec eKsw6z8CtOJVBtrOWvhRWL4TUCga go run full-example.go -cid PoEgXP6uVO45IsENRngDXj5Au5Ya -csec eKsw6z8CtOJVBtrOWvhRWL4TUCga

Loading…
Cancel
Save