diff --git a/CHANGELOG.md b/CHANGELOG.md index b6e9c29811b..c04533ec77f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ * [ENHANCEMENT] Compactor: added a config validation check to fail fast if the compactor has been configured invalid block range periods (each period is expected to be a multiple of the previous one). #3534 * [ENHANCEMENT] Blocks storage: concurrently fetch deletion marks from object storage. #3538 * [ENHANCEMENT] Blocks storage ingester: ingester can now close idle TSDB and delete local data. #3491 +* [ENHANCEMENT] Blocks storage: add option to use V2 signatures for S3 authentication. #3540 * [BUGFIX] Blocks storage ingester: fixed some cases leading to a TSDB WAL corruption after a partial write to disk. #3423 * [BUGFIX] Blocks storage: Fix the race between ingestion and `/flush` call resulting in overlapping blocks. #3422 * [BUGFIX] Querier: fixed `-querier.max-query-into-future` which wasn't correctly enforced on range queries. #3452 diff --git a/docs/blocks-storage/querier.md b/docs/blocks-storage/querier.md index 783913e65fc..1016351971c 100644 --- a/docs/blocks-storage/querier.md +++ b/docs/blocks-storage/querier.md @@ -225,6 +225,11 @@ blocks_storage: # CLI flag: -blocks-storage.s3.insecure [insecure: | default = false] + # The signature version to use for authenticating against S3. Supported + # values are: v4, v2. + # CLI flag: -blocks-storage.s3.signature-version + [signature_version: | default = "v4"] + http: # The time an idle connection will remain idle before closing. # CLI flag: -blocks-storage.s3.http.idle-conn-timeout diff --git a/docs/blocks-storage/store-gateway.md b/docs/blocks-storage/store-gateway.md index b9e13da4875..7b5e3814cf3 100644 --- a/docs/blocks-storage/store-gateway.md +++ b/docs/blocks-storage/store-gateway.md @@ -275,6 +275,11 @@ blocks_storage: # CLI flag: -blocks-storage.s3.insecure [insecure: | default = false] + # The signature version to use for authenticating against S3. Supported + # values are: v4, v2. + # CLI flag: -blocks-storage.s3.signature-version + [signature_version: | default = "v4"] + http: # The time an idle connection will remain idle before closing. # CLI flag: -blocks-storage.s3.http.idle-conn-timeout diff --git a/docs/configuration/config-file-reference.md b/docs/configuration/config-file-reference.md index f7f3cc2cad6..8e1e4e79ab7 100644 --- a/docs/configuration/config-file-reference.md +++ b/docs/configuration/config-file-reference.md @@ -3429,6 +3429,11 @@ s3: # CLI flag: -blocks-storage.s3.insecure [insecure: | default = false] + # The signature version to use for authenticating against S3. Supported values + # are: v4, v2. + # CLI flag: -blocks-storage.s3.signature-version + [signature_version: | default = "v4"] + http: # The time an idle connection will remain idle before closing. # CLI flag: -blocks-storage.s3.http.idle-conn-timeout diff --git a/go.mod b/go.mod index b6ef43c9dd6..9e7f8dd8aa6 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,7 @@ require ( github.com/sony/gobreaker v0.4.1 github.com/spf13/afero v1.2.2 github.com/stretchr/testify v1.6.1 - github.com/thanos-io/thanos v0.13.1-0.20201125083044-ca8be00eaf6e + github.com/thanos-io/thanos v0.13.1-0.20201125124348-2008ef009e88 github.com/uber/jaeger-client-go v2.25.0+incompatible github.com/weaveworks/common v0.0.0-20201119133501-0619918236ec go.etcd.io/bbolt v1.3.5-0.20200615073812-232d8fc87f50 diff --git a/go.sum b/go.sum index 9c17b0f249f..77419695494 100644 --- a/go.sum +++ b/go.sum @@ -1146,8 +1146,8 @@ github.com/thanos-io/thanos v0.13.1-0.20200807203500-9b578afb4763/go.mod h1:KyW0 github.com/thanos-io/thanos v0.13.1-0.20201019130456-f41940581d9a/go.mod h1:A3qUEEbsVkplJnxyDLwuIuvTDaJPByTH+hMdTl9ujAA= github.com/thanos-io/thanos v0.13.1-0.20201030101306-47f9a225cc52 h1:z3hglXVwJ4HgU0OoDS+8+MvEipv/U83IQ+fMsDr00YQ= github.com/thanos-io/thanos v0.13.1-0.20201030101306-47f9a225cc52/go.mod h1:OqqX4x21cg5N5MMHd/yGQAc/V3wg8a7Do4Jk8HfaFZQ= -github.com/thanos-io/thanos v0.13.1-0.20201125083044-ca8be00eaf6e h1:cf/9Osa+ledD0KrP+STooekIFgIp+XUx7tl14jXYni8= -github.com/thanos-io/thanos v0.13.1-0.20201125083044-ca8be00eaf6e/go.mod h1:ffr9z+gefM664JBH/CEMHyHvShq2BQTejT/Ws+V+80Q= +github.com/thanos-io/thanos v0.13.1-0.20201125124348-2008ef009e88 h1:r3lyiYA58zA6yE4CqE0ncavgI2rHgyhLQom5z0usbNM= +github.com/thanos-io/thanos v0.13.1-0.20201125124348-2008ef009e88/go.mod h1:ffr9z+gefM664JBH/CEMHyHvShq2BQTejT/Ws+V+80Q= github.com/themihai/gomemcache v0.0.0-20180902122335-24332e2d58ab h1:7ZR3hmisBWw77ZpO1/o86g+JV3VKlk3d48jopJxzTjU= github.com/themihai/gomemcache v0.0.0-20180902122335-24332e2d58ab/go.mod h1:eheTFp954zcWZXCU8d0AT76ftsQOTo4DTqkN/h3k1MY= github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= diff --git a/pkg/storage/backend/s3/bucket_client.go b/pkg/storage/backend/s3/bucket_client.go index 5d3d7348857..51dab86036f 100644 --- a/pkg/storage/backend/s3/bucket_client.go +++ b/pkg/storage/backend/s3/bucket_client.go @@ -30,5 +30,7 @@ func newS3Config(cfg Config) s3.Config { InsecureSkipVerify: cfg.HTTP.InsecureSkipVerify, Transport: cfg.HTTP.Transport, }, + // Enforce signature version 2 if CLI flag is set + SignatureV2: cfg.SignatureVersion == SignatureVersionV2, } } diff --git a/pkg/storage/backend/s3/config.go b/pkg/storage/backend/s3/config.go index f4e9874708b..a89be513500 100644 --- a/pkg/storage/backend/s3/config.go +++ b/pkg/storage/backend/s3/config.go @@ -1,13 +1,27 @@ package s3 import ( + "errors" "flag" + "fmt" "net/http" + "strings" "time" + "github.com/cortexproject/cortex/pkg/util" "github.com/cortexproject/cortex/pkg/util/flagext" ) +const ( + SignatureVersionV4 = "v4" + SignatureVersionV2 = "v2" +) + +var ( + supportedSignatureVersions = []string{SignatureVersionV4, SignatureVersionV2} + errUnsupportedSignatureVersion = errors.New("unsupported signature version") +) + // HTTPConfig stores the http.Transport configuration for the s3 minio client. type HTTPConfig struct { IdleConnTimeout time.Duration `yaml:"idle_conn_timeout"` @@ -27,11 +41,12 @@ func (cfg *HTTPConfig) RegisterFlagsWithPrefix(prefix string, f *flag.FlagSet) { // Config holds the config options for an S3 backend type Config struct { - Endpoint string `yaml:"endpoint"` - BucketName string `yaml:"bucket_name"` - SecretAccessKey flagext.Secret `yaml:"secret_access_key"` - AccessKeyID string `yaml:"access_key_id"` - Insecure bool `yaml:"insecure"` + Endpoint string `yaml:"endpoint"` + BucketName string `yaml:"bucket_name"` + SecretAccessKey flagext.Secret `yaml:"secret_access_key"` + AccessKeyID string `yaml:"access_key_id"` + Insecure bool `yaml:"insecure"` + SignatureVersion string `yaml:"signature_version"` HTTP HTTPConfig `yaml:"http"` } @@ -48,5 +63,14 @@ func (cfg *Config) RegisterFlagsWithPrefix(prefix string, f *flag.FlagSet) { f.StringVar(&cfg.BucketName, prefix+"s3.bucket-name", "", "S3 bucket name") f.StringVar(&cfg.Endpoint, prefix+"s3.endpoint", "", "The S3 bucket endpoint. It could be an AWS S3 endpoint listed at https://docs.aws.amazon.com/general/latest/gr/s3.html or the address of an S3-compatible service in hostname:port format.") f.BoolVar(&cfg.Insecure, prefix+"s3.insecure", false, "If enabled, use http:// for the S3 endpoint instead of https://. This could be useful in local dev/test environments while using an S3-compatible backend storage, like Minio.") + f.StringVar(&cfg.SignatureVersion, prefix+"s3.signature-version", SignatureVersionV4, fmt.Sprintf("The signature version to use for authenticating against S3. Supported values are: %s.", strings.Join(supportedSignatureVersions, ", "))) cfg.HTTP.RegisterFlagsWithPrefix(prefix, f) } + +// Validate config and returns error on failure +func (cfg *Config) Validate() error { + if !util.StringsContain(supportedSignatureVersions, cfg.SignatureVersion) { + return errUnsupportedSignatureVersion + } + return nil +} diff --git a/pkg/storage/tsdb/config.go b/pkg/storage/tsdb/config.go index 9fedf30cb94..1d8c973e024 100644 --- a/pkg/storage/tsdb/config.go +++ b/pkg/storage/tsdb/config.go @@ -151,6 +151,12 @@ func (cfg *BucketConfig) Validate() error { return errUnsupportedStorageBackend } + if cfg.Backend == BackendS3 { + if err := cfg.S3.Validate(); err != nil { + return err + } + } + return nil } diff --git a/vendor/github.com/thanos-io/thanos/pkg/objstore/s3/s3.go b/vendor/github.com/thanos-io/thanos/pkg/objstore/s3/s3.go index cf087f5ae8d..eb679679805 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/objstore/s3/s3.go +++ b/vendor/github.com/thanos-io/thanos/pkg/objstore/s3/s3.go @@ -161,36 +161,54 @@ func NewBucket(logger log.Logger, conf []byte, component string) (*Bucket, error return NewBucketWithConfig(logger, config, component) } +type overrideSignerType struct { + credentials.Provider + signerType credentials.SignatureType +} + +func (s *overrideSignerType) Retrieve() (credentials.Value, error) { + v, err := s.Provider.Retrieve() + if err != nil { + return v, err + } + if !v.SignerType.IsAnonymous() { + v.SignerType = s.signerType + } + return v, nil +} + // NewBucketWithConfig returns a new Bucket using the provided s3 config values. func NewBucketWithConfig(logger log.Logger, config Config, component string) (*Bucket, error) { var chain []credentials.Provider + // TODO(bwplotka): Don't do flags as they won't scale, use actual params like v2, v4 instead + wrapCredentialsProvider := func(p credentials.Provider) credentials.Provider { return p } + if config.SignatureV2 { + wrapCredentialsProvider = func(p credentials.Provider) credentials.Provider { + return &overrideSignerType{Provider: p, signerType: credentials.SignatureV2} + } + } + if err := validate(config); err != nil { return nil, err } if config.AccessKey != "" { - signature := credentials.SignatureV4 - // TODO(bwplotka): Don't do flags, use actual v2, v4 params. - if config.SignatureV2 { - signature = credentials.SignatureV2 - } - - chain = []credentials.Provider{&credentials.Static{ + chain = []credentials.Provider{wrapCredentialsProvider(&credentials.Static{ Value: credentials.Value{ AccessKeyID: config.AccessKey, SecretAccessKey: config.SecretKey, - SignerType: signature, + SignerType: credentials.SignatureV4, }, - }} + })} } else { chain = []credentials.Provider{ - &credentials.EnvAWS{}, - &credentials.FileAWSCredentials{}, - &credentials.IAM{ + wrapCredentialsProvider(&credentials.EnvAWS{}), + wrapCredentialsProvider(&credentials.FileAWSCredentials{}), + wrapCredentialsProvider(&credentials.IAM{ Client: &http.Client{ Transport: http.DefaultTransport, }, - }, + }), } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 4030f048322..d64807aab8a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -566,7 +566,7 @@ github.com/stretchr/objx github.com/stretchr/testify/assert github.com/stretchr/testify/mock github.com/stretchr/testify/require -# github.com/thanos-io/thanos v0.13.1-0.20201125083044-ca8be00eaf6e +# github.com/thanos-io/thanos v0.13.1-0.20201125124348-2008ef009e88 ## explicit github.com/thanos-io/thanos/pkg/block github.com/thanos-io/thanos/pkg/block/indexheader