mirror of
https://github.com/rclone/rclone.git
synced 2025-02-18 11:31:19 +01:00
Add IAM role and Env credentials
This will make the s3 provider authentaction logic - Configured credentials if both key and secret available - Anonymous if key and secret missing and env_auth not set - if env_auth is set to truthy (https://golang.org/pkg/strconv/#ParseBool) - AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY environment variables - IAM role credentials as fallback
This commit is contained in:
parent
6a47d966a4
commit
ce05ef7110
@ -24,17 +24,29 @@ n/q> n
|
|||||||
name> remote
|
name> remote
|
||||||
What type of source is it?
|
What type of source is it?
|
||||||
Choose a number from below
|
Choose a number from below
|
||||||
1) swift
|
1) amazon cloud drive
|
||||||
2) s3
|
2) b2
|
||||||
3) local
|
3) drive
|
||||||
4) google cloud storage
|
4) dropbox
|
||||||
5) dropbox
|
5) google cloud storage
|
||||||
6) drive
|
6) swift
|
||||||
type> 2
|
7) hubic
|
||||||
AWS Access Key ID.
|
8) local
|
||||||
access_key_id> accesskey
|
9) onedrive
|
||||||
AWS Secret Access Key (password).
|
10) s3
|
||||||
secret_access_key> secretaccesskey
|
11) yandex
|
||||||
|
type> 10
|
||||||
|
Get AWS credentials from runtime (environment variables or EC2 meta data if no env vars). Only applies if access_key_id and secret_access_key is blank.
|
||||||
|
Choose a number from below, or type in your own value
|
||||||
|
* Enter AWS credentials in the next step
|
||||||
|
1) false
|
||||||
|
* Get AWS credentials from the environment (env vars or IAM)
|
||||||
|
2) true
|
||||||
|
env_auth> 2
|
||||||
|
AWS Access Key ID - leave blank for anonymous access or runtime credentials.
|
||||||
|
access_key_id>
|
||||||
|
AWS Secret Access Key (password) - leave blank for anonymous access or runtime credentials.
|
||||||
|
secret_access_key>
|
||||||
Region to connect to.
|
Region to connect to.
|
||||||
Choose a number from below, or type in your own value
|
Choose a number from below, or type in your own value
|
||||||
* The default endpoint - a good choice if you are unsure.
|
* The default endpoint - a good choice if you are unsure.
|
||||||
@ -44,7 +56,10 @@ Choose a number from below, or type in your own value
|
|||||||
* US West (Oregon) Region
|
* US West (Oregon) Region
|
||||||
* Needs location constraint us-west-2.
|
* Needs location constraint us-west-2.
|
||||||
2) us-west-2
|
2) us-west-2
|
||||||
[snip]
|
* US West (Northern California) Region
|
||||||
|
* Needs location constraint us-west-1.
|
||||||
|
[..snip..]
|
||||||
|
8) ap-northeast-1
|
||||||
* South America (Sao Paulo) Region
|
* South America (Sao Paulo) Region
|
||||||
* Needs location constraint sa-east-1.
|
* Needs location constraint sa-east-1.
|
||||||
9) sa-east-1
|
9) sa-east-1
|
||||||
@ -52,31 +67,32 @@ Choose a number from below, or type in your own value
|
|||||||
10) other-v2-signature
|
10) other-v2-signature
|
||||||
* If using an S3 clone that understands v4 signatures set this and make sure you set the endpoint.
|
* If using an S3 clone that understands v4 signatures set this and make sure you set the endpoint.
|
||||||
11) other-v4-signature
|
11) other-v4-signature
|
||||||
region> 1
|
region> 3
|
||||||
Endpoint for S3 API.
|
Endpoint for S3 API.
|
||||||
Leave blank if using AWS to use the default endpoint for the region.
|
Leave blank if using AWS to use the default endpoint for the region.
|
||||||
Specify if using an S3 clone such as Ceph.
|
Specify if using an S3 clone such as Ceph.
|
||||||
endpoint>
|
endpoint>
|
||||||
Location constraint - must be set to match the Region. Used when creating buckets only.
|
Location constraint - must be set to match the Region. Used when creating buckets only.
|
||||||
Choose a number from below, or type in your own value
|
Choose a number from below, or type in your own value
|
||||||
* Empty for US Region, Northern Virginia or Pacific Northwest.
|
* Empty for US Region, Northern Virginia or Pacific Northwest.
|
||||||
1)
|
1)
|
||||||
* US West (Oregon) Region.
|
* US West (Oregon) Region.
|
||||||
2) us-west-2
|
2) us-west-2
|
||||||
* US West (Northern California) Region.
|
* US West (Northern California) Region.
|
||||||
3) us-west-1
|
[..snip..]
|
||||||
* EU (Ireland) Region.
|
8) ap-northeast-1
|
||||||
4) eu-west-1
|
* South America (Sao Paulo) Region.
|
||||||
[snip]
|
9) sa-east-1
|
||||||
location_constraint> 1
|
location_constraint> 3
|
||||||
Remote config
|
Remote config
|
||||||
--------------------
|
--------------------
|
||||||
[remote]
|
[remote]
|
||||||
access_key_id = accesskey
|
env_auth = true
|
||||||
secret_access_key = secretaccesskey
|
access_key_id =
|
||||||
region = us-east-1
|
secret_access_key =
|
||||||
endpoint =
|
region = us-west-1
|
||||||
location_constraint =
|
endpoint =
|
||||||
|
location_constraint = us-west-1
|
||||||
--------------------
|
--------------------
|
||||||
y) Yes this is OK
|
y) Yes this is OK
|
||||||
e) Edit this remote
|
e) Edit this remote
|
||||||
@ -92,7 +108,7 @@ e) Edit existing remote
|
|||||||
n) New remote
|
n) New remote
|
||||||
d) Delete remote
|
d) Delete remote
|
||||||
q) Quit config
|
q) Quit config
|
||||||
e/n/d/q> q
|
e/n/d/q>
|
||||||
```
|
```
|
||||||
|
|
||||||
This remote is called `remote` and can now be used like this
|
This remote is called `remote` and can now be used like this
|
||||||
@ -133,36 +149,57 @@ created in. If you attempt to access a bucket from the wrong region,
|
|||||||
you will get an error, `incorrect region, the bucket is not in 'XXX'
|
you will get an error, `incorrect region, the bucket is not in 'XXX'
|
||||||
region`.
|
region`.
|
||||||
|
|
||||||
|
### Authentication ###
|
||||||
|
There are two ways to supply `rclone` with a set of AWS
|
||||||
|
credentials. In order of precedence:
|
||||||
|
|
||||||
|
- Directly in the rclone configuration file (as configured by `rclone config`)
|
||||||
|
- set `access_key_id` and `secret_access_key`
|
||||||
|
- Runtime configuration:
|
||||||
|
- set `env_auth` to `true` in the config file
|
||||||
|
- Exporting `AWS_ACCESS_KEY` and `AWS_SECRET_KEY` while running `rclone`
|
||||||
|
- Running `rclone` on an EC2 instance with an IAM role
|
||||||
|
|
||||||
|
If none of these option actually end up providing `rclone` with AWS
|
||||||
|
credentials then S3 interaction will be non-authenticated (see below).
|
||||||
|
|
||||||
### Anonymous access to public buckets ###
|
### Anonymous access to public buckets ###
|
||||||
|
|
||||||
If you want to use rclone to access a public bucket, configure with a
|
If you want to use rclone to access a public bucket, configure with a
|
||||||
blank `access_key_id` and `secret_access_key`. Eg
|
blank `access_key_id` and `secret_access_key`. Eg
|
||||||
|
|
||||||
```
|
```
|
||||||
e) Edit existing remote
|
No remotes found - make a new one
|
||||||
n) New remote
|
n) New remote
|
||||||
d) Delete remote
|
|
||||||
q) Quit config
|
q) Quit config
|
||||||
e/n/d/q> n
|
n/q> n
|
||||||
name> anons3
|
name> anons3
|
||||||
What type of source is it?
|
What type of source is it?
|
||||||
Choose a number from below
|
Choose a number from below
|
||||||
1) amazon cloud drive
|
1) amazon cloud drive
|
||||||
2) drive
|
2) b2
|
||||||
3) dropbox
|
3) drive
|
||||||
4) google cloud storage
|
4) dropbox
|
||||||
5) local
|
5) google cloud storage
|
||||||
6) s3
|
6) swift
|
||||||
7) swift
|
7) hubic
|
||||||
type> 6
|
8) local
|
||||||
AWS Access Key ID - leave blank for anonymous access.
|
9) onedrive
|
||||||
access_key_id>
|
10) s3
|
||||||
AWS Secret Access Key (password) - leave blank for anonymous access.
|
11) yandex
|
||||||
secret_access_key>
|
type> 10
|
||||||
Region to connect to.
|
Get AWS credentials from runtime (environment variables or EC2 meta data if no env vars). Only applies if access_key_id and secret_access_key is blank.
|
||||||
region> 1
|
Choose a number from below, or type in your own value
|
||||||
endpoint>
|
* Enter AWS credentials in the next step
|
||||||
location_constraint>
|
1) false
|
||||||
|
* Get AWS credentials from the environment (env vars or IAM)
|
||||||
|
2) true
|
||||||
|
env_auth> 1
|
||||||
|
AWS Access Key ID - leave blank for anonymous access or runtime credentials.
|
||||||
|
access_key_id>
|
||||||
|
AWS Secret Access Key (password) - leave blank for anonymous access or runtime credentials.
|
||||||
|
secret_access_key>
|
||||||
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
Then use it as normal with the name of the public bucket, eg
|
Then use it as normal with the name of the public bucket, eg
|
||||||
|
62
s3/s3.go
62
s3/s3.go
@ -17,6 +17,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
@ -27,6 +28,8 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/s3"
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
@ -42,11 +45,23 @@ func init() {
|
|||||||
NewFs: NewFs,
|
NewFs: NewFs,
|
||||||
// AWS endpoints: http://docs.amazonwebservices.com/general/latest/gr/rande.html#s3_region
|
// AWS endpoints: http://docs.amazonwebservices.com/general/latest/gr/rande.html#s3_region
|
||||||
Options: []fs.Option{{
|
Options: []fs.Option{{
|
||||||
|
Name: "env_auth",
|
||||||
|
Help: "Get AWS credentials from runtime (environment variables or EC2 meta data if no env vars). Only applies if access_key_id and secret_access_key is blank.",
|
||||||
|
Examples: []fs.OptionExample{
|
||||||
|
{
|
||||||
|
Value: "false",
|
||||||
|
Help: "Enter AWS credentials in the next step",
|
||||||
|
}, {
|
||||||
|
Value: "true",
|
||||||
|
Help: "Get AWS credentials from the environment (env vars or IAM)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
Name: "access_key_id",
|
Name: "access_key_id",
|
||||||
Help: "AWS Access Key ID - leave blank for anonymous access.",
|
Help: "AWS Access Key ID - leave blank for anonymous access or runtime credentials.",
|
||||||
}, {
|
}, {
|
||||||
Name: "secret_access_key",
|
Name: "secret_access_key",
|
||||||
Help: "AWS Secret Access Key (password) - leave blank for anonymous access.",
|
Help: "AWS Secret Access Key (password) - leave blank for anonymous access or runtime credentials.",
|
||||||
}, {
|
}, {
|
||||||
Name: "region",
|
Name: "region",
|
||||||
Help: "Region to connect to.",
|
Help: "Region to connect to.",
|
||||||
@ -195,19 +210,38 @@ func s3ParsePath(path string) (bucket, directory string, err error) {
|
|||||||
// s3Connection makes a connection to s3
|
// s3Connection makes a connection to s3
|
||||||
func s3Connection(name string) (*s3.S3, *session.Session, error) {
|
func s3Connection(name string) (*s3.S3, *session.Session, error) {
|
||||||
// Make the auth
|
// Make the auth
|
||||||
accessKeyID := fs.ConfigFile.MustValue(name, "access_key_id")
|
v := credentials.Value{
|
||||||
secretAccessKey := fs.ConfigFile.MustValue(name, "secret_access_key")
|
AccessKeyID: fs.ConfigFile.MustValue(name, "access_key_id"),
|
||||||
var auth *credentials.Credentials
|
SecretAccessKey: fs.ConfigFile.MustValue(name, "secret_access_key"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// first provider to supply a credential set "wins"
|
||||||
|
providers := []credentials.Provider{
|
||||||
|
// use static credentials if they're present (checked by provider)
|
||||||
|
&credentials.StaticProvider{Value: v},
|
||||||
|
|
||||||
|
// * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY
|
||||||
|
// * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY
|
||||||
|
&credentials.EnvProvider{},
|
||||||
|
|
||||||
|
// Pick up IAM role in case we're on EC2
|
||||||
|
&ec2rolecreds.EC2RoleProvider{
|
||||||
|
Client: ec2metadata.New(session.New(), &aws.Config{
|
||||||
|
HTTPClient: &http.Client{Timeout: 1 * time.Second}, // low timeout to ec2 metadata service
|
||||||
|
}),
|
||||||
|
ExpiryWindow: 3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cred := credentials.NewChainCredentials(providers)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case accessKeyID == "" && secretAccessKey == "":
|
case fs.ConfigFile.MustBool(name, "env_auth", false) && v.AccessKeyID == "" && v.SecretAccessKey == "":
|
||||||
fs.Debug(name, "Using anonymous access for S3")
|
// if no access key/secret and iam is explicitly disabled then fall back to anon interaction
|
||||||
auth = credentials.AnonymousCredentials
|
cred = credentials.AnonymousCredentials
|
||||||
case accessKeyID == "":
|
case v.AccessKeyID == "":
|
||||||
return nil, nil, errors.New("access_key_id not found")
|
return nil, nil, errors.New("access_key_id not found")
|
||||||
case secretAccessKey == "":
|
case v.SecretAccessKey == "":
|
||||||
return nil, nil, errors.New("secret_access_key not found")
|
return nil, nil, errors.New("secret_access_key not found")
|
||||||
default:
|
|
||||||
auth = credentials.NewStaticCredentials(accessKeyID, secretAccessKey, "")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
endpoint := fs.ConfigFile.MustValue(name, "endpoint")
|
endpoint := fs.ConfigFile.MustValue(name, "endpoint")
|
||||||
@ -221,7 +255,7 @@ func s3Connection(name string) (*s3.S3, *session.Session, error) {
|
|||||||
awsConfig := aws.NewConfig().
|
awsConfig := aws.NewConfig().
|
||||||
WithRegion(region).
|
WithRegion(region).
|
||||||
WithMaxRetries(maxRetries).
|
WithMaxRetries(maxRetries).
|
||||||
WithCredentials(auth).
|
WithCredentials(cred).
|
||||||
WithEndpoint(endpoint).
|
WithEndpoint(endpoint).
|
||||||
WithHTTPClient(fs.Config.Client()).
|
WithHTTPClient(fs.Config.Client()).
|
||||||
WithS3ForcePathStyle(true)
|
WithS3ForcePathStyle(true)
|
||||||
@ -235,7 +269,7 @@ func s3Connection(name string) (*s3.S3, *session.Session, error) {
|
|||||||
if req.Config.Credentials == credentials.AnonymousCredentials {
|
if req.Config.Credentials == credentials.AnonymousCredentials {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sign(accessKeyID, secretAccessKey, req.HTTPRequest)
|
sign(v.AccessKeyID, v.SecretAccessKey, req.HTTPRequest)
|
||||||
}
|
}
|
||||||
c.Handlers.Sign.Clear()
|
c.Handlers.Sign.Clear()
|
||||||
c.Handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
|
c.Handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
|
||||||
|
Loading…
Reference in New Issue
Block a user