Skip to content

Commit a95a6f3

Browse files
4141doneelJosho
andauthored
feat: Add new configuration option STRIP_LEADING_DIRECTORY_PATH. (#185)
Many thanks to https://github.com/elJosho for this contribution. This will strip the leading directory from a request if configured. It's useful when you're trying to expose a bucket at a specific path on an ALB. For example, if I have an ALB rule that forwards all traffic from "www.mysite.com/mybucket" to the S3 gateway, and I want to request a file in the root of my bucket, "myfile.txt". Making a request to "www.mysite.com/mybucket/myfile.txt" will fail as the S3 gateway will look for the file inside a folder named "mybucket", rather than at the root of the bucket. After this change, setting the new env var to `STRIP_LEADING_DIRECTORY_PATH = /mybucket` will send all requests to the root of the bucket. --------- Co-authored-by: Josh Watt <[email protected]>
1 parent 632bf95 commit a95a6f3

File tree

11 files changed

+50
-18
lines changed

11 files changed

+50
-18
lines changed

Dockerfile.oss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ ENV PROXY_CACHE_VALID_NOTFOUND "1m"
1010
ENV PROXY_CACHE_VALID_FORBIDDEN "30s"
1111
ENV CORS_ENABLED 0
1212
ENV DIRECTORY_LISTING_PATH_PREFIX ""
13+
ENV STRIP_LEADING_DIRECTORY_PATH ""
1314

1415
# We modify the nginx base image by:
1516
# 1. Adding configuration files needed for proxying private S3 buckets

Dockerfile.plus

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ ENV PROXY_CACHE_VALID_NOTFOUND "1m"
1212
ENV PROXY_CACHE_VALID_FORBIDDEN "30s"
1313
ENV CORS_ENABLED 0
1414
ENV DIRECTORY_LISTING_PATH_PREFIX ""
15+
ENV STRIP_LEADING_DIRECTORY_PATH ""
1516

1617
COPY plus/etc/ssl /etc/ssl
1718
COPY plus/usr /usr

common/docker-entrypoint.d/00-check-for-required-env.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ if [[ -v AWS_CONTAINER_CREDENTIALS_RELATIVE_URI ]]; then
3535
echo "Running inside an ECS task, using container credentials"
3636

3737
elif [[ -v S3_SESSION_TOKEN ]]; then
38-
echo "Depreciated the S3_SESSION_TOKEN! Use the environment variable of AWS_SESSION_TOKEN instead"
38+
echo "Deprecated the S3_SESSION_TOKEN! Use the environment variable of AWS_SESSION_TOKEN instead"
3939
failed=1
4040

4141
elif [[ -v AWS_SESSION_TOKEN ]]; then
@@ -58,11 +58,11 @@ elif [[ -v AWS_WEB_IDENTITY_TOKEN_FILE ]]; then
5858
fi
5959

6060
elif [[ -v S3_ACCESS_KEY_ID ]]; then
61-
echo "Depreciated the S3_ACCESS_KEY_ID! Use the environment variable of AWS_ACCESS_KEY_ID instead"
61+
echo "Deprecated the S3_ACCESS_KEY_ID! Use the environment variable of AWS_ACCESS_KEY_ID instead"
6262
failed=1
6363

6464
elif [[ -v S3_SECRET_KEY ]]; then
65-
echo "Depreciated the S3_SECRET_KEY! Use the environment variable of AWS_SECRET_ACCESS_KEY instead"
65+
echo "Deprecated the S3_SECRET_KEY! Use the environment variable of AWS_SECRET_ACCESS_KEY instead"
6666
failed=1
6767

6868
elif [[ -v AWS_SECRET_KEY ]]; then
@@ -77,7 +77,7 @@ else
7777
fi
7878

7979
if [[ -v S3_DEBUG ]]; then
80-
echo "Depreciated the S3_DEBUG! Use the environment variable of DEBUG instead"
80+
echo "Deprecated the S3_DEBUG! Use the environment variable of DEBUG instead"
8181
failed=1
8282
fi
8383

common/etc/nginx/nginx.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ env PROXY_CACHE_VALID_NOTFOUND;
3131
env PROXY_CACHE_VALID_FORBIDDEN;
3232
env HEADER_PREFIXES_TO_STRIP;
3333
env FOUR_O_FOUR_ON_EMPTY_BUCKET;
34+
env STRIP_LEADING_DIRECTORY_PATH;
3435

3536
events {
3637
worker_connections 1024;

common/etc/nginx/templates/default.conf.template

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@ include /etc/nginx/conf.d/gateway/v${AWS_SIGS_VERSION}_js_vars.conf;
99
# Extracts only the path from the requested URI. This strips out all query
1010
# parameters and anchors in order to prevent extraneous data from being sent
1111
# to S3.
12-
map $request_uri $uri_path {
12+
map $request_uri $uri_full_path {
1313
"~^(?P<path>.*?)(\?.*)*$" $path;
1414
}
1515

16+
# Remove a portion of request URL (if configured)
17+
map $uri_full_path $uri_path {
18+
"~^$STRIP_LEADING_DIRECTORY_PATH(.*)" $1;
19+
default $uri_full_path;
20+
}
21+
1622
map $S3_STYLE $s3_host_hdr {
1723
virtual "${S3_BUCKET_NAME}.${S3_SERVER}";
1824
path "${S3_SERVER}:${S3_SERVER_PORT}";

docs/getting_started.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ running as a Container or as a Systemd service.
3939
| `JS_TRUSTED_CERT_PATH` | No | | | Enables the `js_fetch_trusted_certificate` directive when retrieving AWS credentials and sets the path (on the container) to the specified path |
4040
| `HEADER_PREFIXES_TO_STRIP` | No | | | A list of HTTP header prefixes that exclude headers client responses. List should be specified in lower-case and a semicolon (;) should be used to as a deliminator between values. For example: `x-goog-;x-something-` |
4141
| `CORS_ENABLED` | No | `true`, `false` | `false` | Flag that enables CORS headers on GET requests and enables pre-flight OPTIONS requests. If enabled, this will add CORS headers for "fully open" cross domain requests by default, meaning all domains are allowed, similar to the settings show in [this example](https://enable-cors.org/server_nginx.html). CORS settings can be fine-tuned by overwriting the [`cors.conf.template`](/common/etc/nginx/templates/gateway/cors.conf.template) file. |
42-
| `CORS_ALLOWED_ORIGIN` | No | | | value to set to be returned from the CORS `Access-Control-Allow-Origin` header. This value is only used if CORS is enabled. (default: \*) |
43-
42+
| `CORS_ALLOWED_ORIGIN` | No | | | value to set to be returned from the CORS `Access-Control-Allow-Origin` header. This value is only used if CORS is enabled. (default: \*)
43+
| `STRIP_LEADING_DIRECTORY_PATH` | No | | | Removes a portion of the path in the requested URL (if configured). Useful when deploying to an ALB under a folder (eg. www.mysite.com/somepath).
4444

4545
If you are using [AWS instance profile credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html),
4646
you will need to omit the `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and `AWS_SESSION_TOKEN` variables from
@@ -104,6 +104,13 @@ It will also redirect `/some/path` to `/some/path/` when S3 returns 404 on
104104
look like a possible directory, it must not start with a `.` and not have an
105105
extension.
106106

107+
### Hosting a Bucket as a Subfolder on an ALB
108+
109+
The `STRIP_LEADING_DIRECTORY_PATH` environment variable allows one to host an
110+
S3 bucket in a subfolder on an ALB. For example, if you wanted to expose the
111+
root of a bucket under the path "www.mysite.com/somepath", you would set this
112+
variable to "/somepath".
113+
107114
## Running as a Systemd Service
108115

109116
An [install script](/standalone_ubuntu_oss_install.sh) for the gateway shows

settings.example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ S3_BUCKET_NAME=my-bucket
22
AWS_ACCESS_KEY_ID=ZZZZZZZZZZZZZZZZZZZZ
33
AWS_SECRET_ACCESS_KEY=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
44
AWS_SESSION_TOKEN=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
5-
S3_SERVER=s3-us-east-1.amazonaws.com
5+
S3_SERVER=s3.us-east-1.amazonaws.com
66
S3_SERVER_PORT=443
77
S3_SERVER_PROTO=https
88
S3_REGION=us-east-1
@@ -18,3 +18,4 @@ PROXY_CACHE_INACTIVE=60m
1818
PROXY_CACHE_VALID_OK=1h
1919
PROXY_CACHE_VALID_NOTFOUND=1m
2020
PROXY_CACHE_VALID_FORBIDDEN=30s
21+
STRIP_LEADING_DIRECTORY_PATH=/somepath

standalone_ubuntu_oss_install.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ PROXY_CACHE_VALID_NOTFOUND=${PROXY_CACHE_VALID_NOTFOUND:-'1m'}
171171
PROXY_CACHE_VALID_FORBIDDEN=${PROXY_CACHE_VALID_FORBIDDEN:-'30s'}
172172
# Enables or disables CORS for the S3 Gateway (true=enabled, false=disabled)
173173
CORS_ENABLED=${CORS_ENABLED:-'false'}
174+
# Configure portion of URL to be removed (optional)
175+
STRIP_LEADING_DIRECTORY_PATH=${STRIP_LEADING_DIRECTORY_PATH:-''}
174176
EOF
175177

176178
# By enabling CORS, we also need to enable the OPTIONS method which

test.sh

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,12 @@ integration_test() {
247247
printf "\e[1m Integration test suite with PROVIDE_INDEX_PAGE=%s\e[22m\n" "$3"
248248
printf "\033[34;1m▶\033[0m"
249249
printf "\e[1m Integration test suite with APPEND_SLASH_FOR_POSSIBLE_DIRECTORY=%s\e[22m\n" "$4"
250+
printf "\033[34;1m▶\033[0m"
251+
printf "\e[1m Integration test suite with STRIP_LEADING_DIRECTORY_PATH=%s\e[22m\n" "$5"
250252

251253
p "Starting Docker Compose Environment"
252254
# COMPOSE_COMPATIBILITY=true Supports older style compose filenames with _ vs -
253-
COMPOSE_COMPATIBILITY=true AWS_SIGS_VERSION=$1 ALLOW_DIRECTORY_LIST=$2 PROVIDE_INDEX_PAGE=$3 APPEND_SLASH_FOR_POSSIBLE_DIRECTORY=$4 compose up -d
255+
COMPOSE_COMPATIBILITY=true AWS_SIGS_VERSION=$1 ALLOW_DIRECTORY_LIST=$2 PROVIDE_INDEX_PAGE=$3 APPEND_SLASH_FOR_POSSIBLE_DIRECTORY=$4 STRIP_LEADING_DIRECTORY_PATH=$5 compose up -d
254256

255257
if [ "${wait_for_it_installed}" ]; then
256258
if [ -x "${wait_for_it_cmd}" ]; then
@@ -259,8 +261,8 @@ integration_test() {
259261
fi
260262

261263
p "Starting HTTP API tests (v$1 signatures)"
262-
echo " test/integration/test_api.sh \"$test_server\" \"$test_dir\" $1 $2 $3 $4"
263-
bash "${test_dir}/integration/test_api.sh" "${test_server}" "${test_dir}" "$1" "$2" "$3" "$4";
264+
echo " test/integration/test_api.sh \"$test_server\" \"$test_dir\" $1 $2 $3 $4 $5"
265+
bash "${test_dir}/integration/test_api.sh" "${test_server}" "${test_dir}" "$1" "$2" "$3" "$4" "$5";
264266

265267
# We check to see if NGINX is in fact using the correct version of AWS
266268
# signatures as it was configured to do.
@@ -402,36 +404,41 @@ runUnitTestWithSessionToken "s3gateway_test.js"
402404
integration_test_data
403405

404406
p "Testing API with AWS Signature V2 and allow directory listing off"
405-
integration_test 2 0 0 0
407+
integration_test 2 0 0 0 ""
406408

407409
compose stop nginx-s3-gateway # Restart with new config
408410

409411
p "Testing API with AWS Signature V2 and allow directory listing on"
410-
integration_test 2 1 0 0
412+
integration_test 2 1 0 0 ""
411413

412414
compose stop nginx-s3-gateway # Restart with new config
413415

414416
p "Testing API with AWS Signature V2 and static site on"
415-
integration_test 2 0 1 0
417+
integration_test 2 0 1 0 ""
416418

417419
compose stop nginx-s3-gateway # Restart with new config
418420

419421
p "Testing API with AWS Signature V2 and allow directory listing on and append slash and allow index"
420-
integration_test 2 1 1 1
422+
integration_test 2 1 1 1 ""
421423

422424
compose stop nginx-s3-gateway # Restart with new config
423425

424426
p "Test API with AWS Signature V4 and allow directory listing off"
425-
integration_test 4 0 0 0
427+
integration_test 4 0 0 0 ""
426428

427429
compose stop nginx-s3-gateway # Restart with new config
428430

429431
p "Test API with AWS Signature V4 and allow directory listing on and appending /"
430-
integration_test 4 1 0 1
432+
integration_test 4 1 0 1 ""
431433

432434
compose stop nginx-s3-gateway # Restart with new config
433435

434436
p "Test API with AWS Signature V4 and static site on appending /"
435-
integration_test 4 0 1 1
437+
integration_test 4 0 1 1 ""
438+
439+
compose stop nginx-s3-gateway # Restart with new config
440+
441+
p "Testing API with AWS Signature V2 and allow directory listing off and prefix stripping on"
442+
integration_test 2 0 0 0 /my-bucket
436443

437444
p "All integration tests complete"

test/docker-compose.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ services:
2626
ALLOW_DIRECTORY_LIST:
2727
PROVIDE_INDEX_PAGE:
2828
APPEND_SLASH_FOR_POSSIBLE_DIRECTORY:
29+
STRIP_LEADING_DIRECTORY_PATH:
2930
AWS_SIGS_VERSION:
3031
STATIC_SITE_HOSTING:
3132
PROXY_CACHE_MAX_SIZE: "10g"

0 commit comments

Comments
 (0)