diff --git a/Dockerfile.buildkit.plus b/Dockerfile.buildkit.plus deleted file mode 100644 index e0fc59e8..00000000 --- a/Dockerfile.buildkit.plus +++ /dev/null @@ -1,83 +0,0 @@ -FROM debian:bookworm-slim@sha256:67f3931ad8cb1967beec602d8c0506af1e37e8d73c2a0b38b181ec5d8560d395 - -ENV NGINX_PLUS_VERSION 30-2 -ENV NGINX_VERSION 1.25.1 -ENV NJS_VERSION 30+0.8.0-1 -ENV XSLT_VERSION 30-1 - -ENV PROXY_CACHE_MAX_SIZE "10g" -ENV PROXY_CACHE_INACTIVE "60m" -ENV PROXY_CACHE_SLICE_SIZE "1m" -ENV PROXY_CACHE_VALID_OK "1h" -ENV PROXY_CACHE_VALID_NOTFOUND "1m" -ENV PROXY_CACHE_VALID_FORBIDDEN "30s" -ENV CORS_ENABLED 0 -ENV CORS_ALLOW_PRIVATE_NETWORK_ACCESS "" -ENV DIRECTORY_LISTING_PATH_PREFIX "" -ENV STRIP_LEADING_DIRECTORY_PATH "" -ENV PREFIX_LEADING_DIRECTORY_PATH "" - -COPY plus/usr /usr - -# Copy files from the OSS NGINX Docker container such that the container -# startup is the same. -# Source: https://github.com/nginxinc/docker-nginx/tree/1.19.2/stable/buster -COPY common/docker-entrypoint.sh /docker-entrypoint.sh -COPY common/docker-entrypoint.d /docker-entrypoint.d/ -COPY plus/docker-entrypoint.d /docker-entrypoint.d/ -# Add NGINX Plus package repository keyring -COPY plus/usr/share/keyrings/nginx-archive-keyring.gpg /usr/share/keyrings/nginx-archive-keyring.gpg - -RUN --mount=type=secret,id=nginx-crt --mount=type=secret,id=nginx-key \ - set -eux \ - export DEBIAN_FRONTEND=noninteractive; \ - mkdir -p /etc/ssl/nginx; \ - cp /run/secrets/nginx-crt /etc/ssl/nginx/nginx-repo.crt; \ - chmod 0664 /etc/ssl/nginx/nginx-repo.crt; \ - cp /run/secrets/nginx-key /etc/ssl/nginx/nginx-repo.key; \ - chmod 0664 /etc/ssl/nginx/nginx-repo.key; \ - # create nginx user/group first, to be consistent throughout docker variants - addgroup --system --gid 101 nginx; \ - adduser --system --disabled-login --ingroup nginx --no-create-home --home /nonexistent --gecos "nginx user" --shell /bin/false --uid 101 nginx; \ - apt-get -qq update; \ - apt-get -qq upgrade --yes; \ - apt-get -qq install --yes \ - ca-certificates \ - curl \ - libedit2; \ - sh -a /usr/local/bin/add_nginx_plus_repo.sh; \ - rm /usr/local/bin/add_nginx_plus_repo.sh; \ - apt-get -qq update; \ - export DISTRO_VERSION="$(grep '^VERSION_CODENAME=' /etc/os-release | awk -v FS='=' '{print $2}')" && \ - apt-get -qq install --no-install-recommends --no-install-suggests -y \ - nginx-plus=${NGINX_PLUS_VERSION}~${DISTRO_VERSION} \ - nginx-plus-module-njs=${NJS_VERSION}~${DISTRO_VERSION} \ - nginx-plus-module-xslt=${XSLT_VERSION}~${DISTRO_VERSION} \ - gettext-base; \ - apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ - rm -rf /etc/apt/sources.list.d/nginx-plus.list /var/lib/apt/lists/* /var/tmp/* /tmp/* /etc/ssl/nginx; \ - # forward request and error logs to docker log collector - ln -sf /dev/stdout /var/log/nginx/access.log; \ - ln -sf /dev/stderr /var/log/nginx/error.log; \ - chmod -R -v +x /docker-entrypoint.sh /docker-entrypoint.d/*.sh - -ENTRYPOINT ["/docker-entrypoint.sh"] - -EXPOSE 80 - -STOPSIGNAL SIGTERM - -CMD ["nginx", "-g", "daemon off;"] - -# NGINX Docker image setup complete, everything below is specific for -# the S3 Gateway use case. - -COPY plus/etc/nginx /etc/nginx -COPY common/etc /etc -COPY common/docker-entrypoint.d/00-check-for-required-env.sh /docker-entrypoint.d/00-check-for-required-env.sh - -RUN set -eux \ - export DEBIAN_FRONTEND=noninteractive; \ - mkdir -p /var/cache/nginx/s3_proxy; \ - chown nginx:nginx /var/cache/nginx/s3_proxy; \ - chmod -R +x /docker-entrypoint.d/* diff --git a/Dockerfile.oss b/Dockerfile.oss index 41306248..7fef1ed5 100644 --- a/Dockerfile.oss +++ b/Dockerfile.oss @@ -1,63 +1,46 @@ -FROM nginx:1.27.0@sha256:56b388b0d79c738f4cf51bbaf184a14fab19337f4819ceb2cae7d94100262de8 +FROM nginx:1.27.0@sha256:9c367186df9a6b18c6735357b8eb7f407347e84aea09beb184961cb83543d46e # NJS env vars -ENV NJS_VERSION 0.8.4 -ENV NJS_RELEASE 2~bookworm +ENV NJS_VERSION=0.8.4 +ENV NJS_RELEASE=2~bookworm # Proxy cache env vars -ENV PROXY_CACHE_MAX_SIZE "10g" -ENV PROXY_CACHE_INACTIVE "60m" -ENV PROXY_CACHE_SLICE_SIZE "1m" -ENV PROXY_CACHE_VALID_OK "1h" -ENV PROXY_CACHE_VALID_NOTFOUND "1m" -ENV PROXY_CACHE_VALID_FORBIDDEN "30s" +ENV PROXY_CACHE_MAX_SIZE=10g +ENV PROXY_CACHE_INACTIVE=60m +ENV PROXY_CACHE_SLICE_SIZE=1m +ENV PROXY_CACHE_VALID_OK=1h +ENV PROXY_CACHE_VALID_NOTFOUND=1m +ENV PROXY_CACHE_VALID_FORBIDDEN=30s # CORS env vars -ENV CORS_ENABLED 0 -ENV CORS_ALLOW_PRIVATE_NETWORK_ACCESS "" +ENV CORS_ENABLED=0 +ENV CORS_ALLOW_PRIVATE_NETWORK_ACCESS="" # S3 proxy env vars -ENV DIRECTORY_LISTING_PATH_PREFIX "" -ENV STRIP_LEADING_DIRECTORY_PATH "" -ENV PREFIX_LEADING_DIRECTORY_PATH "" - -# We modify the nginx base image by: -# 1. Explicitly install the version of njs coded in the environment variable above. -# 2. Adding configuration files needed for proxying private S3 buckets -# 3. Adding a directory for proxied objects to be stored +ENV DIRECTORY_LISTING_PATH_PREFIX="" +ENV STRIP_LEADING_DIRECTORY_PATH="" +ENV PREFIX_LEADING_DIRECTORY_PATH="" + +# We modify the NGINX OSS base image by: +# 1. Explicitly installing the version of njs coded in the environment variable above. +# 2. Adding configuration files needed for proxying private S3 buckets. +# 3. Adding a directory for proxied objects to be stored. # 4. Replacing the entrypoint script with a modified version that explicitly sets resolvers. RUN set -x \ - && apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y gnupg1 ca-certificates \ - && \ - NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \ - NGINX_GPGKEY_PATH=/etc/apt/keyrings/nginx-archive-keyring.gpg; \ - export GNUPGHOME="$(mktemp -d)"; \ - found=''; \ - for server in \ - hkp://keyserver.ubuntu.com:80 \ - pgp.mit.edu \ - ; do \ - echo "Fetching GPG key $NGINX_GPGKEY from $server"; \ - gpg1 --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \ - done; \ - test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \ - gpg1 --export "$NGINX_GPGKEY" > "$NGINX_GPGKEY_PATH" ; \ - rm -rf "$GNUPGHOME"; \ - apt-get remove --purge --auto-remove -y gnupg1 && rm -rf /var/lib/apt/lists/*; \ - echo "deb [signed-by=/etc/apt/keyrings/nginx-archive-keyring.gpg] https://nginx.org/packages/mainline/debian/ $(echo $PKG_RELEASE | cut -f2 -d~) nginx" >> /etc/apt/sources.list.d/nginx.list; \ + && echo "deb [signed-by=/etc/apt/keyrings/nginx-archive-keyring.gpg] https://nginx.org/packages/mainline/debian/ $(echo $PKG_RELEASE | cut -f2 -d~) nginx" >> /etc/apt/sources.list.d/nginx.list; \ apt-get update \ && apt-get install --no-install-recommends --no-install-suggests -y \ libedit2 \ nginx-module-njs=${NGINX_VERSION}+${NJS_VERSION}-${NJS_RELEASE} \ && apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx.list -COPY common/etc /etc COPY oss/etc /etc +COPY common/etc /etc COPY common/docker-entrypoint.sh /docker-entrypoint.sh COPY common/docker-entrypoint.d /docker-entrypoint.d/ -RUN mkdir -p /var/cache/nginx/s3_proxy \ +RUN set -x \ + && mkdir -p /var/cache/nginx/s3_proxy \ && chown nginx:nginx /var/cache/nginx/s3_proxy \ && chmod -R -v +x /docker-entrypoint.sh /docker-entrypoint.d/*.sh; diff --git a/Dockerfile.plus b/Dockerfile.plus index db8035a3..2a4a6087 100644 --- a/Dockerfile.plus +++ b/Dockerfile.plus @@ -1,61 +1,84 @@ -FROM debian:bookworm-slim@sha256:67f3931ad8cb1967beec602d8c0506af1e37e8d73c2a0b38b181ec5d8560d395 +ARG RELEASE=bookworm +FROM debian:${RELEASE}-slim@sha256:67f3931ad8cb1967beec602d8c0506af1e37e8d73c2a0b38b181ec5d8560d395 -ENV NGINX_PLUS_VERSION 30-2 -ENV NGINX_VERSION 1.25.1 -ENV NJS_VERSION 30+0.8.0-1 -ENV XSLT_VERSION 30-1 +# NJS env vars +ENV NGINX_VERSION=32 +ENV NGINX_PKG_RELEASE=1~${RELEASE} +ENV NJS_VERSION=0.8.4 +ENV NJS_PKG_RELEASE=1~${RELEASE} -ENV PROXY_CACHE_MAX_SIZE "10g" -ENV PROXY_CACHE_INACTIVE "60m" -ENV PROXY_CACHE_SLICE_SIZE "1m" -ENV PROXY_CACHE_VALID_OK "1h" -ENV PROXY_CACHE_VALID_NOTFOUND "1m" -ENV PROXY_CACHE_VALID_FORBIDDEN "30s" -ENV CORS_ENABLED 0 -ENV CORS_ALLOW_PRIVATE_NETWORK_ACCESS "" -ENV DIRECTORY_LISTING_PATH_PREFIX "" -ENV STRIP_LEADING_DIRECTORY_PATH "" -ENV PREFIX_LEADING_DIRECTORY_PATH "" +# Proxy cache env vars +ENV PROXY_CACHE_MAX_SIZE=10g +ENV PROXY_CACHE_INACTIVE=60m +ENV PROXY_CACHE_SLICE_SIZE=1m +ENV PROXY_CACHE_VALID_OK=1h +ENV PROXY_CACHE_VALID_NOTFOUND=1m +ENV PROXY_CACHE_VALID_FORBIDDEN=30s -COPY plus/etc/ssl /etc/ssl -COPY plus/usr /usr +# CORS env vars +ENV CORS_ENABLED=0 +ENV CORS_ALLOW_PRIVATE_NETWORK_ACCESS="" -# Copy files from the OSS NGINX Docker container such that the container -# startup is the same. -COPY common/docker-entrypoint.sh /docker-entrypoint.sh -COPY common/docker-entrypoint.d /docker-entrypoint.d/ -COPY plus/docker-entrypoint.d /docker-entrypoint.d/ -# Add NGINX Plus package repository keyring -COPY plus/usr/share/keyrings/nginx-archive-keyring.gpg /usr/share/keyrings/nginx-archive-keyring.gpg +# S3 proxy env vars +ENV DIRECTORY_LISTING_PATH_PREFIX="" +ENV STRIP_LEADING_DIRECTORY_PATH="" +ENV PREFIX_LEADING_DIRECTORY_PATH="" -RUN set -eux \ - export DEBIAN_FRONTEND=noninteractive; \ - # create nginx user/group first, to be consistent throughout docker variants - addgroup --system --gid 101 nginx; \ - adduser --system --disabled-login --ingroup nginx --no-create-home --home /nonexistent --gecos "nginx user" --shell /bin/false --uid 101 nginx; \ - apt-get -qq update; \ - apt-get -qq upgrade --yes; \ - apt-get -qq install --yes \ - ca-certificates \ - curl \ - libedit2; \ - sh -a /usr/local/bin/add_nginx_plus_repo.sh; \ - rm /usr/local/bin/add_nginx_plus_repo.sh; \ - apt-get -qq update; \ - export DISTRO_VERSION="$(grep '^VERSION_CODENAME=' /etc/os-release | awk -v FS='=' '{print $2}')" && \ - apt-get -qq install --yes --no-install-recommends --no-install-suggests \ - nginx-plus=${NGINX_PLUS_VERSION}~${DISTRO_VERSION} \ - nginx-plus-module-njs=${NJS_VERSION}~${DISTRO_VERSION} \ - nginx-plus-module-xslt=${XSLT_VERSION}~${DISTRO_VERSION} \ - gettext-base; \ - apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ - rm -rf /etc/apt/sources.list.d/nginx-plus.list /var/lib/apt/lists/* /var/tmp/* /tmp/*; \ - # forward request and error logs to docker log collector - ln -sf /dev/stdout /var/log/nginx/access.log; \ - ln -sf /dev/stderr /var/log/nginx/error.log; \ - chmod -R -v +x /docker-entrypoint.sh /docker-entrypoint.d/*.sh +# We create an NGINX Plus image based on the official NGINX Plus Dockerfiles (https://gist.github.com/nginx-gists/36e97fc87efb5cf0039978c8e41a34b5) and modify it by: +# 1. Explicitly installing the version of njs coded in the environment variable above. +# 2. Adding configuration files needed for proxying private S3 buckets. +# 3. Adding a directory for proxied objects to be stored. +# 4. Adding the entrypoint scripts found in the base NGINX OSS Docker image with a modified version that explicitly sets resolvers. -ENTRYPOINT ["/docker-entrypoint.sh"] +# Download your NGINX license certificate and key from the F5 customer portal (https://account.f5.com) and copy them to the build context +RUN --mount=type=secret,id=nginx-crt,dst=nginx-repo.crt \ + --mount=type=secret,id=nginx-key,dst=nginx-repo.key \ + set -x \ +# Create nginx user/group first, to be consistent throughout Docker variants + && groupadd --system --gid 101 nginx \ + && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y ca-certificates gnupg2 lsb-release \ + && \ + NGINX_GPGKEYS="573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 8540A6F18833A80E9C1653A42FD21310B49F6B46 9E9BE90EACBCDE69FE9B204CBCDCD8A38D88A2B3"; \ + NGINX_GPGKEY_PATH=/usr/share/keyrings/nginx-archive-keyring.gpg; \ + export GNUPGHOME="$(mktemp -d)"; \ + found=''; \ + for NGINX_GPGKEY in $NGINX_GPGKEYS; do \ + for server in \ + hkp://keyserver.ubuntu.com:80 \ + pgp.mit.edu \ + ; do \ + echo "Fetching GPG key $NGINX_GPGKEY from $server"; \ + gpg --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \ + done; \ + test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \ + done; \ + gpg1 --export "$NGINX_GPGKEYS" > "$NGINX_GPGKEY_PATH" ; \ + rm -rf "$GNUPGHOME"; \ + apt-get remove --purge --auto-remove -y gnupg2 && rm -rf /var/lib/apt/lists/* \ +# Install the latest release of NGINX Plus and/or NGINX Plus modules (written and maintained by F5) + && nginxPackages=" \ + nginx-plus=${NGINX_VERSION}-${NGINX_PKG_RELEASE} \ + nginx-plus-module-njs=${NGINX_VERSION}+${NJS_VERSION}-${NJS_PKG_RELEASE} \ + nginx-plus-module-xslt=${NGINX_VERSION}-${NGINX_PKG_RELEASE} \ + " \ + && echo "Acquire::https::pkgs.nginx.com::Verify-Peer \"true\";" > /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::pkgs.nginx.com::Verify-Host \"true\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::pkgs.nginx.com::SslCert \"/etc/ssl/nginx/nginx-repo.crt\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "Acquire::https::pkgs.nginx.com::SslKey \"/etc/ssl/nginx/nginx-repo.key\";" >> /etc/apt/apt.conf.d/90nginx \ + && echo "deb [signed-by=$NGINX_GPGKEY_PATH] https://pkgs.nginx.com/plus/debian `lsb_release -cs` nginx-plus\n" > /etc/apt/sources.list.d/nginx-plus.list \ + && mkdir -p /etc/ssl/nginx \ + && cat nginx-repo.crt > /etc/ssl/nginx/nginx-repo.crt \ + && cat nginx-repo.key > /etc/ssl/nginx/nginx-repo.key \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y $nginxPackages curl gettext-base \ + && apt-get remove --purge -y lsb-release \ + && apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-plus.list \ + && rm -rf /etc/apt/apt.conf.d/90nginx /etc/ssl/nginx \ +# Forward request logs to Docker log collector + && ln -sf /dev/stdout /var/log/nginx/access.log \ + && ln -sf /dev/stderr /var/log/nginx/error.log EXPOSE 80 @@ -63,15 +86,17 @@ STOPSIGNAL SIGTERM CMD ["nginx", "-g", "daemon off;"] -# NGINX Docker image setup complete, everything below is specific for -# the S3 Gateway use case. - +# Copy files from the OSS NGINX Docker container such that the container +# startup is the same. COPY plus/etc/nginx /etc/nginx COPY common/etc /etc -COPY common/docker-entrypoint.d/00-check-for-required-env.sh /docker-entrypoint.d/00-check-for-required-env.sh +COPY common/docker-entrypoint.sh /docker-entrypoint.sh +COPY common/docker-entrypoint.d /docker-entrypoint.d/ +COPY plus/docker-entrypoint.d /docker-entrypoint.d/ + +RUN set -x \ + && mkdir -p /var/cache/nginx/s3_proxy \ + && chown nginx:nginx /var/cache/nginx/s3_proxy \ + && chmod -R -v +x /docker-entrypoint.sh /docker-entrypoint.d/*.sh; -RUN set -eux \ - export DEBIAN_FRONTEND=noninteractive; \ - mkdir -p /var/cache/nginx/s3_proxy; \ - chown nginx:nginx /var/cache/nginx/s3_proxy; \ - chmod -R +x /docker-entrypoint.d/* +ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/README.md b/README.md index e33e7cc5..c3c81b90 100644 --- a/README.md +++ b/README.md @@ -76,9 +76,7 @@ test/ contains automated tests for validang that the Dockerfile.oss Dockerfile that configures NGINX OSS to act as a S3 gateway Dockerfile.plus Dockerfile that builds a NGINX Plus instance that is configured equivelently to NGINX OSS - instance is configured to act as a - S3 gateway with NGINX Plus additional features enabled -Dockerfile.buildkit.plus Dockerfile with the same configuration as Dockerfile.plus, but - with support for hiding secrets using Docker's Buildkit + S3 gateway with NGINX Plus additional features enabled. The NGINX Plus license is parsed via Docker's Buildkit built-in support for secrets Dockerfile.latest-njs Dockerfile that inherits from the last build of the gateway and then builds and installs the latest version of njs from source Dockerfile.unprivileged Dockerfiles that inherits from the last build of the gateway and diff --git a/docs/getting_started.md b/docs/getting_started.md index 1590d965..eabfa612 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -2,13 +2,13 @@ ## Contents -[Configuration](#configuration) -[Running as a Systemd Service](#running-as-a-systemd-service) -[Running in Containers](#running-in-containers) -[Running Using AWS Instance Profile Credentials](#running-using-aws-instance-profile-credentials) -[Running on EKS with IAM roles for service accounts](#running-on-eks-with-iam-roles-for-service-accounts) -[Running on EKS with EKS Pod Identities](#running-on-eks-with-eks-pod-identities) -[Troubleshooting](#troubleshooting) +[Configuration](#configuration) +[Running as a Systemd Service](#running-as-a-systemd-service) +[Running in Containers](#running-in-containers) +[Running Using AWS Instance Profile Credentials](#running-using-aws-instance-profile-credentials) +[Running on EKS with IAM roles for service accounts](#running-on-eks-with-iam-roles-for-service-accounts) +[Running on EKS with EKS Pod Identities](#running-on-eks-with-eks-pod-identities) +[Troubleshooting](#troubleshooting) ## Configuration @@ -56,12 +56,12 @@ If you are using [AWS instance profile credentials](https://docs.aws.amazon.com/ you will need to omit the `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and `AWS_SESSION_TOKEN` variables from the configuration. -When running with Docker, the above environment variables can be set in a file +When running with Docker, the above environment variables can be set in a file with the `--env-file` flag. When running as a Systemd service, the environment variables are specified in the `/etc/nginx/environment` file. An example of the format of the file can be found in the [settings.example](/settings.example) file. - + There are few optional environment variables that can be used. * `AWS_ROLE_SESSION_NAME` - (optional) The value will be used for Role Session Name. The default value is nginx-s3-gateway. @@ -98,12 +98,12 @@ All items are set to the same value: ### Configuring Directory Listing Listing of S3 directories ([folders](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-folders.html)) is supported when the -`ALLOW_DIRECTORY_LIST` environment variable is set to `1`. Directory listing +`ALLOW_DIRECTORY_LIST` environment variable is set to `1`. Directory listing output can be customized by changing the [XSL stylesheet](https://www.w3schools.com/xml/xsl_intro.asp): [`common/etc/nginx/include/listing.xsl`](/common/etc/nginx/include/listing.xsl). -If you are not using AWS S3 as your backend, you may see some inconsistency in +If you are not using AWS S3 as your backend, you may see some inconsistency in the behavior with how directory listing works with HEAD requests. Additionally, -due to limitations in proxy response processing, invalid S3 folder requests will +due to limitations in proxy response processing, invalid S3 folder requests will result in log messages like: ``` libxml2 error: "Extra content at the end of the document" @@ -120,22 +120,22 @@ the path of the files returned from the listing. Using the `DIRECTORY_LISTING_PATH_PREFIX` environment variable will allow one to add that prefix in listing page's header and links. -For example, if one configures to `DIRECTORY_LISTING_PATH_PREFIX='main/'` and -then uses HAProxy to proxy the gateway with the +For example, if one configures to `DIRECTORY_LISTING_PATH_PREFIX='main/'` and +then uses HAProxy to proxy the gateway with the `http-request set-path %[path,regsub(^/main,/)]` setting, the architecture -will look like the following: +will look like the following: ![](./img/nginx-s3-gateway-directory-listing-path-prefix.png) ### Static Site Hosting When `PROVIDE_INDEX_PAGE` environment variable is set to 1, the gateway will -transform `/some/path/` to `/some/path/index.html` when retrieving from S3. -Default of "index.html" can be edited in `s3gateway.js`. -It will also redirect `/some/path` to `/some/path/` when S3 returns 404 on -`/some/path` if `APPEND_SLASH_FOR_POSSIBLE_DIRECTORY` is set. `path` has to -look like a possible directory, it must not start with a `.` and not have an -extension. +transform `/some/path/` to `/some/path/index.html` when retrieving from S3. +Default of "index.html" can be edited in `s3gateway.js`. +It will also redirect `/some/path` to `/some/path/` when S3 returns 404 on +`/some/path` if `APPEND_SLASH_FOR_POSSIBLE_DIRECTORY` is set. `path` has to +look like a possible directory, it must not start with a `.` and not have an +extension. ### Hosting a Bucket as a Subfolder on an ALB @@ -189,12 +189,12 @@ A sample Terraform script to provision a bucket is provided in `/deployments/s3_ ## Running as a Systemd Service An [install script](/standalone_ubuntu_oss_install.sh) for the gateway shows -how to install NGINX from a package repository, checkout the gateway source, +how to install NGINX from a package repository, checkout the gateway source, and configure it using the supplied environment variables. To run the script copy it to your destination system, load the environment variables mentioned in the [configuration section](#configuration) into memory, -and then execute the script. The script takes one optional parameter that +and then execute the script. The script takes one optional parameter that specifies the name of the branch to download files from. For example: @@ -206,7 +206,7 @@ sudo env $(cat settings.example) ./standalone_ubuntu_oss_install.sh ### Running the Public Open Source NGINX Container Image -The latest builds of the gateway (that use open source NGINX) are available on +The latest builds of the gateway (that use open source NGINX) are available on the project's Github [package repository](https://github.com/nginxinc/nginx-s3-gateway/pkgs/container/nginx-s3-gateway%2Fnginx-oss-s3-gateway). To run with the public open source image, replace the `settings` file specified @@ -219,7 +219,7 @@ docker run --env-file ./settings --publish 80:80 --name nginx-s3-gateway \ If you would like to run with the latest njs version, run: ``` docker run --env-file ./settings --publish 80:80 --name nginx-s3-gateway \ - ghcr.io/nginxinc/nginx-s3-gateway/nginx-oss-s3-gateway:latest-njs-oss + ghcr.io/nginxinc/nginx-s3-gateway/nginx-oss-s3-gateway:latest-njs-oss ``` Alternatively, if you would like to pin your version to a specific point in @@ -239,13 +239,13 @@ docker build --file Dockerfile.oss --tag nginx-s3-gateway:oss --tag nginx-s3-gat ``` Alternatively, if you would like to use the latest version of -[njs](https://nginx.org/en/docs/njs/), you can build an image from the latest +[njs](https://nginx.org/en/docs/njs/), you can build an image from the latest njs source by building this image after building the parent image above: ``` docker build --file Dockerfile.oss --tag nginx-s3-gateway --tag nginx-s3-gateway:latest-njs-oss . ``` -After building, you can run the image by issuing the following command and +After building, you can run the image by issuing the following command and replacing the path to the `settings` file with a file containing your specific environment variables. ``` @@ -268,11 +268,7 @@ It is worth noting that due to the way the startup scripts work, even the unpriv ### Building the NGINX Plus Container Image -In order to build the NGINX Plus container image, copy your NGINX Plus -repository keys (`nginx-repo.crt` and `nginx-repo.key`) into the -`plus/etc/ssl/nginx` directory before building. - -If you are using a version of Docker that supports Buildkit, then you can +In order to build the NGINX Plus container image, you can build the image as follows in order to prevent your private keys from being stored in the container image. @@ -280,33 +276,17 @@ To build, run the following from the project root directory: ``` DOCKER_BUILDKIT=1 docker build \ - --file Dockerfile.buildkit.plus \ + --file Dockerfile.plus \ --tag nginx-plus-s3-gateway --tag nginx-plus-s3-gateway:plus \ --secret id=nginx-crt,src=plus/etc/ssl/nginx/nginx-repo.crt \ --secret id=nginx-key,src=plus/etc/ssl/nginx/nginx-repo.key \ --squash . ``` -Otherwise, if you don't have Buildkit available, then build as follows. If you -want to remove the private keys from the image, then you may need to do a -post-build squash operation using a utility like -[docker-squash](https://pypi.org/project/docker-squash/). - -``` -docker build --file Dockerfile.plus --tag nginx-plus-s3-gateway --tag nginx-plus-s3-gateway:plus . -``` - -Alternatively, if you would like to use the latest version of -[njs](https://nginx.org/en/docs/njs/) with NGINX Plus, you can build an image -from the latest njs source by building this image after building the parent -image above: -``` -docker build --file Dockerfile.plus --tag nginx-plus-s3-gateway --tag nginx-plus-s3-gateway:latest-njs-plus . -``` - After building, you can run the image by issuing the following command and replacing the path to the `settings` file with a file containing your specific environment variables. + ``` docker run --env-file ./settings --publish 80:80 --name nginx-plus-s3-gateway \ nginx-plus-s3-gateway:plus @@ -316,9 +296,9 @@ docker run --env-file ./settings --publish 80:80 --name nginx-plus-s3-gateway \ [AWS instance profiles](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#ec2-instance-profile) allow you to assign a role to a compute so that other AWS services can trust -the instance without having to store authentication keys in the compute +the instance without having to store authentication keys in the compute instance. This is useful for the gateway because it allows us to run the -gateway without storing an unchanging `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and +gateway without storing an unchanging `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and `AWS_SESSION_TOKEN` in a file on disk or in an easily read environment variable. Instance profiles work by providing credentials to the instance via the @@ -334,7 +314,7 @@ instance, if we run the gateway as a Systemd service there are no additional steps. We just run the install script without specifying the `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and `AWS_SESSION_TOKEN` environment variables. -However, if we want to run the gateway as a container instance on that +However, if we want to run the gateway as a container instance on that EC2 instance, then we will need to run the following command using the AWS CLI tool to allow the metadata endpoint to be accessed from within a container. @@ -380,7 +360,7 @@ modified. --stack-name nginx-s3-gateway \ --query "Stacks[0].Outputs[0].OutputValue" ``` - - Upload a file to the bucket first to prevent getting a `404` when visiting + - Upload a file to the bucket first to prevent getting a `404` when visiting the URL in your browser ```sh # i.e. @@ -480,7 +460,7 @@ An alternative way to use the container image on an EKS cluster is to use a serv - Configuring a [Kubernetes service account to assume an IAM role with EKS Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-association.html) - [Configure your pods, Deployments, etc to use the Service Account](https://docs.aws.amazon.com/eks/latest/userguide/pod-configuration.html) - As soon as the pods/deployments are updated, you will see the couple of Env Variables listed below in the pods. - - `AWS_CONTAINER_CREDENTIALS_FULL_URI` - Contains the Uri of the EKS Pod Identity Agent that will provide the credentials + - `AWS_CONTAINER_CREDENTIALS_FULL_URI` - Contains the Uri of the EKS Pod Identity Agent that will provide the credentials - `AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE` - Contains the token which will be used to create temporary credentials using the EKS Pod Identity Agent. The minimal set of resources to deploy is the same than for [Running on EKS with IAM roles for service accounts](#running-on-eks-with-iam-roles-for-service-accounts), except there is no need to annotate the service account: @@ -494,11 +474,11 @@ metadata: ## Troubleshooting ### Disable default `404` error message -The default behavior of the container is to return a `404` error message for any non-`200` response code. This is implemented as a security feature to sanitize any error response from the S3 bucket being proxied. For container debugging purposes, this sanitization can be turned off by commenting out the following lines within [`default.conf.template`](https://github.com/nginxinc/nginx-s3-gateway/blob/master/common/etc/nginx/templates/default.conf.template). +The default behavior of the container is to return a `404` error message for any non-`200` response code. This is implemented as a security feature to sanitize any error response from the S3 bucket being proxied. For container debugging purposes, this sanitization can be turned off by commenting out the following lines within [`default.conf.template`](https://github.com/nginxinc/nginx-s3-gateway/blob/master/common/etc/nginx/templates/default.conf.template). ```bash proxy_intercept_errors on; error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 420 422 423 424 426 428 429 431 444 449 450 451 500 501 502 503 504 505 506 507 508 509 510 511 =404 @error404; ``` ### Error `403 Access Denied` for AWS Accounts with MFA Enabled -The REST authentication method used in this container does not work with AWS IAM roles that have MFA enabled for authentication. Please use AWS IAM role credentials that do not have MFA enabled. +The REST authentication method used in this container does not work with AWS IAM roles that have MFA enabled for authentication. Please use AWS IAM role credentials that do not have MFA enabled. diff --git a/plus/etc/ssl/nginx/.gitignore b/plus/etc/ssl/nginx/.gitignore deleted file mode 100644 index 1855abcc..00000000 --- a/plus/etc/ssl/nginx/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -nginx-repo.crt -nginx-repo.key diff --git a/plus/usr/local/bin/add_nginx_plus_repo.sh b/plus/usr/local/bin/add_nginx_plus_repo.sh deleted file mode 100644 index 6b24bd56..00000000 --- a/plus/usr/local/bin/add_nginx_plus_repo.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2020 F5 Networks -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -if [ ! -f "/etc/ssl/nginx/nginx-repo.crt" ]; then - >&2 echo "NGINX Plus repository certificate file not found at path: /etc/ssl/nginx/nginx-repo.crt" - exit 1 -fi - -if [ ! -f "/etc/ssl/nginx/nginx-repo.key" ]; then - >&2 echo "NGINX Plus repository key file not found at path: /etc/ssl/nginx/nginx-repo.key" - exit 1 -fi - -version_codename="$(grep '^VERSION_CODENAME=' /etc/os-release | awk -v FS='=' '{print $2}')" - -echo "Acquire::https::pkgs.nginx.com::Verify-Peer \"true\";" >> /etc/apt/apt.conf.d/90nginx -echo "Acquire::https::pkgs.nginx.com::Verify-Host \"true\";" >> /etc/apt/apt.conf.d/90nginx -echo "Acquire::https::pkgs.nginx.com::SslCert \"/etc/ssl/nginx/nginx-repo.crt\";" >> /etc/apt/apt.conf.d/90nginx -echo "Acquire::https::pkgs.nginx.com::SslKey \"/etc/ssl/nginx/nginx-repo.key\";" >> /etc/apt/apt.conf.d/90nginx -echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/plus/debian ${version_codename} nginx-plus" >> /etc/apt/sources.list.d/nginx-plus.list diff --git a/plus/usr/share/keyrings/.gitattributes b/plus/usr/share/keyrings/.gitattributes deleted file mode 100644 index b69c02c2..00000000 --- a/plus/usr/share/keyrings/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.gpg binary diff --git a/plus/usr/share/keyrings/nginx-archive-keyring.gpg b/plus/usr/share/keyrings/nginx-archive-keyring.gpg deleted file mode 100644 index 82b5bff0..00000000 Binary files a/plus/usr/share/keyrings/nginx-archive-keyring.gpg and /dev/null differ