From f81cd7d2797aa1917e3763a330c1933db1b2dd90 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Wed, 17 Dec 2025 16:49:04 +0000 Subject: [PATCH] serve s3: make errors in --s3-auth-key fatal - fixes #9044 Previously if auth keys were provided without a comma then rclone would only log an INFO message which could mean it went on to serve without any auth. The parsing for environment variables was changed in v1.70.0 to make them work properly with multiple inputs. This means the input is treated like a mini CSV file which works well except in this case when the input has commas. This meant `user,auth` without quotes is treated as two key pairs `user` and `quote`. The correct syntax is `"user,auth"`. This updates the documentation accordingly. --- cmd/serve/s3/serve_s3.md | 20 ++++++++++++++++++++ cmd/serve/s3/server.go | 9 +++++++-- cmd/serve/s3/utils.go | 8 ++++---- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/cmd/serve/s3/serve_s3.md b/cmd/serve/s3/serve_s3.md index 7143da9ac..a1281b515 100644 --- a/cmd/serve/s3/serve_s3.md +++ b/cmd/serve/s3/serve_s3.md @@ -13,6 +13,26 @@ docs](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)). `--auth-key` is not provided then `serve s3` will allow anonymous access. +Like all rclone flags `--auth-key` can be set via environment +variables, in this case `RCLONE_AUTH_KEY`. Since this flag can be +repeated, the input to `RCLONE_AUTH_KEY` is CSV encoded. Because the +`accessKey,secretKey` has a comma in, this means it needs to be in +quotes. + +```console +export RCLONE_AUTH_KEY='"user,pass"' +rclone serve s3 ... +``` + +Or to supply multiple identities: + +```console +export RCLONE_AUTH_KEY='"user1,pass1","user2,pass2"' +rclone serve s3 ... +``` + +Setting this variable without quotes will produce an error. + Please note that some clients may require HTTPS endpoints. See [the SSL docs](#tls-ssl) for more information. diff --git a/cmd/serve/s3/server.go b/cmd/serve/s3/server.go index 4ef792701..0d690b642 100644 --- a/cmd/serve/s3/server.go +++ b/cmd/serve/s3/server.go @@ -70,6 +70,11 @@ func newServer(ctx context.Context, f fs.Fs, opt *Options, vfsOpt *vfscommon.Opt w.s3Secret = getAuthSecret(opt.AuthKey) } + authList, err := authlistResolver(opt.AuthKey) + if err != nil { + return nil, fmt.Errorf("parsing auth list failed: %q", err) + } + var newLogger logger w.faker = gofakes3.New( newBackend(w), @@ -77,7 +82,7 @@ func newServer(ctx context.Context, f fs.Fs, opt *Options, vfsOpt *vfscommon.Opt gofakes3.WithLogger(newLogger), gofakes3.WithRequestID(rand.Uint64()), gofakes3.WithoutVersioning(), - gofakes3.WithV4Auth(authlistResolver(opt.AuthKey)), + gofakes3.WithV4Auth(authList), gofakes3.WithIntegrityCheck(true), // Check Content-MD5 if supplied ) @@ -92,7 +97,7 @@ func newServer(ctx context.Context, f fs.Fs, opt *Options, vfsOpt *vfscommon.Opt w._vfs = vfs.New(f, vfsOpt) if len(opt.AuthKey) > 0 { - w.faker.AddAuthKeys(authlistResolver(opt.AuthKey)) + w.faker.AddAuthKeys(authList) } } diff --git a/cmd/serve/s3/utils.go b/cmd/serve/s3/utils.go index 5020df63a..cb6a926a3 100644 --- a/cmd/serve/s3/utils.go +++ b/cmd/serve/s3/utils.go @@ -3,6 +3,7 @@ package s3 import ( "context" "encoding/hex" + "errors" "io" "os" "path" @@ -125,15 +126,14 @@ func rmdirRecursive(p string, VFS *vfs.VFS) { } } -func authlistResolver(list []string) map[string]string { +func authlistResolver(list []string) (map[string]string, error) { authList := make(map[string]string) for _, v := range list { parts := strings.Split(v, ",") if len(parts) != 2 { - fs.Infof(nil, "Ignored: invalid auth pair %s", v) - continue + return nil, errors.New("invalid auth pair: expecting a single comma") } authList[parts[0]] = parts[1] } - return authList + return authList, nil }