2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-23 05:12:10 +00:00

s3: forbid anonymous authentication unless explicitly requested

This commit is contained in:
Michael Eischer 2024-07-08 19:42:00 +02:00
parent 4b364940aa
commit f74e70cc36
3 changed files with 19 additions and 7 deletions

View File

@ -23,11 +23,12 @@ type Config struct {
Layout string `option:"layout" help:"use this backend layout (default: auto-detect) (deprecated)"` Layout string `option:"layout" help:"use this backend layout (default: auto-detect) (deprecated)"`
StorageClass string `option:"storage-class" help:"set S3 storage class (STANDARD, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING or REDUCED_REDUNDANCY)"` StorageClass string `option:"storage-class" help:"set S3 storage class (STANDARD, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING or REDUCED_REDUNDANCY)"`
Connections uint `option:"connections" help:"set a limit for the number of concurrent connections (default: 5)"` Connections uint `option:"connections" help:"set a limit for the number of concurrent connections (default: 5)"`
MaxRetries uint `option:"retries" help:"set the number of retries attempted"` MaxRetries uint `option:"retries" help:"set the number of retries attempted"`
Region string `option:"region" help:"set region"` Region string `option:"region" help:"set region"`
BucketLookup string `option:"bucket-lookup" help:"bucket lookup style: 'auto', 'dns', or 'path'"` BucketLookup string `option:"bucket-lookup" help:"bucket lookup style: 'auto', 'dns', or 'path'"`
ListObjectsV1 bool `option:"list-objects-v1" help:"use deprecated V1 api for ListObjects calls"` ListObjectsV1 bool `option:"list-objects-v1" help:"use deprecated V1 api for ListObjects calls"`
UnsafeAnonymousAuth bool `option:"unsafe-anonymous-auth" help:"use anonymous authentication"`
} }
// NewConfig returns a new Config with the default values filled in. // NewConfig returns a new Config with the default values filled in.

View File

@ -98,6 +98,10 @@ func open(ctx context.Context, cfg Config, rt http.RoundTripper) (*Backend, erro
// getCredentials -- runs through the various credential types and returns the first one that works. // getCredentials -- runs through the various credential types and returns the first one that works.
// additionally if the user has specified a role to assume, it will do that as well. // additionally if the user has specified a role to assume, it will do that as well.
func getCredentials(cfg Config, tr http.RoundTripper) (*credentials.Credentials, error) { func getCredentials(cfg Config, tr http.RoundTripper) (*credentials.Credentials, error) {
if cfg.UnsafeAnonymousAuth {
return credentials.New(&credentials.Static{}), nil
}
// Chains all credential types, in the following order: // Chains all credential types, in the following order:
// - Static credentials provided by user // - Static credentials provided by user
// - AWS env vars (i.e. AWS_ACCESS_KEY_ID) // - AWS env vars (i.e. AWS_ACCESS_KEY_ID)
@ -131,9 +135,14 @@ func getCredentials(cfg Config, tr http.RoundTripper) (*credentials.Credentials,
} }
if c.SignerType == credentials.SignatureAnonymous { if c.SignerType == credentials.SignatureAnonymous {
// Fail if no credentials were found to prevent repeated attempts to (unsuccessfully) retrieve new credentials.
// The first attempt still has to timeout which slows down restic usage considerably. Thus, migrate towards forcing
// users to explicitly decide between authenticated and anonymous access.
if feature.Flag.Enabled(feature.ExplicitS3AnonymousAuth) {
return nil, fmt.Errorf("no credentials found. Use `-o s3.unsafe-anonymous-auth=true` for anonymous authentication")
}
debug.Log("using anonymous access for %#v", cfg.Endpoint) debug.Log("using anonymous access for %#v", cfg.Endpoint)
// short circuit credentials resolution when using anonymous access
// otherwise the IAM provider would continuously try to (unsuccessfully) retrieve new credentials
creds = credentials.New(&credentials.Static{}) creds = credentials.New(&credentials.Static{})
} }

View File

@ -9,6 +9,7 @@ const (
DeprecateLegacyIndex FlagName = "deprecate-legacy-index" DeprecateLegacyIndex FlagName = "deprecate-legacy-index"
DeprecateS3LegacyLayout FlagName = "deprecate-s3-legacy-layout" DeprecateS3LegacyLayout FlagName = "deprecate-s3-legacy-layout"
DeviceIDForHardlinks FlagName = "device-id-for-hardlinks" DeviceIDForHardlinks FlagName = "device-id-for-hardlinks"
ExplicitS3AnonymousAuth FlagName = "explicit-s3-anonymous-auth"
SafeForgetKeepTags FlagName = "safe-forget-keep-tags" SafeForgetKeepTags FlagName = "safe-forget-keep-tags"
) )
@ -18,6 +19,7 @@ func init() {
DeprecateLegacyIndex: {Type: Beta, Description: "disable support for index format used by restic 0.1.0. Use `restic repair index` to update the index if necessary."}, DeprecateLegacyIndex: {Type: Beta, Description: "disable support for index format used by restic 0.1.0. Use `restic repair index` to update the index if necessary."},
DeprecateS3LegacyLayout: {Type: Beta, Description: "disable support for S3 legacy layout used up to restic 0.7.0. Use `RESTIC_FEATURES=deprecate-s3-legacy-layout=false restic migrate s3_layout` to migrate your S3 repository if necessary."}, DeprecateS3LegacyLayout: {Type: Beta, Description: "disable support for S3 legacy layout used up to restic 0.7.0. Use `RESTIC_FEATURES=deprecate-s3-legacy-layout=false restic migrate s3_layout` to migrate your S3 repository if necessary."},
DeviceIDForHardlinks: {Type: Alpha, Description: "store deviceID only for hardlinks to reduce metadata changes for example when using btrfs subvolumes. Will be removed in a future restic version after repository format 3 is available"}, DeviceIDForHardlinks: {Type: Alpha, Description: "store deviceID only for hardlinks to reduce metadata changes for example when using btrfs subvolumes. Will be removed in a future restic version after repository format 3 is available"},
ExplicitS3AnonymousAuth: {Type: Beta, Description: "forbid anonymous S3 authentication unless `-o s3.unsafe-anonymous-auth=true` is set"},
SafeForgetKeepTags: {Type: Beta, Description: "prevent deleting all snapshots if the tag passed to `forget --keep-tags tagname` does not exist"}, SafeForgetKeepTags: {Type: Beta, Description: "prevent deleting all snapshots if the tag passed to `forget --keep-tags tagname` does not exist"},
}) })
} }