From d7af82f4cb1810e65340537167cee91ec41feabe Mon Sep 17 00:00:00 2001 From: chrislusf Date: Fri, 1 Aug 2025 13:08:56 -0700 Subject: [PATCH] support X-Forwarded-Prefix https://github.com/seaweedfs/seaweedfs/issues/7064 --- Amazon-S3-API.md | 19 +++++++++++ S3-API-FAQ.md | 66 +++++++++++++++++++++++++++++++++++ S3-Nginx-Proxy.md | 87 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) diff --git a/Amazon-S3-API.md b/Amazon-S3-API.md index 3ab5c71..9ab64bd 100644 --- a/Amazon-S3-API.md +++ b/Amazon-S3-API.md @@ -283,6 +283,25 @@ SeaweedFS supports S3-compatible Cross-Origin Resource Sharing (CORS) configurat For detailed information about CORS configuration, see the dedicated [[S3-CORS]] page. +# Reverse Proxy Support + +SeaweedFS S3 API supports deployment behind reverse proxies with full AWS Signature v4 authentication compatibility. This includes support for: + +- **X-Forwarded-Host**: Preserves original host header for signature verification +- **X-Forwarded-Prefix**: Handles URL path prefix stripping by reverse proxies +- **Standard forwarded headers**: X-Forwarded-For, X-Forwarded-Proto, etc. + +## Path Prefix Handling + +When using reverse proxies that strip URL prefixes (e.g., `/s3/`, `/api/s3/`), SeaweedFS automatically handles signature verification for both the original prefixed path and the stripped path. This ensures seamless operation with: + +- API gateways +- Multi-tenant deployments +- Subpath hosting scenarios + +For detailed configuration examples and setup instructions, see the dedicated [[S3-Nginx-Proxy]] page. + + ## Multiple S3 Nodes If you need to setup multiple S3 nodes, you can just start multiple s3 instances pointing to a filer. diff --git a/S3-API-FAQ.md b/S3-API-FAQ.md index 728c6d6..84e8098 100644 --- a/S3-API-FAQ.md +++ b/S3-API-FAQ.md @@ -150,4 +150,70 @@ For complete documentation, examples, and best practices, see [[S3 Object Lock a Both modes prevent accidental deletion and provide audit trails for compliance purposes. +## S3 authentication fails when using reverse proxy + +### Symptom + +When accessing SeaweedFS S3 API through a reverse proxy, you might encounter signature verification errors such as: +- `SignatureDoesNotMatch` errors +- Authentication failures for presigned URLs +- Inconsistent behavior between direct access and proxied access + +### Common Causes and Solutions + +**1. Missing X-Forwarded-Host header** + +The reverse proxy must set the `X-Forwarded-Host` header to preserve the original host information for signature calculation. + +```nginx +proxy_set_header X-Forwarded-Host $host; +``` + +**2. URL path prefix stripping without X-Forwarded-Prefix** + +If your reverse proxy strips URL prefixes (e.g., `/s3/bucket/object` → `/bucket/object`), you must set the `X-Forwarded-Prefix` header: + +```nginx +# For /s3/ subpath +location /s3/ { + proxy_set_header X-Forwarded-Prefix /s3; + rewrite ^/s3/(.*) /$1 break; + proxy_pass http://seaweedfs; +} +``` + +**3. Request buffering enabled** + +Nginx request buffering can interfere with chunked transfer encoding and signature verification: + +```nginx +proxy_request_buffering off; +proxy_buffering off; +``` + +**4. Missing or incorrect forwarded headers** + +Ensure all necessary headers are forwarded: + +```nginx +proxy_set_header Host $host; +proxy_set_header X-Forwarded-Host $host; +proxy_set_header X-Forwarded-Proto $scheme; +proxy_set_header X-Forwarded-For $remote_addr; +``` + +### Testing Your Configuration + +You can test your reverse proxy configuration using AWS CLI: + +```bash +# Test basic bucket listing +aws s3 ls --endpoint-url https://yourdomain.com/s3 + +# Test presigned URL generation and access +aws s3 presign s3://test-bucket/test-object --endpoint-url https://yourdomain.com/s3 +``` + +For detailed configuration examples, see the [[S3-Nginx-Proxy]] documentation. + diff --git a/S3-Nginx-Proxy.md b/S3-Nginx-Proxy.md index e63fc45..0499cd7 100644 --- a/S3-Nginx-Proxy.md +++ b/S3-Nginx-Proxy.md @@ -5,10 +5,41 @@ For virtual-hosted style URL buckets, you'll need to add a [wildcard DNS record] Make sure the config sets the `X-Forwarded-Host` and optionally the `X-Forwarded-Port` if you are using a non-standard port. Otherwise, the AWS Signature v4 will not be correctly computed by the server, as it uses the Host header to compute the signature on the client side. +## Reverse Proxy with URL Path Prefixes + +SeaweedFS S3 API supports the `X-Forwarded-Prefix` header for scenarios where a reverse proxy strips URL path prefixes before forwarding requests. This is common when hosting the S3 API under a subpath like `/s3/` or `/api/s3/`. + +### How X-Forwarded-Prefix Works + +When a reverse proxy strips a URL prefix: +1. **Client request**: `https://example.com/s3/my-bucket/my-object` +2. **Proxy strips prefix** and forwards: `https://backend:8333/my-bucket/my-object` +3. **Proxy adds header**: `X-Forwarded-Prefix: /s3` + +SeaweedFS will: +1. First attempt signature verification using the **original path** (`/s3/my-bucket/my-object`) +2. Fall back to verification using the **stripped path** (`/my-bucket/my-object`) if the first attempt fails + +This ensures both regular S3 requests and presigned URLs work correctly with reverse proxies that strip prefixes. + +### Example Use Cases + +- **API Gateway**: `/api/s3/bucket/object` → `/bucket/object` +- **Multi-tenant setup**: `/tenant1/s3/bucket/object` → `/bucket/object` +- **Subpath hosting**: `/storage/s3/bucket/object` → `/bucket/object` + +### Important Notes + +- The `X-Forwarded-Prefix` header should contain the stripped prefix (e.g., `/s3`) +- Both regular S3 authentication and presigned URLs are supported +- This feature works with all S3 operations that require signature verification + Additionally, make sure that `proxy_request_buffering` is `off` (default is `on`), as the proxy will buffer the request, and send the request to the backend as a whole instead of chunked, and again the signature computed by the client side will be different as it would have taken into account the `Transfer-Encoding: chunked` header that is dropped by the proxy when it buffers. ### Example Nginx config +#### Standard Configuration (without URL prefix stripping) + ``` upstream seaweedfs { # Hash on uploadId query string in the GET request create consistency for multipart uploads, @@ -58,6 +89,62 @@ server { proxy_pass http://seaweedfs; } + ssl on; + ssl_certificate /{path_to_ssl_cert}/cert.pem; + ssl_certificate_key /{path_to_ssl_cert}/key.pem; +} +``` + +#### Configuration with URL Prefix Stripping (X-Forwarded-Prefix) + +For scenarios where you need to host SeaweedFS S3 API under a subpath: + +``` +upstream seaweedfs { + hash $arg_uploadId consistent; + server localhost:8333 fail_timeout=0; + keepalive 20; +} + +server { + listen 443 ssl; + server_name yourdomain.com; + + ignore_invalid_headers off; + client_max_body_size 0; + proxy_buffering off; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_connect_timeout 300; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_request_buffering off; + chunked_transfer_encoding off; + + # S3 API under /s3/ subpath + location /s3/ { + # Set the X-Forwarded-Prefix header to the stripped prefix + proxy_set_header X-Forwarded-Prefix /s3; + + # Strip the /s3 prefix before forwarding to backend + rewrite ^/s3/(.*) /$1 break; + + proxy_pass http://seaweedfs; + } + + # Alternative: S3 API under /api/s3/ subpath + location /api/s3/ { + proxy_set_header X-Forwarded-Prefix /api/s3; + rewrite ^/api/s3/(.*) /$1 break; + proxy_pass http://seaweedfs; + } + ssl on; ssl_certificate /{path_to_ssl_cert}/cert.pem; ssl_certificate_key /{path_to_ssl_cert}/key.pem;