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
This commit is contained in:
Harshavardhana 2018-10-29 11:14:12 -07:00 committed by kannappanr
parent 7e879a45d5
commit 9fe51e392b
5 changed files with 39 additions and 15 deletions

View File

@ -17,6 +17,7 @@
package cmd
import (
"crypto/tls"
"errors"
"net"
"os"
@ -157,11 +158,27 @@ func handleCommonEnvVars() {
etcdEndpointsEnv, ok := os.LookupEnv("MINIO_ETCD_ENDPOINTS")
if ok {
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
globalEtcdClient, err = etcd.New(etcd.Config{
Endpoints: etcdEndpoints,
DialTimeout: defaultDialTimeout,
DialKeepAliveTime: defaultDialKeepAlive,
TLS: &tls.Config{
RootCAs: globalRootCAs,
GetClientCertificate: getClientCertificate,
},
})
logger.FatalIf(err, "Unable to initialize etcd with %s", etcdEndpoints)
}

View File

@ -134,9 +134,6 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
// Handle common command args.
handleCommonCmdArgs(ctx)
// Handle common env vars.
handleCommonEnvVars()
// Get port to listen on from gateway address
_, gatewayPort, pErr := net.SplitHostPort(gatewayAddr)
if pErr != nil {
@ -149,11 +146,6 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
// To avoid this error situation we check for port availability.
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.
logger.FatalIf(createConfigDir(), "Unable to create configuration directories")
@ -166,6 +158,14 @@ func StartGateway(ctx *cli.Context, gw Gateway) {
globalRootCAs, err = getRootCAs(getCADir())
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.
logger.LogIf(context.Background(), setMaxResources())

View File

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

View File

@ -218,12 +218,6 @@ func serverMain(ctx *cli.Context) {
logger.EnableQuiet()
}
// Handle all server command args.
serverHandleCmdArgs(ctx)
// Handle all server environment vars.
serverHandleEnvVars()
// Create certs path.
logger.FatalIf(createConfigDir(), "Unable to initialize configuration files")
@ -236,6 +230,12 @@ func serverMain(ctx *cli.Context) {
globalRootCAs, err = getRootCAs(getCADir())
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.
if globalIsDistXL {
if globalEndpoints.IsHTTPS() && !globalIsSSL {

View File

@ -29,6 +29,8 @@ rm -rf /tmp/etcd-data.tmp && mkdir -p /tmp/etcd-data.tmp && \
--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
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
```
### 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).
```
go run full-example.go -cid PoEgXP6uVO45IsENRngDXj5Au5Ya -csec eKsw6z8CtOJVBtrOWvhRWL4TUCga