Commit Graph
34 Commits
Author SHA1 Message Date
Chris Lu 5d5ea63b3f Fix what the Go 1.26 language bump breaks (#10794)
* worker: log the balance move stage through a constant format string

Go 1.26's printf analyzer now follows printf wrappers reached through an
interface, so passing the stage straight to Logger.Info is a vet failure.

* s3api: bracket the IPv6 host in the signature test URL

A bare IPv6 literal is legal in a Host header but never in a URL. Go 1.26
stopped parsing it leniently, so carry the two forms separately and set
r.Host to the value the client would actually have signed.

* mini: bracket IPv6 addresses in the readiness probe URLs

An IPv6-only host hands mini a bare literal, and %s:%d pasted it into a URL
unbracketed. Under Go 1.26 that URL no longer parses, so waiting for the
admin server never succeeds and mini refuses to start.
2026-08-17 14:46:25 -07:00
Chris Lu 40c1797f8e fix(s3): allow anonymous ListBuckets with prefix-scoped List action (#9073)
* fix(s3): allow anonymous ListBuckets with prefix-scoped List action

An anonymous identity holding a prefix-scoped action such as
"List:prefix-*" was denied at the auth middleware before ListBucketsHandler
could apply the per-bucket visibility check. The middleware called
CanDo with an empty bucket, which never matches a scoped action, so
every anonymous ListBuckets request returned 403 even though matching
buckets should have been visible.

Defer ListBuckets authorization to the handler for the anonymous
identity when it actually carries a List action, mirroring the
existing behavior for authenticated users. Anonymous identities with
no List action continue to be rejected at the global layer, preserving
the secure-by-default posture.

Fixes #9072

* refactor(s3): make hasListAction a method on Identity

Addresses PR review — consistent with existing CanDo/isAdmin methods and
also treats Admin identities as implicitly having List permission.
2026-04-14 10:52:00 -07:00
Lars Lehtonen 5c5d377277 weed/s3api: prune test-only functions (#8840)
weed/s3api: prune functions that are referenced only from tests and the tests that exercise them.
2026-03-30 09:43:33 -07:00
3d81d5bef7 Fix S3 signature verification behind reverse proxies (#8444)
* Fix S3 signature verification behind reverse proxies

When SeaweedFS is deployed behind a reverse proxy (e.g. nginx, Kong,
Traefik), AWS S3 Signature V4 verification fails because the Host header
the client signed with (e.g. "localhost:9000") differs from the Host
header SeaweedFS receives on the backend (e.g. "seaweedfs:8333").

This commit adds a new -s3.externalUrl parameter (and S3_EXTERNAL_URL
environment variable) that tells SeaweedFS what public-facing URL clients
use to connect. When set, SeaweedFS uses this host value for signature
verification instead of the Host header from the incoming request.

New parameter:
  -s3.externalUrl  (flag) or S3_EXTERNAL_URL (environment variable)
  Example: -s3.externalUrl=http://localhost:9000
  Example: S3_EXTERNAL_URL=https://s3.example.com

The environment variable is particularly useful in Docker/Kubernetes
deployments where the external URL is injected via container config.
The flag takes precedence over the environment variable when both are set.

At startup, the URL is parsed and default ports are stripped to match
AWS SDK behavior (port 80 for HTTP, port 443 for HTTPS), so
"http://s3.example.com:80" and "http://s3.example.com" are equivalent.

Bugs fixed:
- Default port stripping was removed by a prior PR, causing signature
  mismatches when clients connect on standard ports (80/443)
- X-Forwarded-Port was ignored when X-Forwarded-Host was not present
- Scheme detection now uses proper precedence: X-Forwarded-Proto >
  TLS connection > URL scheme > "http"
- Test expectations for standard port stripping were incorrect
- expectedHost field in TestSignatureV4WithForwardedPort was declared
  but never actually checked (self-referential test)

* Add Docker integration test for S3 proxy signature verification

Docker Compose setup with nginx reverse proxy to validate that the
-s3.externalUrl parameter (or S3_EXTERNAL_URL env var) correctly
resolves S3 signature verification when SeaweedFS runs behind a proxy.

The test uses nginx proxying port 9000 to SeaweedFS on port 8333,
with X-Forwarded-Host/Port/Proto headers set. SeaweedFS is configured
with -s3.externalUrl=http://localhost:9000 so it uses "localhost:9000"
for signature verification, matching what the AWS CLI signs with.

The test can be run with aws CLI on the host or without it by using
the amazon/aws-cli Docker image with --network host.

Test covers: create-bucket, list-buckets, put-object, head-object,
list-objects-v2, get-object, content round-trip integrity,
delete-object, and delete-bucket — all through the reverse proxy.

* Create s3-proxy-signature-tests.yml

* fix CLI

* fix CI

* Update s3-proxy-signature-tests.yml

* address comments

* Update Dockerfile

* add user

* no need for fuse

* Update s3-proxy-signature-tests.yml

* debug

* weed mini

* fix health check

* health check

* fix health checking

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Chris Lu <chris.lu@gmail.com>
2026-02-26 14:20:42 -08:00
Chris Lu d5e71eb0d8 Revert "s3api: preserve Host header port in signature verification (#8434)"
This reverts commit 98d89ffad7.
2026-02-25 12:28:44 -08:00
Chris Lu 98d89ffad7 s3api: preserve Host header port in signature verification (#8434)
Avoid stripping default ports (80/443) from the Host header in extractHostHeader.
This fixes SignatureDoesNotMatch errors when SeaweedFS is accessed via a proxy
(like Kong Ingress) that explicitly includes the port in the Host header or
X-Forwarded-Host, which S3 clients sign.

Also cleaned up unused variables and logic after refactoring.
2026-02-24 13:09:40 -08:00
Chris Lu f64ce759e0 feat(iam): add SetUserStatus and UpdateAccessKey actions (#7750)
feat(iam): add SetUserStatus and UpdateAccessKey actions (#7745)

Add ability to enable/disable users and access keys without deleting them.

## Changes

### Protocol Buffer Updates
- Add `disabled` field (bool) to Identity message for user status
  - false (default) = enabled, true = disabled
  - No backward compatibility hack needed since zero value is correct
- Add `status` field (string: Active/Inactive) to Credential message

### New IAM Actions
- SetUserStatus: Enable or disable a user (requires admin)
- UpdateAccessKey: Change access key status (self-service or admin)

### Behavior
- Disabled users: All API requests return AccessDenied
- Inactive access keys: Signature validation fails
- Status check happens early in auth flow for performance
- Backward compatible: existing configs default to enabled (disabled=false)

### Use Cases
1. Temporary suspension: Disable user access during investigation
2. Key rotation: Deactivate old key before deletion
3. Offboarding: Disable rather than delete for audit purposes
4. Emergency response: Quickly disable compromised credentials

Fixes #7745
2025-12-14 18:48:39 -08:00
Chris Lu 498ac8903f S3: prevent deleting buckets with object locking (#7434)
* prevent deleting buckets with object locking

* addressing comments

* Update s3api_bucket_handlers.go

* address comments

* early return

* refactor

* simplify

* constant

* go fmt
2025-11-03 15:27:20 -08:00
Chris Luandgemini-code-assist[bot] 9f07bca9cc Fix IPv6 host header formatting to match AWS SDK behavior (#7414)
* Add nginx reverse proxy documentation for S3 API

Fixes #7407

Add comprehensive documentation and example configuration for using
nginx as a reverse proxy with SeaweedFS S3 API while maintaining AWS
Signature V4 authentication compatibility.

Changes:
- Add docker/nginx/README.md with detailed setup guide
- Add docker/nginx/s3-example.conf with working configuration
- Update docker/nginx/proxy.conf with important S3 notes

The documentation covers:
- Critical requirements for AWS Signature V4 authentication
- Common mistakes and why they break S3 authentication
- Complete working nginx configurations
- Debugging tips and troubleshooting
- Performance tuning recommendations

* Fix IPv6 host header formatting to match AWS SDK behavior

Follow-up to PR #7403

When a default port (80 for HTTP, 443 for HTTPS) is stripped from an
IPv6 address, the square brackets should also be removed to match AWS
SDK behavior for S3 signature calculation.

Reference: https://github.com/aws/aws-sdk-go-v2/blob/main/aws/signer/internal/v4/host.go
The AWS SDK's stripPort function explicitly removes brackets when
returning an IPv6 address without a port.

Changes:
- Update extractHostHeader to strip brackets from IPv6 addresses when
  no port or default port is used
- Update test expectations to match AWS SDK behavior
- Add detailed comments explaining the AWS SDK compatibility requirement

This ensures S3 signature validation works correctly with IPv6 addresses
behind reverse proxies, matching AWS S3 canonical request format.

Fixes the issue raised in PR #7403 comment:
https://github.com/seaweedfs/seaweedfs/pull/7403#issuecomment-3471105438

* Update docker/nginx/README.md

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Add nginx reverse proxy documentation for S3 API

Fixes #7407

Add comprehensive documentation and example configuration for using
nginx as a reverse proxy with SeaweedFS S3 API while maintaining AWS
Signature V4 authentication compatibility.

Changes:
- Add docker/nginx/README.md with detailed setup guide
- Add docker/nginx/s3-example.conf with working configuration
- Update docker/nginx/proxy.conf with important S3 notes

The documentation covers:
- Critical requirements for AWS Signature V4 authentication
- Common mistakes and why they break S3 authentication
- Complete working nginx configurations
- Debugging tips and troubleshooting
- Performance tuning recommendations

Fix IPv6 host header formatting to match AWS SDK behavior

Follow-up to PR #7403

When a default port (80 for HTTP, 443 for HTTPS) is stripped from an
IPv6 address, the square brackets should also be removed to match AWS
SDK behavior for S3 signature calculation.

Reference: https://github.com/aws/aws-sdk-go-v2/blob/main/aws/signer/internal/v4/host.go
The AWS SDK's stripPort function explicitly removes brackets when
returning an IPv6 address without a port.

Changes:
- Update extractHostHeader to strip brackets from IPv6 addresses when
  no port or default port is used
- Update test expectations to match AWS SDK behavior
- Add detailed comments explaining the AWS SDK compatibility requirement

This ensures S3 signature validation works correctly with IPv6 addresses
behind reverse proxies, matching AWS S3 canonical request format.

Fixes the issue raised in PR #7403 comment:
https://github.com/seaweedfs/seaweedfs/pull/7403#issuecomment-3471105438

* Revert "Merge branch 'fix-ipv6-brackets-default-port' of https://github.com/seaweedfs/seaweedfs into fix-ipv6-brackets-default-port"

This reverts commit cca3f3985f, reversing
changes made to 2b8f9de78e.

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-10-30 21:06:00 -07:00
7e624d5355 * Fix s3 auth with proxy request (#7403)
* * Fix s3 auth with proxy request

* * 6649 Add unit test for signature v4

* address comments

* fix for tests

* ipv6

* address comments

* setting scheme

Works for both cases (direct HTTPS and behind proxy)

* trim for ipv6

* Corrected Scheme Precedence Order

* trim

* accurate

---------

Co-authored-by: chrislu <chris.lu@gmail.com>
Co-authored-by: Chris Lu <chrislusf@users.noreply.github.com>
2025-10-29 18:01:18 -07:00
Chris Lu 7d26c8838f S3: auth supports X-Forwarded-Host and X-Forwarded-Port (#7398)
* add fix and tests

* address comments

* idiomatic

* ipv6
2025-10-28 14:16:27 -07:00
Tom Crasset 824dcac3bf s3: combine all signature verification checks into a single function (#7330) 2025-10-25 01:11:45 -07:00
Chris Lu 07dc552e1c master: Fix raft url (#7255)
* fix signature

* fix url scheme
2025-09-18 14:46:53 -07:00
Chris Luandgemini-code-assist[bot] c6d9756933 fix signature hashing for iam (#7100)
* fix signature hashing for iam

* add tests

* address comments

* Update weed/s3api/auto_signature_v4_test.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* indention

* fix test

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-08-05 22:54:54 -07:00
Chris Luandgemini-code-assist[bot] 72176601c1 S3: Fix iam payload hash (#7081)
* fix iam payload hash

* streaming hash

* Update weed/s3api/auto_signature_v4_test.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Update weed/s3api/auto_signature_v4_test.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* address comments

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-08-04 09:10:01 -07:00
Chris Luandgemini-code-assist[bot] 3d4e8409a5 Support X-Forwarded-Port (#7070)
* support for the X-Forwarded-Prefix header

* remove comments

* refactoring

* refactoring

* path.Clean

* support X-Forwarded-Port

* Update weed/s3api/auth_signature_v4.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Update weed/s3api/auto_signature_v4_test.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* more tests

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-08-01 15:45:34 -07:00
Chris Lu f1eb4dd427 S3: support for the X-Forwarded-Prefix header (#7068)
* support for the X-Forwarded-Prefix header

* remove comments

* refactoring

* refactoring

* path.Clean
2025-08-01 13:07:54 -07:00
Chris LuandCopilot 74f4e9ba5a rewrite, simplify, avoid unused functions (#6989)
* adding cors support

* address some comments

* optimize matchesWildcard

* address comments

* fix for tests

* address comments

* address comments

* address comments

* path building

* refactor

* Update weed/s3api/s3api_bucket_config.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* address comment

Service-level responses need both Access-Control-Allow-Methods and Access-Control-Allow-Headers. After setting Access-Control-Allow-Origin and Access-Control-Expose-Headers, also set Access-Control-Allow-Methods: * and Access-Control-Allow-Headers: * so service endpoints satisfy CORS preflight requirements.

* Update weed/s3api/s3api_bucket_config.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update weed/s3api/s3api_object_handlers.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update weed/s3api/s3api_object_handlers.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix

* refactor

* Update weed/s3api/s3api_bucket_config.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update weed/s3api/s3api_object_handlers.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update weed/s3api/s3api_server.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* simplify

* add cors tests

* fix tests

* fix tests

* remove unused functions

* fix tests

* simplify

* address comments

* fix

* Update weed/s3api/auth_signature_v4.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* rename variable

* Revert "Apply suggestion from @Copilot"

This reverts commit fce2d4e57e.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-15 10:11:49 -07:00
Tom Crasset a7b964af96 add s3 signature tests and prepare implementation of STREAMING-UNSIGNED-PAYLOAD-TRAILER (#6525)
* add tests for s3 signature

* add test for newSignV4ChunkedReader.Read()

* add glog import
2025-02-07 10:54:31 -08:00
Konstantin Lebedev 5ffacbb6ea refactor all methods strings to const (#5726) 2024-07-01 01:00:39 -07:00
clonefetch 9e07a87fcb chore: fix function names in comment (#5478) 2024-04-08 07:19:02 -07:00
Konstantin LebedevandKonstantin Lebedev d8b424d123 [s3] optimization iam lookup for reducing algorithm complexity (#4857)
optimization iam lookup for reducing algorithm complexity
https://github.com/seaweedfs/seaweedfs/issues/4519

Co-authored-by: Konstantin Lebedev <9497591+kmlebedev@users.noreply.github.co>
2023-09-21 08:19:11 -07:00
chrislu cf28108ea4 fix grpd dial option 2023-09-19 14:02:51 -07:00
Patrick Schmidt 98dcec0ee2 Clean up old signature hash pools 2023-09-05 10:33:27 -07:00
Patrick Schmidt cdd817edf9 Improve S3 request signing performance
This change is caching HMAC hashers for repeated use in subsequent
requests and chunks, so they don't have to be initialized from
scratch every time.
On my local computer this gives me ~5-6 times faster signature
calculation and ~5-6.5% more throughput in S3 requests. The smaller
the payload the better the throughput gets.
2023-09-05 10:33:27 -07:00
Ryan Russell 6f7ef8711a docs(s3api): readability improvements (#3696)
Signed-off-by: Ryan Russell <git@ryanrussell.org>

Signed-off-by: Ryan Russell <git@ryanrussell.org>
2022-09-15 03:13:21 -07:00
chrislu 26dbc6c905 move to https://github.com/seaweedfs/seaweedfs 2022-07-29 00:17:28 -07:00
Eng Zer Jun a23bcbb7ec refactor: move from io/ioutil to io and os package
The io/ioutil package has been deprecated as of Go 1.16, see
https://golang.org/doc/go1.16#ioutil. This commit replaces the existing
io/ioutil functions with their new definitions in io and os packages.

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2021-10-14 12:27:58 +08:00
Konstantin Lebedev ba175f81b5 add auth aws signV4 2021-04-08 17:40:47 +05:00
Konstantin Lebedev e1190b3224 load S3 config from filer
https://github.com/chrislusf/seaweedfs/issues/1500
2020-11-03 21:45:56 +05:00
Chris Lu 5b40a2690a refactoring 2020-09-19 14:09:58 -07:00
Chris Lu ed0acd1722 go fmt 2020-02-26 16:52:57 -08:00
Chris Lu b90ad6f452 add v2 support 2020-02-09 16:02:05 -08:00
Chris Lu 9ed364f053 support acl 2020-02-09 14:30:02 -08:00