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

add support for server side s3 managed encryption #40

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -85,7 +85,8 @@ Possible JSON properties:
- `unprotected_metrics`: optional, disable HTTP basic auth protection for Prometheus metrics endpoint
- `s3.service_label`: optional, defines which service label backman will look for to find the S3-compatible object storage
- `s3.bucket_name`: optional, bucket to use on S3 storage, backman will use service-instance/binding-name if not configured
- `s3.encryption_key`: optional, defines the key which will be used to encrypt and decrypt backups as they are stored on the S3 can also be passed as an environment variable with the name `BACKMAN_ENCRYPTION_KEY`
- `s3.encryption_key`: optional, defines the key which will be used to encrypt and decrypt backups as they are stored on the S3 can also be passed as an environment variable with the name `BACKMAN_ENCRYPTION_KEY`. This is done at the client-side
- `s3.server_side_encryption`: optional, use s3 managed server side encryption (only possible value for now is "S3")
- `services.<service-instance>.schedule`: optional, defines cron schedule for running backups
- `services.<service-instance>.timeout`: optional, backman will abort a running backup/restore if timeout is exceeded
- `services.<service-instance>.retention.days`: optional, specifies how long backman will keep backups on S3 at maximum for this service instance
Expand Down
10 changes: 9 additions & 1 deletion config/config.go
Expand Up @@ -3,6 +3,7 @@ package config
import (
"encoding/json"
"errors"
"github.com/minio/minio-go/v6/pkg/encrypt"
"io/ioutil"
"log"
"os"
Expand Down Expand Up @@ -34,6 +35,7 @@ type S3Config struct {
ServiceName string `json:"service_name"`
BucketName string `json:"bucket_name"`
EncryptionKey string `json:"encryption_key"`
ServerSideEncryption string `json:"server_side_encryption"`
}

type ServiceConfig struct {
Expand Down Expand Up @@ -143,6 +145,12 @@ func Get() *Config {
if len(envConfig.S3.EncryptionKey) > 0 {
config.S3.EncryptionKey = envConfig.S3.EncryptionKey
}
if len(envConfig.S3.ServerSideEncryption) > 0 {
if envConfig.S3.ServerSideEncryption != string(encrypt.S3) {
log.Fatalln("only S3 mananged encryption(SSE-S3) is supported for now")
}
config.S3.ServerSideEncryption = envConfig.S3.ServerSideEncryption
}
for serviceName, serviceConfig := range envConfig.Services {
mergedServiceConfig := config.Services[serviceName]
if len(serviceConfig.Schedule) > 0 {
Expand Down Expand Up @@ -192,4 +200,4 @@ func Get() *Config {
}
})
return &config
}
}
12 changes: 11 additions & 1 deletion s3/objects.go
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"crypto/md5"
"encoding/hex"
"github.com/minio/minio-go/v6/pkg/encrypt"
"io"
"io/ioutil"
"sort"
Expand Down Expand Up @@ -57,7 +58,12 @@ func (s *Client) UploadWithContext(ctx context.Context, object string, reader io
}
}

n, err := s.Client.PutObjectWithContext(ctx, s.BucketName, object, uploadReader, size, minio.PutObjectOptions{ContentType: "application/gzip"})
putOptions := minio.PutObjectOptions{ContentType: "application/gzip"}
if len(config.Get().S3.ServerSideEncryption) != 0 {
putOptions.ServerSideEncryption = encrypt.NewSSE()
}

n, err := s.Client.PutObjectWithContext(ctx, s.BucketName, object, uploadReader, size, putOptions)
if err != nil {
return err
}
Expand All @@ -80,6 +86,10 @@ func (s *Client) Download(object string) (io.Reader, error) {

func (s *Client) DownloadWithContext(ctx context.Context, object string) (io.ReadCloser, error) {
log.Debugf("download S3 object [%s]", object)
getOptions := minio.GetObjectOptions{}
if len(config.Get().S3.ServerSideEncryption) != 0 {
getOptions.ServerSideEncryption = encrypt.NewSSE()
}
reader, err := s.Client.GetObjectWithContext(ctx, s.BucketName, object, minio.GetObjectOptions{})
if err != nil {
return nil, err
Expand Down