chrislusf
2025-08-01 13:08:56 -07:00
parent 40aac1ab46
commit d7af82f4cb
3 changed files with 172 additions and 0 deletions
+19
@@ -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.
+66
@@ -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.
+87
@@ -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;