mirror of
https://github.com/minio/minio.git
synced 2024-12-24 22:25:54 -05:00
Disable federated buckets when etcd is namespaced (#8709)
This is to ensure that when we have multiple tenants deployed all sharing the same etcd for global bucket should avoid listing each others buckets, this leads to information leak which should be avoided unless etcd is not namespaced for IAM assets in which case it can be assumed that its a federated setup. Federated setup and namespaced IAM assets on etcd is not supported since namespacing is only useful when you wish to separate the tenants as isolated instances of MinIO. This PR allows a new type of behavior, primarily driven by the usecase of m3(mkube) multi-tenant deployments with global bucket support.
This commit is contained in:
parent
5d09233115
commit
669c9da85d
@ -278,7 +278,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R
|
|||||||
|
|
||||||
// If etcd, dns federation configured list buckets from etcd.
|
// If etcd, dns federation configured list buckets from etcd.
|
||||||
var bucketsInfo []BucketInfo
|
var bucketsInfo []BucketInfo
|
||||||
if globalDNSConfig != nil {
|
if globalDNSConfig != nil && globalBucketFederation {
|
||||||
dnsBuckets, err := globalDNSConfig.List()
|
dnsBuckets, err := globalDNSConfig.List()
|
||||||
if err != nil && err != dns.ErrNoEntriesFound {
|
if err != nil && err != dns.ErrNoEntriesFound {
|
||||||
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
|
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
|
@ -315,6 +315,13 @@ func lookupConfigs(s config.Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bucket federation is 'true' only when IAM assets are not namespaced
|
||||||
|
// per tenant and all tenants interested in globally available users
|
||||||
|
// if namespace was requested such as specifying etcdPathPrefix then
|
||||||
|
// we assume that users are interested in global bucket support
|
||||||
|
// but not federation.
|
||||||
|
globalBucketFederation = etcdCfg.PathPrefix == "" && etcdCfg.Enabled
|
||||||
|
|
||||||
if len(globalDomainNames) != 0 && !globalDomainIPs.IsEmpty() && globalEtcdClient != nil {
|
if len(globalDomainNames) != 0 && !globalDomainIPs.IsEmpty() && globalEtcdClient != nil {
|
||||||
globalDNSConfig, err = dns.NewCoreDNS(etcdCfg.Config,
|
globalDNSConfig, err = dns.NewCoreDNS(etcdCfg.Config,
|
||||||
dns.DomainNames(globalDomainNames),
|
dns.DomainNames(globalDomainNames),
|
||||||
|
@ -619,7 +619,8 @@ type bucketForwardingHandler struct {
|
|||||||
func (f bucketForwardingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (f bucketForwardingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
if globalDNSConfig == nil || len(globalDomainNames) == 0 ||
|
if globalDNSConfig == nil || len(globalDomainNames) == 0 ||
|
||||||
guessIsHealthCheckReq(r) || guessIsMetricsReq(r) ||
|
guessIsHealthCheckReq(r) || guessIsMetricsReq(r) ||
|
||||||
guessIsRPCReq(r) || guessIsLoginSTSReq(r) || isAdminReq(r) {
|
guessIsRPCReq(r) || guessIsLoginSTSReq(r) || isAdminReq(r) ||
|
||||||
|
!globalBucketFederation {
|
||||||
f.handler.ServeHTTP(w, r)
|
f.handler.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -212,6 +212,10 @@ var (
|
|||||||
// Allocated etcd endpoint for config and bucket DNS.
|
// Allocated etcd endpoint for config and bucket DNS.
|
||||||
globalEtcdClient *etcd.Client
|
globalEtcdClient *etcd.Client
|
||||||
|
|
||||||
|
// Is set to true when Bucket federation is requested
|
||||||
|
// and is 'true' when etcdConfig.PathPrefix is empty
|
||||||
|
globalBucketFederation bool
|
||||||
|
|
||||||
// Allocated DNS config wrapper over etcd client.
|
// Allocated DNS config wrapper over etcd client.
|
||||||
globalDNSConfig *dns.CoreDNS
|
globalDNSConfig *dns.CoreDNS
|
||||||
|
|
||||||
|
@ -640,8 +640,11 @@ func isRemoteCallRequired(ctx context.Context, bucket string, objAPI ObjectLayer
|
|||||||
if globalDNSConfig == nil {
|
if globalDNSConfig == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
_, err := objAPI.GetBucketInfo(ctx, bucket)
|
if globalBucketFederation {
|
||||||
return err == toObjectErr(errVolumeNotFound, bucket)
|
_, err := objAPI.GetBucketInfo(ctx, bucket)
|
||||||
|
return err == toObjectErr(errVolumeNotFound, bucket)
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// CopyObjectHandler - Copy Object
|
// CopyObjectHandler - Copy Object
|
||||||
@ -2421,6 +2424,7 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.
|
|||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(err), r.URL, guessIsBrowserReq(r))
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if globalDNSConfig != nil {
|
if globalDNSConfig != nil {
|
||||||
_, err := globalDNSConfig.Get(bucket)
|
_, err := globalDNSConfig.Get(bucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -258,10 +258,6 @@ func (web *webAPIHandlers) DeleteBucket(r *http.Request, args *RemoveBucketArgs,
|
|||||||
return toJSONError(ctx, err, args.BucketName)
|
return toJSONError(ctx, err, args.BucketName)
|
||||||
}
|
}
|
||||||
|
|
||||||
globalNotificationSys.RemoveNotification(args.BucketName)
|
|
||||||
globalPolicySys.Remove(args.BucketName)
|
|
||||||
globalNotificationSys.DeleteBucket(ctx, args.BucketName)
|
|
||||||
|
|
||||||
if globalDNSConfig != nil {
|
if globalDNSConfig != nil {
|
||||||
if err := globalDNSConfig.Delete(args.BucketName); err != nil {
|
if err := globalDNSConfig.Delete(args.BucketName); err != nil {
|
||||||
// Deleting DNS entry failed, attempt to create the bucket again.
|
// Deleting DNS entry failed, attempt to create the bucket again.
|
||||||
@ -270,6 +266,8 @@ func (web *webAPIHandlers) DeleteBucket(r *http.Request, args *RemoveBucketArgs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
globalNotificationSys.DeleteBucket(ctx, args.BucketName)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +137,38 @@ MINIO_CACHE_EXCLUDE (csv) comma separated wildcard exclusion patterns e.g
|
|||||||
MINIO_CACHE_COMMENT (sentence) optionally add a comment to this setting
|
MINIO_CACHE_COMMENT (sentence) optionally add a comment to this setting
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Etcd
|
||||||
|
MinIO supports storing encrypted IAM assets and bucket DNS records on etcd.
|
||||||
|
|
||||||
|
> NOTE: if *path_prefix* is set then MinIO will not federate your buckets, namespaced IAM assets are assumed as isolated tenants, only buckets are considered globally unique but performing a lookup with a *bucket* which belongs to a different tenant will fail unlike federated setups where MinIO would port-forward and route the request to relevant cluster accordingly. This is a special feature, federated deployments should not need to set *path_prefix*.
|
||||||
|
|
||||||
|
```
|
||||||
|
KEY:
|
||||||
|
etcd federate multiple clusters for IAM and Bucket DNS
|
||||||
|
|
||||||
|
ARGS:
|
||||||
|
endpoints* (csv) comma separated list of etcd endpoints e.g. "http://localhost:2379"
|
||||||
|
path_prefix (path) namespace prefix to isolate tenants e.g. "customer1/"
|
||||||
|
coredns_path (path) shared bucket DNS records, default is "/skydns"
|
||||||
|
client_cert (path) client cert for mTLS authentication
|
||||||
|
client_cert_key (path) client cert key for mTLS authentication
|
||||||
|
comment (sentence) optionally add a comment to this setting
|
||||||
|
```
|
||||||
|
|
||||||
|
or environment variables
|
||||||
|
```
|
||||||
|
KEY:
|
||||||
|
etcd federate multiple clusters for IAM and Bucket DNS
|
||||||
|
|
||||||
|
ARGS:
|
||||||
|
MINIO_ETCD_ENDPOINTS* (csv) comma separated list of etcd endpoints e.g. "http://localhost:2379"
|
||||||
|
MINIO_ETCD_PATH_PREFIX (path) namespace prefix to isolate tenants e.g. "customer1/"
|
||||||
|
MINIO_ETCD_COREDNS_PATH (path) shared bucket DNS records, default is "/skydns"
|
||||||
|
MINIO_ETCD_CLIENT_CERT (path) client cert for mTLS authentication
|
||||||
|
MINIO_ETCD_CLIENT_CERT_KEY (path) client cert key for mTLS authentication
|
||||||
|
MINIO_ETCD_COMMENT (sentence) optionally add a comment to this setting
|
||||||
|
```
|
||||||
|
|
||||||
#### Notifications
|
#### Notifications
|
||||||
Notification targets supported by MinIO are in the following list. To configure individual targets please refer to more detailed documentation [here](https://docs.min.io/docs/minio-bucket-notification-guide.html)
|
Notification targets supported by MinIO are in the following list. To configure individual targets please refer to more detailed documentation [here](https://docs.min.io/docs/minio-bucket-notification-guide.html)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user