Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds SSE-KMS and SSE-C config to S3 Objstore #3064

Merged
merged 13 commits into from
Aug 25, 2020
Next Next commit
Adds SSE config to S3 Objstore
Signed-off-by: James Bach <[email protected]>
jalev committed Aug 23, 2020

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 70ac68a82f539812e01bc8e03314981f25ba093c
40 changes: 36 additions & 4 deletions pkg/objstore/s3/s3.go
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ import (
"crypto/tls"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"os"
@@ -53,13 +54,22 @@ type Config struct {
AccessKey string `yaml:"access_key"`
Insecure bool `yaml:"insecure"`
SignatureV2 bool `yaml:"signature_version2"`
SSEEncryption bool `yaml:"encrypt_sse"`
SecretKey string `yaml:"secret_key"`
PutUserMetadata map[string]string `yaml:"put_user_metadata"`
HTTPConfig HTTPConfig `yaml:"http_config"`
TraceConfig TraceConfig `yaml:"trace"`
// PartSize used for multipart upload. Only used if uploaded object size is known and larger than configured PartSize.
PartSize uint64 `yaml:"part_size"`
PartSize uint64 `yaml:"part_size"`
SSEConfig SSEConfig `yaml:"sse_config"`
}

// SSEConfig deals with the configuration of SSE for Minio. The following options are valid:
// kmsencryptioncontext == https://docs.aws.amazon.com/kms/latest/developerguide/services-s3.html#s3-encryption-context
type SSEConfig struct {
Enable bool `yaml:"enabled"`
KMSKeyID string `yaml:"kms_key_id"`
KMSEncryptionContext map[string]string `yaml:"kms_encryption_context"`
EncryptionKey string `yaml:"encryption_key"`
}

type TraceConfig struct {
@@ -173,8 +183,26 @@ func NewBucketWithConfig(logger log.Logger, config Config, component string) (*B
client.SetAppInfo(fmt.Sprintf("thanos-%s", component), fmt.Sprintf("%s (%s)", version.Version, runtime.Version()))

var sse encrypt.ServerSide
if config.SSEEncryption {
sse = encrypt.NewSSE()
if config.SSEConfig.Enable {
switch {
case config.SSEConfig.KMSKeyID != "":
sse, err = encrypt.NewSSEKMS(config.SSEConfig.KMSKeyID, config.SSEConfig.KMSEncryptionContext)
if err != nil {
return nil, errors.Wrap(err, "initialize s3 client SSE-KMS")
}
case config.SSEConfig.EncryptionKey != "":
key, err := ioutil.ReadFile(config.SSEConfig.EncryptionKey)
if err != nil {
return nil, err
}

sse, err = encrypt.NewSSEC(key)
if err != nil {
return nil, errors.Wrap(err, "initialize s3 client SSE-C")
}
default:
sse = encrypt.NewSSE()
}
}

if config.TraceConfig.Enable {
@@ -211,6 +239,10 @@ func validate(conf Config) error {
if conf.AccessKey != "" && conf.SecretKey == "" {
return errors.New("no s3 secret_key specified while access_key is present in config file; either both should be present in config or envvars/IAM should be used.")
}

if conf.SSEConfig.EncryptionKey != "" && conf.SSEConfig.KMSKeyID != "" {
return errors.New("sse_encryption_key AND sse_kms_key_id set in sse_config. You can set one or the other, but NOT both.")
}
return nil
}

12 changes: 12 additions & 0 deletions pkg/objstore/s3/s3_test.go
Original file line number Diff line number Diff line change
@@ -24,6 +24,18 @@ insecure: false`)
}
}

func TestParseConfig_SSEConfig(t *testing.T) {
input := []byte(`sse_config:
enabled: true`)

cfg, err := parseConfig(input)
testutil.Ok(t, err)

if !cfg.SSEConfig.Enable {
t.Errorf("parsing of sse_config failed: got %v, expected %v", cfg.SSEConfig.Enable, true)
}
}

func TestParseConfig_DefaultHTTPConfig(t *testing.T) {
input := []byte(`bucket: abcd
insecure: false`)