Merge tag '1.3.1' into merge-upstream
This commit is contained in:
commit
51191e168a
83 changed files with 2512 additions and 772 deletions
17
.github/dependabot.yml
vendored
17
.github/dependabot.yml
vendored
|
@ -1,11 +1,12 @@
|
|||
version: 2
|
||||
updates:
|
||||
|
||||
# Maintain dependencies for Docker
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
commit-message:
|
||||
prefix: "build"
|
||||
labels:
|
||||
- "type/build"
|
||||
- "scope/dockerfile"
|
||||
|
@ -14,6 +15,18 @@ updates:
|
|||
- package-ecosystem: "pip"
|
||||
directory: "/test/requirements"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "ci"
|
||||
labels:
|
||||
- "type/ci"
|
||||
|
||||
# Maintain GitHub Actions
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "ci"
|
||||
labels:
|
||||
- "type/ci"
|
||||
|
|
|
@ -1,39 +1,40 @@
|
|||
name: DockerHub
|
||||
name: Build and publish Docker images
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * 1'
|
||||
- cron: "0 0 * * 1"
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- '*.*.*'
|
||||
- "*.*.*"
|
||||
paths-ignore:
|
||||
- 'test/*'
|
||||
- '.gitignore'
|
||||
- 'docker-compose-separate-containers.yml'
|
||||
- 'docker-compose.yml'
|
||||
- 'LICENSE'
|
||||
- 'Makefile'
|
||||
- '*.md'
|
||||
- "test/*"
|
||||
- ".gitignore"
|
||||
- "docker-compose-separate-containers.yml"
|
||||
- "docker-compose.yml"
|
||||
- "LICENSE"
|
||||
- "Makefile"
|
||||
- "*.md"
|
||||
|
||||
jobs:
|
||||
multiarch-build-debian:
|
||||
name: Build and publish Debian image
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Retrieve version
|
||||
run: echo "GIT_DESCRIBE=$(git describe --tags)" >> $GITHUB_ENV
|
||||
|
||||
- name: Retrieve nginx-proxy version
|
||||
id: nginx-proxy_version
|
||||
run: echo "VERSION=$(git describe --tags)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Get Docker tags for Debian based image
|
||||
id: docker_meta_debian
|
||||
uses: docker/metadata-action@v3
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/nginx-proxy/nginx-proxy
|
||||
|
@ -42,37 +43,43 @@ jobs:
|
|||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
labels: |
|
||||
org.opencontainers.image.authors=Nicolas Duchon <nicolas.duchon@gmail.com> (@buchdag), Jason Wilder
|
||||
org.opencontainers.image.version=${{ env.GIT_DESCRIBE }}
|
||||
org.opencontainers.image.version=${{ steps.nginx-proxy_version.outputs.VERSION }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Retrieve docker-gen version
|
||||
id: docker-gen_version
|
||||
run: sed -n -e 's;^FROM nginxproxy/docker-gen:\([0-9.]*\).*;VERSION=\1;p' Dockerfile >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Build and push the Debian based image
|
||||
id: docker_build_debian
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
build-args: NGINX_PROXY_VERSION=${{ env.GIT_DESCRIBE }}
|
||||
build-args: |
|
||||
NGINX_PROXY_VERSION=${{ steps.nginx-proxy_version.outputs.VERSION }}
|
||||
DOCKER_GEN_VERSION=${{ steps.docker-gen_version.outputs.VERSION }}
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
push: true
|
||||
tags: ${{ steps.docker_meta_debian.outputs.tags }}
|
||||
|
@ -82,20 +89,21 @@ jobs:
|
|||
run: echo ${{ steps.docker_build_debian.outputs.digest }}
|
||||
|
||||
multiarch-build-alpine:
|
||||
name: Build and publish Alpine image
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Retrieve version
|
||||
run: echo "GIT_DESCRIBE=$(git describe --tags)" >> $GITHUB_ENV
|
||||
|
||||
- name: Retrieve nginx-proxy version
|
||||
id: nginx-proxy_version
|
||||
run: echo "VERSION=$(git describe --tags)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Get Docker tags for Alpine based image
|
||||
id: docker_meta_alpine
|
||||
uses: docker/metadata-action@v3
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/nginx-proxy/nginx-proxy
|
||||
|
@ -104,38 +112,44 @@ jobs:
|
|||
tags: |
|
||||
type=semver,suffix=-alpine,pattern={{version}}
|
||||
type=semver,suffix=-alpine,pattern={{major}}.{{minor}}
|
||||
type=raw,value=alpine,enable=${{ github.ref == 'refs/heads/main' }}
|
||||
type=raw,value=alpine,enable={{is_default_branch}}
|
||||
labels: |
|
||||
org.opencontainers.image.authors=Nicolas Duchon <nicolas.duchon@gmail.com> (@buchdag), Jason Wilder
|
||||
org.opencontainers.image.version=${{ env.GIT_DESCRIBE }}
|
||||
org.opencontainers.image.version=${{ steps.nginx-proxy_version.outputs.VERSION }}
|
||||
flavor: latest=false
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Retrieve docker-gen version
|
||||
id: docker-gen_version
|
||||
run: sed -n -e 's;^FROM nginxproxy/docker-gen:\([0-9.]*\).*;VERSION=\1;p' Dockerfile >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Build and push the Alpine based image
|
||||
id: docker_build_alpine
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.alpine
|
||||
build-args: NGINX_PROXY_VERSION=${{ env.GIT_DESCRIBE }}
|
||||
build-args: |
|
||||
NGINX_PROXY_VERSION=${{ steps.nginx-proxy_version.outputs.VERSION }}
|
||||
DOCKER_GEN_VERSION=${{ steps.docker-gen_version.outputs.VERSION }}
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
push: true
|
||||
tags: ${{ steps.docker_meta_alpine.outputs.tags }}
|
14
.github/workflows/test.yml
vendored
14
.github/workflows/test.yml
vendored
|
@ -3,13 +3,15 @@ name: Tests
|
|||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- 'LICENSE'
|
||||
- '**.md'
|
||||
- "LICENSE"
|
||||
- "**.md"
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'LICENSE'
|
||||
- '**.md'
|
||||
- "LICENSE"
|
||||
- "**.md"
|
||||
|
||||
jobs:
|
||||
unit:
|
||||
|
@ -22,10 +24,10 @@ jobs:
|
|||
base_docker_image: [alpine, debian]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
|
|
54
Dockerfile
54
Dockerfile
|
@ -1,60 +1,24 @@
|
|||
# setup build arguments for version of dependencies to use
|
||||
ARG DOCKER_GEN_VERSION=0.9.0
|
||||
ARG FOREGO_VERSION=v0.17.0
|
||||
FROM nginxproxy/docker-gen:0.10.4-debian AS docker-gen
|
||||
|
||||
# Use a specific version of golang to build both binaries
|
||||
FROM golang:1.20.6 as gobuilder
|
||||
|
||||
# Build docker-gen from scratch
|
||||
FROM gobuilder as dockergen
|
||||
|
||||
ARG DOCKER_GEN_VERSION
|
||||
|
||||
RUN git clone https://github.com/nginx-proxy/docker-gen \
|
||||
&& cd /go/docker-gen \
|
||||
&& git -c advice.detachedHead=false checkout $DOCKER_GEN_VERSION \
|
||||
&& go mod download \
|
||||
&& CGO_ENABLED=0 GOOS=linux go build -ldflags "-X main.buildVersion=${DOCKER_GEN_VERSION}" ./cmd/docker-gen \
|
||||
&& go clean -cache \
|
||||
&& mv docker-gen /usr/local/bin/ \
|
||||
&& cd - \
|
||||
&& rm -rf /go/docker-gen
|
||||
|
||||
# Build forego from scratch
|
||||
FROM gobuilder as forego
|
||||
|
||||
ARG FOREGO_VERSION
|
||||
|
||||
RUN git clone https://github.com/nginx-proxy/forego/ \
|
||||
&& cd /go/forego \
|
||||
&& git -c advice.detachedHead=false checkout $FOREGO_VERSION \
|
||||
&& go mod download \
|
||||
&& CGO_ENABLED=0 GOOS=linux go build -o forego . \
|
||||
&& go clean -cache \
|
||||
&& mv forego /usr/local/bin/ \
|
||||
&& cd - \
|
||||
&& rm -rf /go/forego
|
||||
FROM nginxproxy/forego:0.17.1-debian AS forego
|
||||
|
||||
# Build the final image
|
||||
FROM nginx:1.25.1
|
||||
FROM nginx:1.23.4
|
||||
|
||||
ARG NGINX_PROXY_VERSION
|
||||
# Add DOCKER_GEN_VERSION environment variable
|
||||
# Because some external projects rely on it
|
||||
ARG DOCKER_GEN_VERSION
|
||||
# Add DOCKER_GEN_VERSION environment variable because
|
||||
# acme-companion rely on it (but the actual value is not important)
|
||||
ARG DOCKER_GEN_VERSION="unknown"
|
||||
ENV NGINX_PROXY_VERSION=${NGINX_PROXY_VERSION} \
|
||||
DOCKER_GEN_VERSION=${DOCKER_GEN_VERSION} \
|
||||
DOCKER_HOST=unix:///tmp/docker.sock
|
||||
|
||||
# Install wget and install/updates certificates
|
||||
# Install/update certificates
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y -q --no-install-recommends \
|
||||
ca-certificates \
|
||||
wget \
|
||||
&& apt-get install -y -q --no-install-recommends ca-certificates \
|
||||
&& apt-get clean \
|
||||
&& rm -r /var/lib/apt/lists/*
|
||||
|
||||
|
||||
# Configure Nginx
|
||||
RUN echo "daemon off;" >> /etc/nginx/nginx.conf \
|
||||
&& sed -i 's/worker_processes 1/worker_processes auto/' /etc/nginx/nginx.conf \
|
||||
|
@ -63,7 +27,7 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf \
|
|||
|
||||
# Install Forego + docker-gen
|
||||
COPY --from=forego /usr/local/bin/forego /usr/local/bin/forego
|
||||
COPY --from=dockergen /usr/local/bin/docker-gen /usr/local/bin/docker-gen
|
||||
COPY --from=docker-gen /usr/local/bin/docker-gen /usr/local/bin/docker-gen
|
||||
|
||||
COPY network_internal.conf /etc/nginx/
|
||||
|
||||
|
|
|
@ -1,55 +1,23 @@
|
|||
# setup build arguments for version of dependencies to use
|
||||
ARG DOCKER_GEN_VERSION=0.9.0
|
||||
ARG FOREGO_VERSION=v0.17.0
|
||||
FROM nginxproxy/docker-gen:0.10.4 AS docker-gen
|
||||
|
||||
# Use a specific version of golang to build both binaries
|
||||
FROM golang:1.20.6-alpine as gobuilder
|
||||
RUN apk add --no-cache git musl-dev
|
||||
|
||||
# Build docker-gen from scratch
|
||||
FROM gobuilder as dockergen
|
||||
|
||||
ARG DOCKER_GEN_VERSION
|
||||
|
||||
RUN git clone https://github.com/nginx-proxy/docker-gen \
|
||||
&& cd /go/docker-gen \
|
||||
&& git -c advice.detachedHead=false checkout $DOCKER_GEN_VERSION \
|
||||
&& go mod download \
|
||||
&& CGO_ENABLED=0 go build -ldflags "-X main.buildVersion=${DOCKER_GEN_VERSION}" ./cmd/docker-gen \
|
||||
&& go clean -cache \
|
||||
&& mv docker-gen /usr/local/bin/ \
|
||||
&& cd - \
|
||||
&& rm -rf /go/docker-gen
|
||||
|
||||
# Build forego from scratch
|
||||
FROM gobuilder as forego
|
||||
|
||||
ARG FOREGO_VERSION
|
||||
|
||||
RUN git clone https://github.com/nginx-proxy/forego/ \
|
||||
&& cd /go/forego \
|
||||
&& git -c advice.detachedHead=false checkout $FOREGO_VERSION \
|
||||
&& go mod download \
|
||||
&& CGO_ENABLED=0 go build -o forego . \
|
||||
&& go clean -cache \
|
||||
&& mv forego /usr/local/bin/ \
|
||||
&& cd - \
|
||||
&& rm -rf /go/forego
|
||||
FROM nginxproxy/forego:0.17.1 AS forego
|
||||
|
||||
# Build the final image
|
||||
FROM nginx:1.25.1-alpine
|
||||
FROM nginx:1.23.4-alpine
|
||||
|
||||
ARG NGINX_PROXY_VERSION
|
||||
# Add DOCKER_GEN_VERSION environment variable
|
||||
# Because some external projects rely on it
|
||||
ARG DOCKER_GEN_VERSION
|
||||
# Add DOCKER_GEN_VERSION environment variable because
|
||||
# acme-companion rely on it (but the actual value is not important)
|
||||
ARG DOCKER_GEN_VERSION="unknown"
|
||||
ENV NGINX_PROXY_VERSION=${NGINX_PROXY_VERSION} \
|
||||
DOCKER_GEN_VERSION=${DOCKER_GEN_VERSION} \
|
||||
DOCKER_HOST=unix:///tmp/docker.sock
|
||||
|
||||
# Install wget and install/updates certificates
|
||||
# Install dependencies
|
||||
RUN apk add --no-cache --virtual .run-deps \
|
||||
ca-certificates bash wget openssl \
|
||||
bash \
|
||||
ca-certificates \
|
||||
openssl \
|
||||
&& update-ca-certificates
|
||||
|
||||
# Configure Nginx
|
||||
|
@ -60,7 +28,7 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf \
|
|||
|
||||
# Install Forego + docker-gen
|
||||
COPY --from=forego /usr/local/bin/forego /usr/local/bin/forego
|
||||
COPY --from=dockergen /usr/local/bin/docker-gen /usr/local/bin/docker-gen
|
||||
COPY --from=docker-gen /usr/local/bin/docker-gen /usr/local/bin/docker-gen
|
||||
|
||||
COPY network_internal.conf /etc/nginx/
|
||||
|
||||
|
|
6
Makefile
6
Makefile
|
@ -3,13 +3,13 @@
|
|||
|
||||
|
||||
build-webserver:
|
||||
docker build -t web test/requirements/web
|
||||
docker build --pull -t web test/requirements/web
|
||||
|
||||
build-nginx-proxy-test-debian:
|
||||
docker build --build-arg NGINX_PROXY_VERSION="test" -t nginxproxy/nginx-proxy:test .
|
||||
docker build --pull --build-arg NGINX_PROXY_VERSION="test" -t nginxproxy/nginx-proxy:test .
|
||||
|
||||
build-nginx-proxy-test-alpine:
|
||||
docker build --build-arg NGINX_PROXY_VERSION="test" -f Dockerfile.alpine -t nginxproxy/nginx-proxy:test .
|
||||
docker build --pull --build-arg NGINX_PROXY_VERSION="test" -f Dockerfile.alpine -t nginxproxy/nginx-proxy:test .
|
||||
|
||||
test-debian: build-webserver build-nginx-proxy-test-debian
|
||||
test/pytest.sh
|
||||
|
|
160
README.md
160
README.md
|
@ -8,7 +8,7 @@ it to the docker hub automatically. See `.github/workflows/docker_push.yml` for
|
|||
# Original Readme
|
||||
[](https://github.com/nginx-proxy/nginx-proxy/actions/workflows/test.yml)
|
||||
[](https://github.com/nginx-proxy/nginx-proxy/releases)
|
||||

|
||||

|
||||
[](https://hub.docker.com/r/nginxproxy/nginx-proxy "Click to view the image on Docker Hub")
|
||||
[](https://hub.docker.com/r/nginxproxy/nginx-proxy 'DockerHub')
|
||||
[](https://hub.docker.com/r/nginxproxy/nginx-proxy 'DockerHub')
|
||||
|
@ -130,7 +130,7 @@ You can also use wildcards at the beginning and the end of host name, like `*.ba
|
|||
You can have multiple containers proxied by the same `VIRTUAL_HOST` by adding a `VIRTUAL_PATH` environment variable containing the absolute path to where the container should be mounted. For example with `VIRTUAL_HOST=foo.example.com` and `VIRTUAL_PATH=/api/v2/service`, then requests to http://foo.example.com/api/v2/service will be routed to the container. If you wish to have a container serve the root while other containers serve other paths, give the root container a `VIRTUAL_PATH` of `/`. Unmatched paths will be served by the container at `/` or will return the default nginx error page if no container has been assigned `/`.
|
||||
It is also possible to specify multiple paths with regex locations like `VIRTUAL_PATH=~^/(app1|alternative1)/`. For further details see the nginx documentation on location blocks. This is not compatible with `VIRTUAL_DEST`.
|
||||
|
||||
The full request URI will be forwarded to the serving container in the `X-Forwarded-Path` header.
|
||||
The full request URI will be forwarded to the serving container in the `X-Original-URI` header.
|
||||
|
||||
**NOTE**: Your application needs to be able to generate links starting with `VIRTUAL_PATH`. This can be achieved by it being natively on this path or having an option to prepend this path. The application does not need to expect this path in the request.
|
||||
|
||||
|
@ -160,10 +160,17 @@ The filename of the previous example would be `example.tld_8610f6c344b4096614eab
|
|||
|
||||
This environment variable of the nginx proxy container can be used to customize the return error page if no matching path is found. Furthermore it is possible to use anything which is compatible with the `return` statement of nginx.
|
||||
|
||||
For example `DEFAUL_ROOT=418` will return a 418 error page instead of the normal 404 one.
|
||||
Another example is `DEFAULT_ROOT="301 https://github.com/nginx-proxy/nginx-proxy/blob/main/README.md"` which would redirect an invalid request to this documentation.
|
||||
Nginx variables such as $scheme, $host, and $request_uri can be used. However, care must be taken to make sure the $ signs are escaped properly.
|
||||
If you want to use `301 $scheme://$host/myapp1$request_uri` you should use:
|
||||
Exception: If this is set to the string `none`, no default `location /` directive will be generated. This makes it possible for you to provide your own `location /` directive in your [`/etc/nginx/vhost.d/VIRTUAL_HOST`](#per-virtual_host) or [`/etc/nginx/vhost.d/default`](#per-virtual_host-default-configuration) files.
|
||||
|
||||
If unspecified, `DEFAULT_ROOT` defaults to `404`.
|
||||
|
||||
Examples (YAML syntax):
|
||||
|
||||
* `DEFAULT_ROOT: "none"` prevents `nginx-proxy` from generating a default `location /` directive.
|
||||
* `DEFAULT_ROOT: "418"` returns a 418 error page instead of the normal 404 one.
|
||||
* `DEFAULT_ROOT: "301 https://github.com/nginx-proxy/nginx-proxy/blob/main/README.md"` redirects the client to this documentation.
|
||||
|
||||
Nginx variables such as `$scheme`, `$host`, and `$request_uri` can be used. However, care must be taken to make sure the `$` signs are escaped properly. For example, if you want to use `301 $scheme://$host/myapp1$request_uri` you should use:
|
||||
|
||||
* Bash: `DEFAULT_ROOT='301 $scheme://$host/myapp1$request_uri'`
|
||||
* Docker Compose yaml: `- DEFAULT_ROOT: 301 $$scheme://$$host/myapp1$$request_uri`
|
||||
|
@ -228,6 +235,11 @@ If you would like to connect to FastCGI backend, set `VIRTUAL_PROTO=fastcgi` on
|
|||
|
||||
If you use fastcgi,you can set `VIRTUAL_ROOT=xxx` for your root directory
|
||||
|
||||
### Custom log format
|
||||
|
||||
If you want to use a custom log format, you can set `LOG_FORMAT=xxx` on the proxy container.
|
||||
|
||||
With docker compose take care to escape the `$` character with `$$` to avoid variable interpolation. Example: `$remote_addr` becomes `$$remote_addr`.
|
||||
|
||||
### Default Host
|
||||
|
||||
|
@ -343,10 +355,9 @@ Note that the `Mozilla-Old` policy should use a 1024 bits DH key for compatibili
|
|||
|
||||
The default behavior for the proxy when port 80 and 443 are exposed is as follows:
|
||||
|
||||
* If a container has a usable cert, port 80 will redirect to 443 for that container so that HTTPS is always preferred when available.
|
||||
* If the container does not have a usable cert, a 503 will be returned.
|
||||
|
||||
Note that in the latter case, a browser may get an connection error as no certificate is available to establish a connection. A self-signed or generic cert named `default.crt` and `default.key` will allow a client browser to make a SSL connection (likely w/ a warning) and subsequently receive a 500.
|
||||
* If a virtual host has a usable cert, port 80 will redirect to 443 for that virtual host so that HTTPS is always preferred when available.
|
||||
* If the virtual host does not have a usable cert, but `default.crt` and `default.key` exist, those will be used as the virtual host's certificate and the client browser will receive a 500 error.
|
||||
* If the virtual host does not have a usable cert, and `default.crt` and `default.key` do not exist, TLS negotiation will fail (see [Missing Certificate](#missing-certificate) below).
|
||||
|
||||
To serve traffic in both SSL and non-SSL modes without redirecting to SSL, you can include the environment variable `HTTPS_METHOD=noredirect` (the default is `HTTPS_METHOD=redirect`). You can also disable the non-SSL site entirely with `HTTPS_METHOD=nohttp`, or disable the HTTPS site with `HTTPS_METHOD=nohttps`. `HTTPS_METHOD` can be specified on each container for which you want to override the default behavior or on the proxy container to set it globally. If `HTTPS_METHOD=noredirect` is used, Strict Transport Security (HSTS) is disabled to prevent HTTPS users from being redirected by the client. If you cannot get to the HTTP site after changing this setting, your browser has probably cached the HSTS policy and is automatically redirecting you back to HTTPS. You will need to clear your browser's HSTS cache or use an incognito window / different browser.
|
||||
|
||||
|
@ -354,6 +365,31 @@ By default, [HTTP Strict Transport Security (HSTS)](https://developer.mozilla.or
|
|||
|
||||
*WARNING*: HSTS will force your users to visit the HTTPS version of your site for the `max-age` time - even if they type in `http://` manually. The only way to get to an HTTP site after receiving an HSTS response is to clear your browser's HSTS cache.
|
||||
|
||||
#### Missing Certificate
|
||||
|
||||
If HTTPS is enabled for a virtual host but its certificate is missing, nginx-proxy will configure nginx to use the default certificate (`default.crt` with `default.key`) and return a 500 error.
|
||||
|
||||
If the default certificate is also missing, nginx-proxy will configure nginx to accept HTTPS connections but fail the TLS negotiation. Client browsers will render a TLS error page. As of March 2023, web browsers display the following error messages:
|
||||
|
||||
* Chrome:
|
||||
|
||||
> This site can't provide a secure connection
|
||||
>
|
||||
> example.test sent an invalid response.
|
||||
>
|
||||
> Try running Connectivity Diagnostics.
|
||||
>
|
||||
> `ERR_SSL_PROTOCOL_ERROR`
|
||||
|
||||
* Firefox:
|
||||
|
||||
> Secure Connection Failed
|
||||
>
|
||||
> An error occurred during a connection to example.test.
|
||||
> Peer reports it experienced an internal error.
|
||||
>
|
||||
> Error code: `SSL_ERROR_INTERNAL_ERROR_ALERT` "TLS error".
|
||||
|
||||
### Basic Authentication Support
|
||||
|
||||
In order to be able to secure your virtual host, you have to create a file named as its equivalent VIRTUAL_HOST variable on directory
|
||||
|
@ -369,6 +405,72 @@ docker run -d -p 80:80 -p 443:443 \
|
|||
|
||||
You'll need apache2-utils on the machine where you plan to create the htpasswd file. Follow these [instructions](http://httpd.apache.org/docs/2.2/programs/htpasswd.html)
|
||||
|
||||
### Upstream (Backend) Server HTTP Load Balancing Support
|
||||
|
||||
> **Warning**
|
||||
> This feature is experimental. The behavior may change (or the feature may be removed entirely) without warning in a future release, even if the release is not a new major version. If you use this feature, or if you would like to use this feature but you require changes to it first, please [provide feedback in #2195](https://github.com/nginx-proxy/nginx-proxy/discussions/2195). Once we have collected enough feedback we will promote this feature to officially supported.
|
||||
|
||||
If you have multiple containers with the same `VIRTUAL_HOST` and `VIRTUAL_PATH` settings, nginx will spread the load across all of them. To change the load balancing algorithm from nginx's default (round-robin), set the `com.github.nginx-proxy.nginx-proxy.loadbalance` label on one or more of your application containers to the desired load balancing directive. See the [`ngx_http_upstream_module` documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html) for available directives.
|
||||
|
||||
> **Note**
|
||||
> * Don't forget the terminating semicolon (`;`).
|
||||
> * If you are using Docker Compose, remember to escape any dollar sign (`$`) characters (`$` becomes `$$`).
|
||||
|
||||
Docker Compose example:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
nginx-proxy:
|
||||
image: nginxproxy/nginx-proxy
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
environment:
|
||||
HTTPS_METHOD: nohttps
|
||||
myapp:
|
||||
image: jwilder/whoami
|
||||
expose:
|
||||
- "8000"
|
||||
environment:
|
||||
VIRTUAL_HOST: myapp.example
|
||||
VIRTUAL_PORT: "8000"
|
||||
labels:
|
||||
com.github.nginx-proxy.nginx-proxy.loadbalance: "hash $$remote_addr;"
|
||||
deploy:
|
||||
replicas: 4
|
||||
```
|
||||
|
||||
### Upstream (Backend) Server HTTP Keep-Alive Support
|
||||
|
||||
> **Warning**
|
||||
> This feature is experimental. The behavior may change (or the feature may be removed entirely) without warning in a future release, even if the release is not a new major version. If you use this feature, or if you would like to use this feature but you require changes to it first, please [provide feedback in #2194](https://github.com/nginx-proxy/nginx-proxy/discussions/2194). Once we have collected enough feedback we will promote this feature to officially supported.
|
||||
|
||||
To enable HTTP keep-alive between `nginx-proxy` and a backend server, set the `com.github.nginx-proxy.nginx-proxy.keepalive` label on the server's container to the desired maximum number of idle connections. See the [nginx keepalive documentation](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) and the [Docker label documentation](https://docs.docker.com/config/labels-custom-metadata/) for details.
|
||||
|
||||
### Headers
|
||||
|
||||
By default, `nginx-proxy` forwards all incoming request headers from the client to the backend server unmodified, with the following exceptions:
|
||||
|
||||
* `Connection`: Set to `upgrade` if the client sets the `Upgrade` header, otherwise set to `close`. (Keep-alive between `nginx-proxy` and the backend server is not supported.)
|
||||
* `Proxy`: Always removed if present. This prevents attackers from using the so-called [httpoxy attack](http://httpoxy.org). There is no legitimate reason for a client to send this header, and there are many vulnerable languages / platforms (`CVE-2016-5385`, `CVE-2016-5386`, `CVE-2016-5387`, `CVE-2016-5388`, `CVE-2016-1000109`, `CVE-2016-1000110`, `CERT-VU#797896`).
|
||||
* `X-Real-IP`: Set to the client's IP address.
|
||||
* `X-Forwarded-For`: The client's IP address is appended to the value provided by the client. (If the client did not provide this header, it is set to the client's IP address.)
|
||||
* `X-Forwarded-Host`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to the value of the `Host` header provided by the client. Otherwise, the header is forwarded to the backend server unmodified.
|
||||
* `X-Forwarded-Proto`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to `http` for plain HTTP connections and `https` for TLS connections. Otherwise, the header is forwarded to the backend server unmodified.
|
||||
* `X-Forwarded-Ssl`: Set to `on` if the `X-Forwarded-Proto` header sent to the backend server is `https`, otherwise set to `off`.
|
||||
* `X-Forwarded-Port`: If the client did not provide this header or if the `TRUST_DOWNSTREAM_PROXY` environment variable is set to `false` (see below), this is set to the port of the server that accepted the client's request. Otherwise, the header is forwarded to the backend server unmodified.
|
||||
* `X-Original-URI`: Set to the original request URI.
|
||||
|
||||
#### Trusting Downstream Proxy Headers
|
||||
|
||||
For legacy compatibility reasons, `nginx-proxy` forwards any client-supplied `X-Forwarded-Proto` (which affects the value of `X-Forwarded-Ssl`), `X-Forwarded-Host`, and `X-Forwarded-Port` headers unchecked and unmodified. To prevent malicious clients from spoofing the protocol, hostname, or port that is perceived by your backend server, you are encouraged to set the `TRUST_DOWNSTREAM_PROXY` value to `false` if:
|
||||
|
||||
* you do not operate a second reverse proxy downstream of `nginx-proxy`, or
|
||||
* you do operate a second reverse proxy downstream of `nginx-proxy` but that proxy forwards those headers unchecked from untrusted clients.
|
||||
|
||||
The default for `TRUST_DOWNSTREAM_PROXY` may change to `false` in a future version of `nginx-proxy`. If you require it to be enabled, you are encouraged to explicitly set it to `true` to avoid compatibility problems when upgrading.
|
||||
|
||||
### Custom Nginx Configuration
|
||||
|
||||
If you need to configure Nginx beyond what is possible using environment variables, you can provide custom configuration files on either a proxy-wide or per-`VIRTUAL_HOST` basis.
|
||||
|
@ -386,10 +488,11 @@ proxy_set_header Upgrade $http_upgrade;
|
|||
proxy_set_header Connection $proxy_connection;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Host $proxy_x_forwarded_host;
|
||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
||||
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
|
||||
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
|
||||
proxy_set_header X-Forwarded-Path $request_uri;
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
|
||||
# Mitigate httpoxy attack (see README for details)
|
||||
proxy_set_header Proxy "";
|
||||
|
@ -397,8 +500,6 @@ proxy_set_header Proxy "";
|
|||
|
||||
***NOTE***: If you provide this file it will replace the defaults; you may want to check the .tmpl file to make sure you have all of the needed options.
|
||||
|
||||
***NOTE***: The default configuration blocks the `Proxy` HTTP request header from being sent to downstream servers. This prevents attackers from using the so-called [httpoxy attack](http://httpoxy.org). There is no legitimate reason for a client to send this header, and there are many vulnerable languages / platforms (`CVE-2016-5385`, `CVE-2016-5386`, `CVE-2016-5387`, `CVE-2016-5388`, `CVE-2016-1000109`, `CVE-2016-1000110`, `CERT-VU#797896`).
|
||||
|
||||
#### Proxy-wide
|
||||
|
||||
To add settings on a proxy-wide basis, add your configuration file under `/etc/nginx/conf.d` using a name ending in `.conf`.
|
||||
|
@ -465,6 +566,32 @@ ln -s /path/to/vhost.d/www.example.com /path/to/vhost.d/example.com
|
|||
|
||||
If you want most of your virtual hosts to use a default single `location` block configuration and then override on a few specific ones, add those settings to the `/etc/nginx/vhost.d/default_location` file. This file will be used on any virtual host which does not have a `/etc/nginx/vhost.d/{VIRTUAL_HOST}_location` file associated with it.
|
||||
|
||||
#### Overriding `location` blocks
|
||||
|
||||
The `${VIRTUAL_HOST}_${PATH_HASH}_location`, `${VIRTUAL_HOST}_location`, and `default_location` files documented above make it possible to *augment* the generated [`location` block(s)](https://nginx.org/en/docs/http/ngx_http_core_module.html#location) in a virtual host. In some circumstances, you may need to *completely override* the `location` block for a particular combination of virtual host and path. To do this, create a file whose name follows this pattern:
|
||||
|
||||
```
|
||||
/etc/nginx/vhost.d/${VIRTUAL_HOST}_${PATH_HASH}_location_override
|
||||
```
|
||||
|
||||
where `${VIRTUAL_HOST}` is the name of the virtual host (the `VIRTUAL_HOST` environment variable) and `${PATH_HASH}` is the SHA-1 hash of the path, as [described above](#per-virtual_path-location-configuration).
|
||||
|
||||
For convenience, the `_${PATH_HASH}` part can be omitted if the path is `/`:
|
||||
|
||||
```
|
||||
/etc/nginx/vhost.d/${VIRTUAL_HOST}_location_override
|
||||
```
|
||||
|
||||
When an override file exists, the `location` block that is normally created by `nginx-proxy` is not generated. Instead, the override file is included via the [nginx `include` directive](https://nginx.org/en/docs/ngx_core_module.html#include).
|
||||
|
||||
You are responsible for providing a suitable `location` block in your override file as required for your service. By default, `nginx-proxy` uses the `VIRTUAL_HOST` name as the upstream name for your application's Docker container; see [here](#unhashed-vs-sha1-upstream-names) for details. As an example, if your container has a `VIRTUAL_HOST` value of `app.example.com`, then to override the location block for `/` you would create a file named `/etc/nginx/vhost.d/app.example.com_location_override` that contains something like this:
|
||||
|
||||
```
|
||||
location / {
|
||||
proxy_pass http://app.example.com;
|
||||
}
|
||||
```
|
||||
|
||||
#### Per-VIRTUAL_HOST `server_tokens` configuration
|
||||
Per virtual-host `servers_tokens` directive can be configured by passing appropriate value to the `SERVER_TOKENS` environment variable. Please see the [nginx http_core module configuration](https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens) for more details.
|
||||
|
||||
|
@ -476,12 +603,13 @@ Please note that using regular expressions in `VIRTUAL_HOST` will always result
|
|||
|
||||
### Troubleshooting
|
||||
|
||||
In case you can't access your VIRTUAL_HOST, set `DEBUG=true` in the client container's environment and have a look at the generated nginx configuration file `/etc/nginx/conf.d/default.conf`:
|
||||
If you can't access your `VIRTUAL_HOST`, inspect the generated nginx configuration:
|
||||
|
||||
```console
|
||||
docker exec <nginx-proxy-instance> cat /etc/nginx/conf.d/default.conf
|
||||
docker exec <nginx-proxy-instance> nginx -T
|
||||
```
|
||||
Especially at `upstream` definition blocks which should look like:
|
||||
|
||||
Pay attention to the `upstream` definition blocks, which should look like this:
|
||||
|
||||
```Nginx
|
||||
# foo.example.com
|
||||
|
|
|
@ -109,6 +109,13 @@ if [[ $* == 'forego start -r' ]]; then
|
|||
_resolvers
|
||||
|
||||
_setup_dhparam
|
||||
|
||||
if [ -z "${TRUST_DOWNSTREAM_PROXY}" ]; then
|
||||
cat >&2 <<-EOT
|
||||
Warning: TRUST_DOWNSTREAM_PROXY is not set; defaulting to "true". For security, you should explicitly set TRUST_DOWNSTREAM_PROXY to "false" if there is not a trusted reverse proxy in front of this proxy.
|
||||
Warning: The default value of TRUST_DOWNSTREAM_PROXY might change to "false" in a future version of nginx-proxy. If you require TRUST_DOWNSTREAM_PROXY to be enabled, explicitly set it to "true".
|
||||
EOT
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
|
|
982
nginx.tmpl
982
nginx.tmpl
File diff suppressed because it is too large
Load diff
101
test/conftest.py
101
test/conftest.py
|
@ -322,31 +322,28 @@ def wait_for_nginxproxy_to_be_ready():
|
|||
logging.debug("nginx-proxy ready")
|
||||
break
|
||||
|
||||
def find_docker_compose_file(request):
|
||||
"""
|
||||
helper for fixture functions to figure out the name of the docker-compose file to consider.
|
||||
|
||||
- if the test module provides a `docker_compose_file` variable, take that
|
||||
- else, if a yaml file exists with the same name as the test module (but for the `.yml` extension), use that
|
||||
- otherwise use `docker-compose.yml`.
|
||||
@pytest.fixture
|
||||
def docker_compose_file(request):
|
||||
"""Fixture naming the docker-compose file to consider.
|
||||
|
||||
If a YAML file exists with the same name as the test module (with the `.py` extension replaced
|
||||
with `.yml` or `.yaml`), use that. Otherwise, use `docker-compose.yml` in the same directory
|
||||
as the test module.
|
||||
|
||||
Tests can override this fixture to specify a custom location.
|
||||
"""
|
||||
test_module_dir = os.path.dirname(request.module.__file__)
|
||||
yml_file = os.path.join(test_module_dir, request.module.__name__ + '.yml')
|
||||
yaml_file = os.path.join(test_module_dir, request.module.__name__ + '.yaml')
|
||||
default_file = os.path.join(test_module_dir, 'docker-compose.yml')
|
||||
|
||||
docker_compose_file_module_variable = getattr(request.module, "docker_compose_file", None)
|
||||
if docker_compose_file_module_variable is not None:
|
||||
docker_compose_file = os.path.join( test_module_dir, docker_compose_file_module_variable)
|
||||
if not os.path.isfile(docker_compose_file):
|
||||
raise ValueError(f"docker compose file {docker_compose_file!r} could not be found. Check your test module `docker_compose_file` variable value.")
|
||||
if os.path.isfile(yml_file):
|
||||
docker_compose_file = yml_file
|
||||
elif os.path.isfile(yaml_file):
|
||||
docker_compose_file = yaml_file
|
||||
else:
|
||||
if os.path.isfile(yml_file):
|
||||
docker_compose_file = yml_file
|
||||
elif os.path.isfile(yaml_file):
|
||||
docker_compose_file = yaml_file
|
||||
else:
|
||||
docker_compose_file = default_file
|
||||
docker_compose_file = default_file
|
||||
|
||||
if not os.path.isfile(docker_compose_file):
|
||||
logging.error("Could not find any docker-compose file named either '{0}.yml', '{0}.yaml' or 'docker-compose.yml'".format(request.module.__name__))
|
||||
|
@ -419,34 +416,72 @@ def connect_to_all_networks():
|
|||
return [connect_to_network(network) for network in networks]
|
||||
|
||||
|
||||
class DockerComposer(contextlib.AbstractContextManager):
|
||||
def __init__(self):
|
||||
self._docker_compose_file = None
|
||||
|
||||
def __exit__(self, *exc_info):
|
||||
self._down()
|
||||
|
||||
def _down(self):
|
||||
if self._docker_compose_file is None:
|
||||
return
|
||||
for network in self._networks:
|
||||
disconnect_from_network(network)
|
||||
docker_compose_down(self._docker_compose_file)
|
||||
self._docker_compose_file = None
|
||||
|
||||
def compose(self, docker_compose_file):
|
||||
if docker_compose_file == self._docker_compose_file:
|
||||
return
|
||||
self._down()
|
||||
if docker_compose_file is None:
|
||||
return
|
||||
remove_all_containers()
|
||||
docker_compose_up(docker_compose_file)
|
||||
self._networks = connect_to_all_networks()
|
||||
wait_for_nginxproxy_to_be_ready()
|
||||
time.sleep(3) # give time to containers to be ready
|
||||
self._docker_compose_file = docker_compose_file
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Py.test fixtures
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def docker_compose(request):
|
||||
"""
|
||||
pytest fixture providing containers described in a docker compose file. After the tests, remove the created containers
|
||||
|
||||
A custom docker compose file name can be defined in a variable named `docker_compose_file`.
|
||||
@pytest.fixture(scope="module")
|
||||
def docker_composer():
|
||||
with DockerComposer() as d:
|
||||
yield d
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ca_root_certificate():
|
||||
return CA_ROOT_CERTIFICATE
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def monkey_patched_dns():
|
||||
original_dns_resolver = monkey_patch_urllib_dns_resolver()
|
||||
yield
|
||||
restore_urllib_dns_resolver(original_dns_resolver)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def docker_compose(monkey_patched_dns, docker_composer, docker_compose_file):
|
||||
"""Ensures containers described in a docker compose file are started.
|
||||
|
||||
A custom docker compose file name can be specified by overriding the `docker_compose_file`
|
||||
fixture.
|
||||
|
||||
Also, in the case where pytest is running from a docker container, this fixture makes sure
|
||||
our container will be attached to all the docker networks.
|
||||
"""
|
||||
docker_compose_file = find_docker_compose_file(request)
|
||||
original_dns_resolver = monkey_patch_urllib_dns_resolver()
|
||||
remove_all_containers()
|
||||
docker_compose_up(docker_compose_file)
|
||||
networks = connect_to_all_networks()
|
||||
wait_for_nginxproxy_to_be_ready()
|
||||
time.sleep(3) # give time to containers to be ready
|
||||
docker_composer.compose(docker_compose_file)
|
||||
yield docker_client
|
||||
for network in networks:
|
||||
disconnect_from_network(network)
|
||||
docker_compose_down(docker_compose_file)
|
||||
restore_urllib_dns_resolver(original_dns_resolver)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
###############################################################################
|
||||
# #
|
||||
# This script is meant to run the test suite from a Docker container. #
|
||||
|
@ -9,17 +9,20 @@
|
|||
###############################################################################
|
||||
|
||||
# Returns the absolute directory path to this script
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
ARGS=("$@")
|
||||
TESTDIR=$(cd "${0%/*}" && pwd) || exit 1
|
||||
DIR=$(cd "${TESTDIR}/.." && pwd) || exit 1
|
||||
|
||||
# check requirements
|
||||
echo "> Building nginx-proxy-tester image..."
|
||||
docker build -t nginx-proxy-tester -f "${DIR}/requirements/Dockerfile-nginx-proxy-tester" "${DIR}/requirements"
|
||||
docker build --pull -t nginx-proxy-tester \
|
||||
-f "${TESTDIR}/requirements/Dockerfile-nginx-proxy-tester" \
|
||||
"${TESTDIR}/requirements" \
|
||||
|| exit 1
|
||||
|
||||
# run the nginx-proxy-tester container setting the correct value for the working dir in order for
|
||||
# run the nginx-proxy-tester container setting the correct value for the working dir in order for
|
||||
# docker-compose to work properly when run from within that container.
|
||||
exec docker run --rm -it --name "nginx-proxy-pytest" \
|
||||
--volume "/var/run/docker.sock:/var/run/docker.sock" \
|
||||
--volume "${DIR}:${DIR}" \
|
||||
--workdir "${DIR}" \
|
||||
nginx-proxy-tester "${ARGS[@]}"
|
||||
--workdir "${TESTDIR}" \
|
||||
nginx-proxy-tester "$@"
|
||||
|
|
|
@ -2,4 +2,4 @@ backoff==2.2.1
|
|||
docker-compose==1.29.2
|
||||
docker==6.1.3
|
||||
pytest==7.4.0
|
||||
requests==2.29.0
|
||||
requests==2.30.0
|
||||
|
|
|
@ -10,8 +10,6 @@ web:
|
|||
reverseproxy:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
container_name: reverseproxy
|
||||
environment:
|
||||
DEBUG: "true"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./tmp_certs:/etc/nginx/certs:ro
|
||||
- ./tmp_certs:/etc/nginx/certs:ro
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
import pytest
|
||||
import re
|
||||
|
||||
def test_debug_info_is_present_in_nginx_generated_conf(docker_compose, nginxproxy):
|
||||
conf = nginxproxy.get_conf().decode('ASCII')
|
||||
assert re.search(r"# Exposed ports: \[\{\d+\.\d+\.\d+\.\d+\s+80\s+tcp \} \{\d+\.\d+\.\d+\.\d+\s+81\s+tcp \}\]", conf) or \
|
||||
re.search(r"# Exposed ports: \[\{\d+\.\d+\.\d+\.\d+\s+81\s+tcp \} \{\d+\.\d+\.\d+\.\d+\s+80\s+tcp \}\]", conf)
|
||||
assert re.search(r"# Exposed ports: \[\{\d+\.\d+\.\d+\.\d+\s+82\s+tcp \} \{\d+\.\d+\.\d+\.\d+\s+83\s+tcp \}\]", conf) or \
|
||||
re.search(r"# Exposed ports: \[\{\d+\.\d+\.\d+\.\d+\s+83\s+tcp \} \{\d+\.\d+\.\d+\.\d+\s+82\s+tcp \}\]", conf)
|
||||
assert "# Default virtual port: 80" in conf
|
||||
assert "# VIRTUAL_PORT: 82" in conf
|
||||
assert conf.count("# /!\\ Virtual port not exposed") == 1
|
|
@ -1,26 +0,0 @@
|
|||
web1:
|
||||
image: web
|
||||
expose:
|
||||
- "80"
|
||||
- "81"
|
||||
environment:
|
||||
WEB_PORTS: "80 81"
|
||||
VIRTUAL_HOST: "web1.nginx-proxy.tld"
|
||||
VIRTUAL_PORT: "82"
|
||||
|
||||
web2:
|
||||
image: web
|
||||
expose:
|
||||
- "82"
|
||||
- "83"
|
||||
environment:
|
||||
WEB_PORTS: "82 83"
|
||||
VIRTUAL_HOST: "web2.nginx-proxy.tld"
|
||||
VIRTUAL_PORT: "82"
|
||||
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
environment:
|
||||
DEBUG: "true"
|
|
@ -1,8 +0,0 @@
|
|||
import pytest
|
||||
import re
|
||||
|
||||
def test_debug_info_is_present_in_nginx_generated_conf(docker_compose, nginxproxy):
|
||||
conf = nginxproxy.get_conf().decode('ASCII')
|
||||
assert re.search(r"# Exposed ports: \[\{\d+\.\d+\.\d+\.\d+\s+80\s+tcp \} \{\d+\.\d+\.\d+\.\d+\s+81\s+tcp \}\]", conf) or \
|
||||
re.search(r"# Exposed ports: \[\{\d+\.\d+\.\d+\.\d+\s+81\s+tcp \} \{\d+\.\d+\.\d+\.\d+\s+80\s+tcp \}\]", conf)
|
||||
assert conf.count("# Exposed ports: [{") == 1
|
|
@ -1,25 +0,0 @@
|
|||
web1:
|
||||
image: web
|
||||
expose:
|
||||
- "80"
|
||||
- "81"
|
||||
environment:
|
||||
WEB_PORTS: "80 81"
|
||||
VIRTUAL_HOST: "web1.nginx-proxy.tld"
|
||||
VIRTUAL_PORT: "82"
|
||||
DEBUG: "true"
|
||||
|
||||
web2:
|
||||
image: web
|
||||
expose:
|
||||
- "82"
|
||||
- "83"
|
||||
environment:
|
||||
WEB_PORTS: "82 83"
|
||||
VIRTUAL_HOST: "web2.nginx-proxy.tld"
|
||||
VIRTUAL_PORT: "82"
|
||||
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
8
test/test_default-root-none.py
Normal file
8
test/test_default-root-none.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
import re
|
||||
|
||||
|
||||
def test_default_root_none(docker_compose, nginxproxy):
|
||||
conf = nginxproxy.get_conf().decode()
|
||||
assert re.search(r"(?m)^\s*location\s+/path\s+\{", conf)
|
||||
assert not re.search(r"(?m)^\s*location\s+/\s+\{", conf)
|
||||
|
15
test/test_default-root-none.yml
Normal file
15
test/test_default-root-none.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
services:
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
environment:
|
||||
DEFAULT_ROOT: none
|
||||
web:
|
||||
image: web
|
||||
expose:
|
||||
- "80"
|
||||
environment:
|
||||
WEB_PORTS: "80"
|
||||
VIRTUAL_HOST: web.nginx-proxy.test
|
||||
VIRTUAL_PATH: /path
|
|
@ -1,41 +1,9 @@
|
|||
import os
|
||||
import docker
|
||||
import logging
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def nginx_tmpl():
|
||||
"""
|
||||
pytest fixture which extracts the the nginx config template from
|
||||
the nginxproxy/nginx-proxy:test image
|
||||
"""
|
||||
script_dir = os.path.dirname(__file__)
|
||||
logging.info("extracting nginx.tmpl from nginxproxy/nginx-proxy:test")
|
||||
docker_client = docker.from_env()
|
||||
print(
|
||||
docker_client.containers.run(
|
||||
image="nginxproxy/nginx-proxy:test",
|
||||
remove=True,
|
||||
volumes=["{current_dir}:{current_dir}".format(current_dir=script_dir)],
|
||||
entrypoint="sh",
|
||||
command='-xc "cp /app/nginx.tmpl {current_dir} && chmod 777 {current_dir}/nginx.tmpl"'.format(
|
||||
current_dir=script_dir
|
||||
),
|
||||
stderr=True,
|
||||
)
|
||||
)
|
||||
yield
|
||||
logging.info("removing nginx.tmpl")
|
||||
os.remove(os.path.join(script_dir, "nginx.tmpl"))
|
||||
|
||||
|
||||
def test_unknown_virtual_host_is_503(nginx_tmpl, docker_compose, nginxproxy):
|
||||
def test_unknown_virtual_host_is_503(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://unknown.nginx.container.docker/")
|
||||
assert r.status_code == 503
|
||||
|
||||
|
||||
def test_forwards_to_whoami(nginx_tmpl, docker_compose, nginxproxy):
|
||||
def test_forwards_to_whoami(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://whoami.nginx.container.docker/")
|
||||
assert r.status_code == 200
|
||||
whoami_container = docker_compose.containers.get("whoami")
|
||||
|
|
|
@ -14,7 +14,7 @@ services:
|
|||
- nginx
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
|
||||
- ../../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
|
||||
|
||||
web:
|
||||
image: web
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import os
|
||||
import docker
|
||||
import logging
|
||||
import pytest
|
||||
import re
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
|
||||
|
@ -13,38 +10,12 @@ pytestmark = pytest.mark.skipif(
|
|||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def nginx_tmpl():
|
||||
"""
|
||||
pytest fixture which extracts the the nginx config template from
|
||||
the nginxproxy/nginx-proxy:test image
|
||||
"""
|
||||
script_dir = os.path.dirname(__file__)
|
||||
logging.info("extracting nginx.tmpl from nginxproxy/nginx-proxy:test")
|
||||
docker_client = docker.from_env()
|
||||
print(
|
||||
docker_client.containers.run(
|
||||
image="nginxproxy/nginx-proxy:test",
|
||||
remove=True,
|
||||
volumes=["{current_dir}:{current_dir}".format(current_dir=script_dir)],
|
||||
entrypoint="sh",
|
||||
command='-xc "cp /app/nginx.tmpl {current_dir} && chmod 777 {current_dir}/nginx.tmpl"'.format(
|
||||
current_dir=script_dir
|
||||
),
|
||||
stderr=True,
|
||||
)
|
||||
)
|
||||
yield
|
||||
logging.info("removing nginx.tmpl")
|
||||
os.remove(os.path.join(script_dir, "nginx.tmpl"))
|
||||
|
||||
|
||||
def test_unknown_virtual_host_is_503(nginx_tmpl, docker_compose, nginxproxy):
|
||||
def test_unknown_virtual_host_is_503(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://unknown.nginx.container.docker/")
|
||||
assert r.status_code == 503
|
||||
|
||||
|
||||
def test_forwards_to_whoami(nginx_tmpl, docker_compose, nginxproxy):
|
||||
def test_forwards_to_whoami(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://whoami.nginx.container.docker/")
|
||||
assert r.status_code == 200
|
||||
whoami_container = docker_compose.containers.get("whoami")
|
||||
|
|
|
@ -11,7 +11,7 @@ services:
|
|||
command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
|
||||
- ../../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
|
||||
- nginx_conf:/etc/nginx/conf.d
|
||||
|
||||
web:
|
||||
|
|
5
test/test_fallback.data/custom-fallback.conf
Normal file
5
test/test_fallback.data/custom-fallback.conf
Normal file
|
@ -0,0 +1,5 @@
|
|||
server {
|
||||
server_name __;
|
||||
listen 80 default_server;
|
||||
return 418;
|
||||
}
|
14
test/test_fallback.data/custom-fallback.yml
Normal file
14
test/test_fallback.data/custom-fallback.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
services:
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./custom-fallback.conf:/etc/nginx/conf.d/zzz-custom-fallback.conf:ro
|
||||
http-only:
|
||||
image: web
|
||||
expose:
|
||||
- "83"
|
||||
environment:
|
||||
WEB_PORTS: "83"
|
||||
VIRTUAL_HOST: http-only.nginx-proxy.test
|
||||
HTTPS_METHOD: nohttps
|
|
@ -0,0 +1,71 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 4096 (0x1000)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
|
||||
Validity
|
||||
Not Before: Feb 7 21:54:16 2023 GMT
|
||||
Not After : Jun 25 21:54:16 2050 GMT
|
||||
Subject: CN=http-only.nginx-proxy.test
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:b4:62:61:07:54:2e:6d:55:83:2d:24:b7:e2:15:
|
||||
34:13:bd:79:21:e9:10:75:3f:4c:f8:ba:60:29:87:
|
||||
e5:8e:2a:1e:fd:33:51:5a:8a:3a:6f:60:ff:24:f1:
|
||||
1b:27:30:8c:ac:43:04:b7:79:cb:7a:ec:c6:08:a4:
|
||||
a0:15:b0:0f:ee:6b:15:84:24:11:bc:85:2b:48:06:
|
||||
04:0a:58:bb:8c:e8:4d:48:f5:06:c5:91:fe:5d:99:
|
||||
0a:29:31:8a:f1:9b:0c:e0:39:75:a1:06:9b:d4:f5:
|
||||
06:74:8f:46:5e:64:ba:2f:d0:3d:7c:3d:30:03:e9:
|
||||
7c:35:17:69:04:f6:2e:29:d4:93:d6:d6:d2:6c:04:
|
||||
38:06:21:06:05:30:8a:b9:9d:05:8d:12:6e:48:39:
|
||||
bb:f6:93:4f:ba:a5:84:c7:96:2f:be:92:25:e9:d0:
|
||||
95:2a:d9:23:8a:b3:28:0b:b6:19:1c:3b:be:a2:91:
|
||||
70:44:a8:77:18:94:4b:df:61:f4:5c:c9:78:76:34:
|
||||
b5:87:0f:c0:92:04:26:b6:ca:62:cd:9b:5d:eb:bf:
|
||||
10:ac:df:af:72:5f:af:09:38:b1:dc:e1:3d:13:db:
|
||||
a0:ac:b7:2e:ca:39:5c:4c:f1:1e:81:a8:b4:44:a2:
|
||||
72:d5:3b:c0:71:cc:dc:16:0d:fa:38:96:44:b3:00:
|
||||
d6:65
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:http-only.nginx-proxy.test
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
3b:54:95:48:4d:f6:93:38:42:40:02:ab:b7:17:3b:50:3b:ca:
|
||||
c7:12:69:b0:da:cb:d7:3e:0e:1f:bf:a2:59:c7:fe:c2:5c:43:
|
||||
84:92:b9:3a:be:8f:7e:2e:81:3c:ed:f3:a9:77:21:c2:35:f1:
|
||||
da:cf:3a:1e:e2:ee:a2:ce:72:55:97:87:0e:ad:59:61:f7:75:
|
||||
46:c0:2b:d4:88:b7:36:97:11:fb:5e:28:89:e9:2a:92:f1:15:
|
||||
f1:43:8e:c1:38:85:8d:3a:26:7d:25:72:93:17:96:8d:5a:ed:
|
||||
e8:73:3a:d5:8d:80:f2:af:38:84:ff:85:2e:d1:36:7d:2e:e1:
|
||||
f0:2c:d8:15:5f:fc:c5:70:5d:25:6a:22:f3:2a:cd:0f:25:ad:
|
||||
d4:93:d3:9a:3e:50:bc:da:a5:6c:86:ea:1d:d9:b9:c5:90:db:
|
||||
f5:02:c8:c9:77:5c:ef:77:fe:74:60:41:33:d9:3c:a2:e1:73:
|
||||
aa:14:18:5d:36:58:c8:41:63:4c:59:0e:4b:3d:c5:65:5a:01:
|
||||
b0:16:50:0f:d0:4f:0d:ca:97:f6:11:47:06:6b:b1:ae:bb:26:
|
||||
30:34:8b:7a:91:5d:8a:22:c7:f9:05:0d:bb:a5:b7:60:c0:20:
|
||||
ce:d0:0e:c0:66:b3:e7:c4:61:ec:c5:40:e6:52:11:41:c3:11:
|
||||
18:04:c7:1e
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDCzCCAfOgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
|
||||
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
|
||||
ZDAgFw0yMzAyMDcyMTU0MTZaGA8yMDUwMDYyNTIxNTQxNlowJTEjMCEGA1UEAwwa
|
||||
aHR0cC1vbmx5Lm5naW54LXByb3h5LnRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
||||
DwAwggEKAoIBAQC0YmEHVC5tVYMtJLfiFTQTvXkh6RB1P0z4umAph+WOKh79M1Fa
|
||||
ijpvYP8k8RsnMIysQwS3ect67MYIpKAVsA/uaxWEJBG8hStIBgQKWLuM6E1I9QbF
|
||||
kf5dmQopMYrxmwzgOXWhBpvU9QZ0j0ZeZLov0D18PTAD6Xw1F2kE9i4p1JPW1tJs
|
||||
BDgGIQYFMIq5nQWNEm5IObv2k0+6pYTHli++kiXp0JUq2SOKsygLthkcO76ikXBE
|
||||
qHcYlEvfYfRcyXh2NLWHD8CSBCa2ymLNm13rvxCs369yX68JOLHc4T0T26Csty7K
|
||||
OVxM8R6BqLREonLVO8BxzNwWDfo4lkSzANZlAgMBAAGjKTAnMCUGA1UdEQQeMByC
|
||||
Gmh0dHAtb25seS5uZ2lueC1wcm94eS50ZXN0MA0GCSqGSIb3DQEBCwUAA4IBAQA7
|
||||
VJVITfaTOEJAAqu3FztQO8rHEmmw2svXPg4fv6JZx/7CXEOEkrk6vo9+LoE87fOp
|
||||
dyHCNfHazzoe4u6iznJVl4cOrVlh93VGwCvUiLc2lxH7XiiJ6SqS8RXxQ47BOIWN
|
||||
OiZ9JXKTF5aNWu3oczrVjYDyrziE/4Uu0TZ9LuHwLNgVX/zFcF0laiLzKs0PJa3U
|
||||
k9OaPlC82qVshuod2bnFkNv1AsjJd1zvd/50YEEz2Tyi4XOqFBhdNljIQWNMWQ5L
|
||||
PcVlWgGwFlAP0E8Nypf2EUcGa7GuuyYwNIt6kV2KIsf5BQ27pbdgwCDO0A7AZrPn
|
||||
xGHsxUDmUhFBwxEYBMce
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAtGJhB1QubVWDLSS34hU0E715IekQdT9M+LpgKYfljioe/TNR
|
||||
Woo6b2D/JPEbJzCMrEMEt3nLeuzGCKSgFbAP7msVhCQRvIUrSAYECli7jOhNSPUG
|
||||
xZH+XZkKKTGK8ZsM4Dl1oQab1PUGdI9GXmS6L9A9fD0wA+l8NRdpBPYuKdST1tbS
|
||||
bAQ4BiEGBTCKuZ0FjRJuSDm79pNPuqWEx5YvvpIl6dCVKtkjirMoC7YZHDu+opFw
|
||||
RKh3GJRL32H0XMl4djS1hw/AkgQmtspizZtd678QrN+vcl+vCTix3OE9E9ugrLcu
|
||||
yjlcTPEegai0RKJy1TvAcczcFg36OJZEswDWZQIDAQABAoIBAAfDA/HQyX6i41YZ
|
||||
8l+kEe2XhZLT+IVTB/jb7C9dTZ9kaJj0kFeZAxKv1cq9JTH2gNcYuyc58muDrLHK
|
||||
g6jrPoQ/z1k0RB8ci9Q5jgrz7n4NsOWmxXfS5GMaprlHDHeA+HjdgBZBtorfUDvL
|
||||
vndpVimgiETETUCd115hd39jKHFcRcdV6yCix7ObywK3dMgLVpagCcnlyCWffS/r
|
||||
nhhMfJ+VstW0nUtfZ7JEYwT6Cg7lLAVtDkqPX8zGjJiRwUKH808bUyqEw1y5Cc8U
|
||||
U5hbmMgPWfXsKxsEC6FSVHBG9ZX2jymOMQXijLFcBSuWvADHmyU+ZxXcbtd1rv4E
|
||||
cGFj3wECgYEA5cNrr5WjrpEin6MYYVWxiQ+xEWPU2R17eApagrDRLM41JJpv7a5m
|
||||
TYuZRfIxb59CBPi718Gi168P3T2KMvo2/BTh9Lq5ZBYHx3aDqW2QvMFn7/tgamj8
|
||||
0DBxccd2QWfGIBrT1rAF7lD8TC86wtDDVKrvhucRSEXVKF/jWFFRGfUCgYEAyPt6
|
||||
48khr7sfNMVdkDLjQjZVV6H7ZUMoSn0FGybgKWxW+b0XCBPObUQWIpyCNTRr1+4A
|
||||
1TAUS+F/OVVfwnLNgemeE2wd6CaduxwiK1U4pHbyXCElH1ifonHWV3MoXOefYsiY
|
||||
q5z2jfJzUi0JZVUKsveu9rQsFLsc//1s/I5T1LECgYEAldY6fNg2VVp63OZsuNU8
|
||||
oSiljbSwEyMh6Oe/nOkYkIKtr4AzrCoGt11piG7ohGW0lS9suMijnMqiquI+JP5+
|
||||
KyinLoUy761aR17nf+9e62mpkZw6hUqQTGi7Irs0SHUXhMpaCfDi/Ua9MiW+yVuB
|
||||
ds6+xBgeciZwWxMlXOwy2p0CgYEAm+YWiSK3Mq0fo7uEvBn9Fps2z+ciLoZNdppL
|
||||
n6gkMX2MaeQ3PVi/wxoRYX+tsL+c973yf2vwEnw0R7Dlutt6dc9VgxNWj4GE0GMe
|
||||
Tiao7Uom7Tf4p7wC9+r9rI/zOz2f8OxRIK18wtbShWfR5fx1dCWUXmGb3+jUse1O
|
||||
4Qk2FcECgYAvSvGFoJb8tuHFEYYHBbjficmvTUsrTE+EhxPqWKFhKfF19fFFIupy
|
||||
XBCrN6nwrh+/YMxZXeIRbbTTf814cOO7PjLeNhnfhJZkaJq1HzbYe3bOurna3qrm
|
||||
Ra3xiM8Ld2PyGnZPXf8+AWhMhuPkLX1KFVTCAxwCpmTZCHtiGCmXMA==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,71 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 4096 (0x1000)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
|
||||
Validity
|
||||
Not Before: Feb 7 21:53:19 2023 GMT
|
||||
Not After : Jun 25 21:53:19 2050 GMT
|
||||
Subject: CN=https-and-http.nginx-proxy.test
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:b7:97:85:d1:7f:6b:50:29:f3:87:b7:4e:f5:25:
|
||||
40:6a:d8:fa:a1:63:3c:4a:2e:68:4a:c6:8b:38:df:
|
||||
07:81:d0:08:9d:fc:17:f5:37:28:7f:31:e6:f3:81:
|
||||
28:4e:22:b6:bd:a2:4e:f2:2f:e5:0f:dd:55:3c:e1:
|
||||
04:84:4c:45:1b:1a:ae:b7:f0:2a:da:43:05:71:91:
|
||||
92:b8:d1:49:fe:80:0a:53:b9:66:da:54:60:9a:fc:
|
||||
e1:b2:e8:28:48:7f:96:94:3c:92:a3:b2:37:f6:7a:
|
||||
c2:de:0b:12:f0:ae:4e:92:fe:2d:c1:b2:95:28:1f:
|
||||
88:8d:79:99:81:19:ae:22:a4:95:f5:9f:db:25:8e:
|
||||
1d:cf:43:cd:6f:85:93:5f:79:ee:f8:f3:d4:82:e1:
|
||||
e9:4d:c9:ad:ae:5b:92:43:3a:3c:71:51:70:f7:3e:
|
||||
bd:1b:24:52:6a:a3:cf:54:72:57:ed:fe:72:ea:96:
|
||||
9b:5a:02:02:a7:df:85:b7:68:ae:1e:07:77:9f:59:
|
||||
a5:a0:8b:28:c2:c8:b7:bb:8a:42:50:df:05:73:bf:
|
||||
9c:55:13:b5:82:79:77:40:57:a4:8f:88:a5:71:50:
|
||||
d7:70:b0:4d:0c:d9:86:b3:9b:db:8a:20:bd:19:68:
|
||||
10:52:2d:53:ba:0e:2e:1c:ad:80:54:bb:b6:c9:ab:
|
||||
11:39
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:https-and-http.nginx-proxy.test
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
2c:f3:e5:47:3f:8e:5a:28:b1:df:e5:95:50:85:6f:27:2f:a6:
|
||||
8d:f1:5e:cf:df:e2:52:66:97:61:36:59:81:26:25:19:99:c9:
|
||||
93:e5:85:cb:ca:69:af:4b:21:a3:d2:7a:bf:b5:5e:2d:42:fb:
|
||||
99:f8:22:58:e5:bf:79:b8:8a:74:7e:c6:94:14:d9:f2:27:63:
|
||||
b6:e5:74:21:5b:59:fb:f6:c8:a9:28:fb:60:f7:5e:bd:c2:e6:
|
||||
74:24:14:96:61:95:6c:c2:66:b4:52:25:a1:85:5a:97:e5:68:
|
||||
5c:62:cf:69:3b:b0:a9:56:d8:e3:5f:74:dc:84:18:d5:3e:4f:
|
||||
c9:35:39:26:88:dc:9b:80:d9:40:e1:4f:09:27:8d:d2:89:55:
|
||||
30:91:02:86:35:04:95:1e:1d:58:14:5b:c6:e0:2e:a7:bf:a8:
|
||||
f6:2b:76:8a:4e:71:79:bc:c0:04:cd:db:81:73:46:ce:68:ed:
|
||||
25:b0:0e:42:8d:96:64:77:3b:f4:9d:1a:c9:f6:78:4c:56:4f:
|
||||
92:17:29:3d:80:50:71:77:4b:a8:29:c2:12:fc:ad:0a:37:81:
|
||||
38:4c:fb:54:99:4d:12:5f:98:dc:d1:a9:7b:08:45:c4:6f:7e:
|
||||
fe:00:e0:db:79:fe:d1:28:e3:8e:82:d1:fb:bc:0a:c4:42:93:
|
||||
c9:5e:eb:ba
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDFTCCAf2gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
|
||||
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
|
||||
ZDAgFw0yMzAyMDcyMTUzMTlaGA8yMDUwMDYyNTIxNTMxOVowKjEoMCYGA1UEAwwf
|
||||
aHR0cHMtYW5kLWh0dHAubmdpbngtcHJveHkudGVzdDCCASIwDQYJKoZIhvcNAQEB
|
||||
BQADggEPADCCAQoCggEBALeXhdF/a1Ap84e3TvUlQGrY+qFjPEouaErGizjfB4HQ
|
||||
CJ38F/U3KH8x5vOBKE4itr2iTvIv5Q/dVTzhBIRMRRsarrfwKtpDBXGRkrjRSf6A
|
||||
ClO5ZtpUYJr84bLoKEh/lpQ8kqOyN/Z6wt4LEvCuTpL+LcGylSgfiI15mYEZriKk
|
||||
lfWf2yWOHc9DzW+Fk1957vjz1ILh6U3Jra5bkkM6PHFRcPc+vRskUmqjz1RyV+3+
|
||||
cuqWm1oCAqffhbdorh4Hd59ZpaCLKMLIt7uKQlDfBXO/nFUTtYJ5d0BXpI+IpXFQ
|
||||
13CwTQzZhrOb24ogvRloEFItU7oOLhytgFS7tsmrETkCAwEAAaMuMCwwKgYDVR0R
|
||||
BCMwIYIfaHR0cHMtYW5kLWh0dHAubmdpbngtcHJveHkudGVzdDANBgkqhkiG9w0B
|
||||
AQsFAAOCAQEALPPlRz+OWiix3+WVUIVvJy+mjfFez9/iUmaXYTZZgSYlGZnJk+WF
|
||||
y8ppr0sho9J6v7VeLUL7mfgiWOW/ebiKdH7GlBTZ8idjtuV0IVtZ+/bIqSj7YPde
|
||||
vcLmdCQUlmGVbMJmtFIloYVal+VoXGLPaTuwqVbY41903IQY1T5PyTU5Jojcm4DZ
|
||||
QOFPCSeN0olVMJEChjUElR4dWBRbxuAup7+o9it2ik5xebzABM3bgXNGzmjtJbAO
|
||||
Qo2WZHc79J0ayfZ4TFZPkhcpPYBQcXdLqCnCEvytCjeBOEz7VJlNEl+Y3NGpewhF
|
||||
xG9+/gDg23n+0SjjjoLR+7wKxEKTyV7rug==
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAt5eF0X9rUCnzh7dO9SVAatj6oWM8Si5oSsaLON8HgdAInfwX
|
||||
9TcofzHm84EoTiK2vaJO8i/lD91VPOEEhExFGxqut/Aq2kMFcZGSuNFJ/oAKU7lm
|
||||
2lRgmvzhsugoSH+WlDySo7I39nrC3gsS8K5Okv4twbKVKB+IjXmZgRmuIqSV9Z/b
|
||||
JY4dz0PNb4WTX3nu+PPUguHpTcmtrluSQzo8cVFw9z69GyRSaqPPVHJX7f5y6pab
|
||||
WgICp9+Ft2iuHgd3n1mloIsowsi3u4pCUN8Fc7+cVRO1gnl3QFekj4ilcVDXcLBN
|
||||
DNmGs5vbiiC9GWgQUi1Tug4uHK2AVLu2yasROQIDAQABAoIBACT4KSVHoEdzOyvw
|
||||
GME6sB8T9Fw9TG2vrKaqFmzsVGmqh6Gwmu5xHgGG/fe44XHigaPsJDOWu2yXaEur
|
||||
ECrH5P6RP++gODDdYCI/ayk2U80g4XN8mR6L8Swkkhphr4Lx1lOhYvH9uFE05Tqr
|
||||
RjQbFY16C6K+oFSFDQ1YGDYsAqnM3RD7PH+lHpo8UN1TO/vogdSQEpMYZDwLAYnW
|
||||
uD5G3c0u2PsGu9YLuz2p8hcs3chh+cqKJWXOeW0JLrNGx1bqeQWkn6nXRDdRYi9V
|
||||
cJlTgDqGuF54bieSyq9ABDZQP4Ol+moYKDoIz5PwurNjcYSklrT1tw0gqHZoQK1L
|
||||
fDjw3QECgYEA7QMRU1AFKTvO7/8WLHLN5BT63n31wm0e9PYpz/XVLWEfxBcp9Xmf
|
||||
xAIhXZ/U9P4dfNqxTjN9mVGzCHh5KfDJnUFqOXFy/zvfMeRzJf6dJo6/4OX9Bijr
|
||||
Tgd454vyGXYQP2t+F14UAwl6vlGOAjttiP5qY5Ef1gllBEeIPe9Ts9kCgYEAxkzZ
|
||||
pq4HJ/5/iDquMEHXNXzpNPavSvgxQdl1ILvJ49LJImmQFBCP9PqiOTIfePz1OqUI
|
||||
C4baFuc0FEDJ3x9CUNmMY1lEi2ZUq2agPSXaQNsMcKtEJH8SoJlJIRpkQA7unX09
|
||||
zb4dam6g79OaGmb8scePuezXMLv1Ee6WWtXbzGECgYEA6PYn9Gzl9cacu9dOUzgw
|
||||
2ewpPcIvawDY+cxwAsHO3MDneVWPX4JBoGa7pwvwRTL1hwBqYMRJwwbD5CKObcQI
|
||||
V/KxV28Eqo2N77tt1z2x9/E99u/4yTI1P0gm9ejfeVlL1RpyIMPPBcEujZ0Z6WXC
|
||||
X3I63k0KLtajHRa2erIf4tkCgYAfunAgwTuX5JqXO3xfcEl033WY6deGUUvgU2Dw
|
||||
Sdu1viY8gVNyQmwmMGwAZsquWxsJtRoibgM7IucsTml+b8v2j7hstP3IqCjn+9Wr
|
||||
swDG28WTyXNvu31JgP04dLaRoVIAlOdsofym6OiLNvozO0M3VsziXMjZnVlK8zfP
|
||||
dORkQQKBgQDXAJEJPygxVA+bF104dzCMWGmU7K8ShEWC5eOdKK4KWf9bNDpY6M6c
|
||||
i6zga/xBbj7e3Bxqprpp8Wy2gIsnYiVo4V9EQethbLdomPxOpBMNMARw81rL1CpO
|
||||
jbHB7bIDcKs2tQoZEXUW86ZxC8sdaDaWTJTfUO0RpJow6ZO3yvxVIQ==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,71 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 4096 (0x1000)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
|
||||
Validity
|
||||
Not Before: Feb 7 21:53:49 2023 GMT
|
||||
Not After : Jun 25 21:53:49 2050 GMT
|
||||
Subject: CN=https-only.nginx-proxy.test
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:d9:87:48:02:85:f4:5f:0d:90:7e:4c:4f:13:89:
|
||||
41:ca:41:15:c2:6f:fd:a8:c7:17:83:c6:dd:8c:fe:
|
||||
19:a4:b2:6b:0b:35:4f:b4:3d:7c:40:0a:04:33:2a:
|
||||
fd:10:72:f7:63:63:99:5b:3d:ec:78:ee:c6:4d:c8:
|
||||
0e:4c:be:f2:3f:e3:02:74:57:9a:c1:fe:15:95:63:
|
||||
4e:e7:2c:eb:70:f2:6b:c8:ba:01:a2:ca:a1:c7:76:
|
||||
ff:38:e4:c2:b0:66:fc:85:d2:af:0f:22:81:d4:82:
|
||||
eb:d5:b0:e6:69:14:37:dd:8d:ad:29:ce:93:68:5a:
|
||||
ce:f4:77:76:6f:78:13:b6:c8:2f:fe:e0:b6:7e:fb:
|
||||
29:16:be:e2:f5:45:3b:39:5b:52:dc:26:b7:ca:0c:
|
||||
b6:1c:fc:a8:38:0b:dd:c1:f4:04:9b:2d:38:c9:a5:
|
||||
2d:3e:f1:42:88:53:a2:3b:17:cf:d5:3c:2b:d6:6a:
|
||||
7f:6f:05:8d:c5:b7:5d:64:1e:83:1b:e7:ec:80:3d:
|
||||
6d:34:c1:66:b2:e6:5d:d9:a7:6e:46:75:14:bf:10:
|
||||
16:c5:fc:47:8e:63:fa:e5:b4:bd:f2:b9:e0:cb:ea:
|
||||
75:f9:68:ee:7d:8f:ea:8f:1a:9f:34:27:7a:4a:9f:
|
||||
85:fd:3e:17:a7:96:c3:d0:4e:50:a2:a2:e0:45:92:
|
||||
d0:b5
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:https-only.nginx-proxy.test
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
8a:52:46:42:a9:74:18:6a:52:90:ef:a4:e9:c5:54:d5:97:3a:
|
||||
ff:8b:c2:76:4f:9e:47:aa:e1:ea:e5:b9:af:9d:33:e3:85:17:
|
||||
54:7d:32:bd:ac:90:3f:5c:d2:a1:42:17:52:2b:b1:83:e5:c3:
|
||||
bf:81:f0:e7:38:e2:88:67:7b:d8:59:fe:f9:94:99:ba:be:f4:
|
||||
3c:24:b2:c7:9e:f0:98:21:c6:2d:c2:e8:f3:67:bd:62:00:aa:
|
||||
ce:34:fa:b4:53:6d:c1:09:5e:55:bd:43:aa:86:c6:f8:c5:83:
|
||||
46:3a:49:12:a2:ec:30:36:0c:99:44:74:09:9d:cc:4b:98:1f:
|
||||
7e:c9:9b:68:a0:f8:1e:00:14:d0:da:2a:bf:c8:ca:a8:1c:10:
|
||||
b5:68:a2:f1:41:93:0c:f3:3f:c0:c6:53:3c:8d:a7:dd:a5:7b:
|
||||
35:cc:44:e0:5b:6d:c5:cb:33:6f:c1:43:7e:06:df:21:99:11:
|
||||
b3:91:41:b4:5e:f0:37:1e:8e:e5:73:85:dc:4a:21:d5:41:f9:
|
||||
4e:b8:f5:ed:21:93:09:91:c2:8c:6b:04:a4:84:ab:3a:fe:35:
|
||||
64:fa:6b:a7:8d:40:a6:64:89:30:84:ac:28:99:5a:01:79:77:
|
||||
c0:df:88:da:a9:75:5f:c4:51:ae:a8:45:7b:d2:e1:a2:81:29:
|
||||
60:cd:7b:cd
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDDTCCAfWgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
|
||||
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
|
||||
ZDAgFw0yMzAyMDcyMTUzNDlaGA8yMDUwMDYyNTIxNTM0OVowJjEkMCIGA1UEAwwb
|
||||
aHR0cHMtb25seS5uZ2lueC1wcm94eS50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEA2YdIAoX0Xw2QfkxPE4lBykEVwm/9qMcXg8bdjP4ZpLJrCzVP
|
||||
tD18QAoEMyr9EHL3Y2OZWz3seO7GTcgOTL7yP+MCdFeawf4VlWNO5yzrcPJryLoB
|
||||
osqhx3b/OOTCsGb8hdKvDyKB1ILr1bDmaRQ33Y2tKc6TaFrO9Hd2b3gTtsgv/uC2
|
||||
fvspFr7i9UU7OVtS3Ca3ygy2HPyoOAvdwfQEmy04yaUtPvFCiFOiOxfP1Twr1mp/
|
||||
bwWNxbddZB6DG+fsgD1tNMFmsuZd2aduRnUUvxAWxfxHjmP65bS98rngy+p1+Wju
|
||||
fY/qjxqfNCd6Sp+F/T4Xp5bD0E5QoqLgRZLQtQIDAQABoyowKDAmBgNVHREEHzAd
|
||||
ghtodHRwcy1vbmx5Lm5naW54LXByb3h5LnRlc3QwDQYJKoZIhvcNAQELBQADggEB
|
||||
AIpSRkKpdBhqUpDvpOnFVNWXOv+LwnZPnkeq4erlua+dM+OFF1R9Mr2skD9c0qFC
|
||||
F1IrsYPlw7+B8Oc44ohne9hZ/vmUmbq+9Dwkssee8Jghxi3C6PNnvWIAqs40+rRT
|
||||
bcEJXlW9Q6qGxvjFg0Y6SRKi7DA2DJlEdAmdzEuYH37Jm2ig+B4AFNDaKr/Iyqgc
|
||||
ELVoovFBkwzzP8DGUzyNp92lezXMROBbbcXLM2/BQ34G3yGZEbORQbRe8DcejuVz
|
||||
hdxKIdVB+U649e0hkwmRwoxrBKSEqzr+NWT6a6eNQKZkiTCErCiZWgF5d8DfiNqp
|
||||
dV/EUa6oRXvS4aKBKWDNe80=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA2YdIAoX0Xw2QfkxPE4lBykEVwm/9qMcXg8bdjP4ZpLJrCzVP
|
||||
tD18QAoEMyr9EHL3Y2OZWz3seO7GTcgOTL7yP+MCdFeawf4VlWNO5yzrcPJryLoB
|
||||
osqhx3b/OOTCsGb8hdKvDyKB1ILr1bDmaRQ33Y2tKc6TaFrO9Hd2b3gTtsgv/uC2
|
||||
fvspFr7i9UU7OVtS3Ca3ygy2HPyoOAvdwfQEmy04yaUtPvFCiFOiOxfP1Twr1mp/
|
||||
bwWNxbddZB6DG+fsgD1tNMFmsuZd2aduRnUUvxAWxfxHjmP65bS98rngy+p1+Wju
|
||||
fY/qjxqfNCd6Sp+F/T4Xp5bD0E5QoqLgRZLQtQIDAQABAoIBAAWs//YA5MVuJy0E
|
||||
dLO/yxWp6RVvsqCqwTRRBgrdvnGLrjtWosPDLvDE0iM7peq99TKEsMWusfLd2BLD
|
||||
e4wJF20PUUsT1hflt050juR9SY9i4+kS4WQMAXig5DvpzCKqLUCYpLSyY8zVta2X
|
||||
tgtb2bFQNwp2N2ZrqCa8zzxNV8ZXGoW+ZlvBJEDtBwt1DCDhY39/pqHfIhFl4Vwk
|
||||
YhhbVjID145D1j/fP6vLceM2YA4uRmF1itj1iQ6YNNpXRspUGE4DXdqR6HcbduiX
|
||||
trZjmdtKXY8mJg6jyLZxYbjFlKV/LvqKRYF3Jb9K0vdd4juBdZoy7DQzoLhcnzui
|
||||
pEnPLakCgYEA9tN6KdQGKGBXGuF+ZqhXfB/XSkKUf8o/5j62cbu11ZIJ+iEBx+d6
|
||||
lQAxTz5hHUL6a3c5qiM+AWBxYuFD6oqptIlTlBfIXI978neDNvEWWffivPvQLbt9
|
||||
o9ohOirfK1iGPvtrpAwjv5ylE5SiTmJ/6wDvQWjNGAnJ3aaxkesJUSMCgYEA4Z0K
|
||||
UHZVtnKLtzzIY7KfLbuKF/fJEDfMNr4Wgl6ny21vqO9kJGmA7SaoNdhx8RDcKmeV
|
||||
/Vey4ug6YlOG48eapKLTthdRz5mx+jIkUfdOhj81m28xm/OPTqCrviTHCNOHeYDy
|
||||
NKAIlJMo2z0vTKJn5eP6CsYmDWLpHQNyXY5qcEcCgYAzDBWt5O3JF/Or2Yr8zEAb
|
||||
qbIq544yx69jfQDakMnQe72Yf48Quuz9N+b6zpnjJWEJLMU+TL+cJUgN/SzAqyDh
|
||||
96zTaf/ENOCbiuAWUtIelUfNcf7iFm6rnodUsl0pZ8uL5w+iA+i4zjrNy+WtdG2k
|
||||
OrNAwd345L1dHAaJeSSaJQKBgQCUnF3r7Fa/TCpt87LHwSQK+sqWyRf+/9IbiRDI
|
||||
pVL/s8FmVPHw7jIHhHwuo7lCImnz4LGy5C6oOnIizIRAy/04Ty0Hd8ri5YmPlbHI
|
||||
8A8gbMiB7zeNU1zlXP5jzFPyo2tMhLyGH5gnTdwOtfnPD/dCPe45ZJYyISIOg3O0
|
||||
3peMBwKBgH20cskAOCNclfoG+Nis52h8FqmDlflJ8waUarvk26JhO1e009kOytw8
|
||||
x/qSuttpGtTG+4fdc2wJvFNczr4h9ZlftBdgZXj8PKgRpcIe8q97Xg8PUj+Xfu/t
|
||||
vD/QV+tVcGoAMsQq4NeFxiTbPfwVyXdYFT1XVCu6JEdLL+gpWh5W
|
||||
-----END RSA PRIVATE KEY-----
|
36
test/test_fallback.data/nodefault.yml
Normal file
36
test/test_fallback.data/nodefault.yml
Normal file
|
@ -0,0 +1,36 @@
|
|||
services:
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./nodefault.certs:/etc/nginx/certs:ro
|
||||
https-and-http:
|
||||
image: web
|
||||
expose:
|
||||
- "81"
|
||||
environment:
|
||||
WEB_PORTS: "81"
|
||||
VIRTUAL_HOST: https-and-http.nginx-proxy.test
|
||||
https-only:
|
||||
image: web
|
||||
expose:
|
||||
- "82"
|
||||
environment:
|
||||
WEB_PORTS: "82"
|
||||
VIRTUAL_HOST: https-only.nginx-proxy.test
|
||||
HTTPS_METHOD: nohttp
|
||||
http-only:
|
||||
image: web
|
||||
expose:
|
||||
- "83"
|
||||
environment:
|
||||
WEB_PORTS: "83"
|
||||
VIRTUAL_HOST: http-only.nginx-proxy.test
|
||||
HTTPS_METHOD: nohttps
|
||||
missing-cert:
|
||||
image: web
|
||||
expose:
|
||||
- "84"
|
||||
environment:
|
||||
WEB_PORTS: "84"
|
||||
VIRTUAL_HOST: missing-cert.nginx-proxy.test
|
16
test/test_fallback.data/nohttp-on-app.yml
Normal file
16
test/test_fallback.data/nohttp-on-app.yml
Normal file
|
@ -0,0 +1,16 @@
|
|||
services:
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./withdefault.certs:/etc/nginx/certs:ro
|
||||
environment:
|
||||
HTTPS_METHOD: redirect
|
||||
https-only:
|
||||
image: web
|
||||
expose:
|
||||
- "82"
|
||||
environment:
|
||||
WEB_PORTS: "82"
|
||||
HTTPS_METHOD: nohttp
|
||||
VIRTUAL_HOST: https-only.nginx-proxy.test
|
22
test/test_fallback.data/nohttp-with-missing-cert.yml
Normal file
22
test/test_fallback.data/nohttp-with-missing-cert.yml
Normal file
|
@ -0,0 +1,22 @@
|
|||
services:
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./withdefault.certs:/etc/nginx/certs:ro
|
||||
environment:
|
||||
HTTPS_METHOD: nohttp
|
||||
https-only:
|
||||
image: web
|
||||
expose:
|
||||
- "82"
|
||||
environment:
|
||||
WEB_PORTS: "82"
|
||||
VIRTUAL_HOST: https-only.nginx-proxy.test
|
||||
missing-cert:
|
||||
image: web
|
||||
expose:
|
||||
- "84"
|
||||
environment:
|
||||
WEB_PORTS: "84"
|
||||
VIRTUAL_HOST: missing-cert.nginx-proxy.test
|
15
test/test_fallback.data/nohttp.yml
Normal file
15
test/test_fallback.data/nohttp.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
services:
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./withdefault.certs:/etc/nginx/certs:ro
|
||||
environment:
|
||||
HTTPS_METHOD: nohttp
|
||||
https-only:
|
||||
image: web
|
||||
expose:
|
||||
- "82"
|
||||
environment:
|
||||
WEB_PORTS: "82"
|
||||
VIRTUAL_HOST: https-only.nginx-proxy.test
|
15
test/test_fallback.data/nohttps-on-app.yml
Normal file
15
test/test_fallback.data/nohttps-on-app.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
services:
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
environment:
|
||||
HTTPS_METHOD: redirect
|
||||
http-only:
|
||||
image: web
|
||||
expose:
|
||||
- "83"
|
||||
environment:
|
||||
WEB_PORTS: "83"
|
||||
HTTPS_METHOD: nohttps
|
||||
VIRTUAL_HOST: http-only.nginx-proxy.test
|
14
test/test_fallback.data/nohttps.yml
Normal file
14
test/test_fallback.data/nohttps.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
services:
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
environment:
|
||||
HTTPS_METHOD: nohttps
|
||||
http-only:
|
||||
image: web
|
||||
expose:
|
||||
- "83"
|
||||
environment:
|
||||
WEB_PORTS: "83"
|
||||
VIRTUAL_HOST: http-only.nginx-proxy.test
|
70
test/test_fallback.data/withdefault.certs/default.crt
Normal file
70
test/test_fallback.data/withdefault.certs/default.crt
Normal file
|
@ -0,0 +1,70 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 4096 (0x1000)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
|
||||
Validity
|
||||
Not Before: Feb 9 04:02:23 2023 GMT
|
||||
Not After : Jun 27 04:02:23 2050 GMT
|
||||
Subject: CN=*.nginx-proxy.test
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:db:bd:54:de:01:7e:82:4e:c0:f1:5d:12:fd:3a:
|
||||
fb:21:19:4d:44:25:47:ea:ad:d8:11:5c:d1:65:88:
|
||||
af:49:fc:8e:4b:c3:01:c1:0d:6d:22:67:bd:31:66:
|
||||
9f:4a:50:17:9e:47:b3:3b:b3:21:73:1f:81:55:73:
|
||||
52:47:9b:fb:85:6b:e8:d8:09:cc:e1:7d:1c:14:03:
|
||||
1c:ae:84:b4:5b:e5:e5:c7:71:fc:1f:74:33:4f:ae:
|
||||
f7:8d:21:1f:55:8d:93:c7:84:4d:93:01:a1:1c:37:
|
||||
ae:85:5c:70:2c:21:ec:87:35:c3:86:d3:b3:0f:9a:
|
||||
b0:9d:8a:cd:0e:49:e8:99:c5:4c:50:bd:a8:6e:a7:
|
||||
01:3e:a7:dc:cf:c3:48:37:8e:c6:8a:89:b0:41:01:
|
||||
58:ee:45:94:fa:90:eb:df:c8:0e:b7:dd:79:75:13:
|
||||
1e:07:69:ee:54:47:92:18:9d:e0:a9:ee:4e:22:d1:
|
||||
f4:a2:4d:a1:47:ed:9b:35:2a:70:cc:66:fb:3e:f0:
|
||||
49:f7:ee:62:2a:27:a1:d3:52:7b:ff:e9:12:d9:5b:
|
||||
6b:f6:18:bf:9c:9d:5f:00:29:d2:54:b5:f8:a4:a2:
|
||||
9b:3f:fe:a6:ed:14:ae:a0:fe:13:33:18:33:17:a9:
|
||||
8b:fe:fc:75:65:0c:fb:c2:d1:1e:81:ca:43:89:bd:
|
||||
78:dd
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:*.nginx-proxy.test
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
43:a7:1f:4b:ec:ff:1d:70:c7:f8:6e:eb:fd:15:25:27:b2:54:
|
||||
c7:92:cf:ed:51:31:28:56:76:5c:da:8b:17:31:55:8c:a1:c2:
|
||||
37:95:27:7b:b6:58:e5:92:ef:1e:fe:35:f1:44:ca:c7:1b:7b:
|
||||
75:bf:e1:91:61:6d:8a:6f:35:8b:73:f4:d9:08:60:25:07:7a:
|
||||
3e:c2:79:e7:ae:b4:70:cc:8a:30:cb:80:aa:47:1a:40:82:00:
|
||||
a0:5e:01:67:d1:95:21:3c:b1:52:7d:f5:87:b6:43:41:df:b2:
|
||||
a7:ee:3b:73:17:c4:19:2c:6b:7b:3c:26:9e:4c:00:e3:e8:07:
|
||||
f2:e1:a1:31:79:57:be:b6:b1:a7:93:70:4e:e1:7d:bf:08:c5:
|
||||
e7:a0:de:7d:82:20:24:f7:b0:3f:c2:94:36:88:ef:7b:7d:c0:
|
||||
7f:8a:78:a1:8e:56:42:82:ce:82:e6:8e:3d:1b:b7:ca:dd:a9:
|
||||
a8:e6:f9:a3:f4:4a:a4:a0:9c:15:6f:44:8c:48:20:e5:85:ed:
|
||||
6f:85:22:41:1d:1f:fe:58:e5:43:ad:f2:c4:10:5a:10:ed:36:
|
||||
10:98:ad:73:97:6a:e0:19:18:d6:32:26:03:3d:dd:84:5c:2e:
|
||||
97:ca:a2:f5:63:f2:7a:16:f1:55:ca:d2:a1:54:09:8a:bb:23:
|
||||
f0:53:36:51
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC+zCCAeOgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
|
||||
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
|
||||
ZDAgFw0yMzAyMDkwNDAyMjNaGA8yMDUwMDYyNzA0MDIyM1owHTEbMBkGA1UEAwwS
|
||||
Ki5uZ2lueC1wcm94eS50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
||||
AQEA271U3gF+gk7A8V0S/Tr7IRlNRCVH6q3YEVzRZYivSfyOS8MBwQ1tIme9MWaf
|
||||
SlAXnkezO7Mhcx+BVXNSR5v7hWvo2AnM4X0cFAMcroS0W+Xlx3H8H3QzT673jSEf
|
||||
VY2Tx4RNkwGhHDeuhVxwLCHshzXDhtOzD5qwnYrNDknomcVMUL2obqcBPqfcz8NI
|
||||
N47GiomwQQFY7kWU+pDr38gOt915dRMeB2nuVEeSGJ3gqe5OItH0ok2hR+2bNSpw
|
||||
zGb7PvBJ9+5iKieh01J7/+kS2Vtr9hi/nJ1fACnSVLX4pKKbP/6m7RSuoP4TMxgz
|
||||
F6mL/vx1ZQz7wtEegcpDib143QIDAQABoyEwHzAdBgNVHREEFjAUghIqLm5naW54
|
||||
LXByb3h5LnRlc3QwDQYJKoZIhvcNAQELBQADggEBAEOnH0vs/x1wx/hu6/0VJSey
|
||||
VMeSz+1RMShWdlzaixcxVYyhwjeVJ3u2WOWS7x7+NfFEyscbe3W/4ZFhbYpvNYtz
|
||||
9NkIYCUHej7CeeeutHDMijDLgKpHGkCCAKBeAWfRlSE8sVJ99Ye2Q0HfsqfuO3MX
|
||||
xBksa3s8Jp5MAOPoB/LhoTF5V762saeTcE7hfb8Ixeeg3n2CICT3sD/ClDaI73t9
|
||||
wH+KeKGOVkKCzoLmjj0bt8rdqajm+aP0SqSgnBVvRIxIIOWF7W+FIkEdH/5Y5UOt
|
||||
8sQQWhDtNhCYrXOXauAZGNYyJgM93YRcLpfKovVj8noW8VXK0qFUCYq7I/BTNlE=
|
||||
-----END CERTIFICATE-----
|
27
test/test_fallback.data/withdefault.certs/default.key
Normal file
27
test/test_fallback.data/withdefault.certs/default.key
Normal file
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA271U3gF+gk7A8V0S/Tr7IRlNRCVH6q3YEVzRZYivSfyOS8MB
|
||||
wQ1tIme9MWafSlAXnkezO7Mhcx+BVXNSR5v7hWvo2AnM4X0cFAMcroS0W+Xlx3H8
|
||||
H3QzT673jSEfVY2Tx4RNkwGhHDeuhVxwLCHshzXDhtOzD5qwnYrNDknomcVMUL2o
|
||||
bqcBPqfcz8NIN47GiomwQQFY7kWU+pDr38gOt915dRMeB2nuVEeSGJ3gqe5OItH0
|
||||
ok2hR+2bNSpwzGb7PvBJ9+5iKieh01J7/+kS2Vtr9hi/nJ1fACnSVLX4pKKbP/6m
|
||||
7RSuoP4TMxgzF6mL/vx1ZQz7wtEegcpDib143QIDAQABAoIBAGUd9QXMTjkMoIDx
|
||||
QaHCGHocuI+ZUETQBtPGkJ1WjsNPMvPuIsqBsSzZ7Bflj3uU66lseTAJuGTPpKZ7
|
||||
0Ose/llhVN7Fc8B34AndfL9aVdzMKDblXw3iXRJYA5awHUkzQ0PWwBPb9hWUEf1Q
|
||||
klXcrolx1i4fEREnMArvKnlezWikpXcqDYRcmUfEvVozaq75heavHpOcOq2dg7vo
|
||||
N/gcJmfG4aDOhrZC1f22u5cNePvbVj+DdXOUHMEEfXOFbxk97VhmcIaH75ugvVh4
|
||||
EMMg87mcGLZiqPO5k6SYcuGyquc32Tf5sK80mpt/+SAEHCvSmUt9c1ynQrS9IhNp
|
||||
OGfZhQkCgYEA+LonwScVGVEgHg1A9E7BKhIrgUOlwWNM43s+o8Uuz1T72VUVZ6N/
|
||||
aO0+2Panw1qjsb0CUC2zft3zZTiZd81gWRmBYQ0R9dHWyWHbJlOv8rAmJ+60Gr2a
|
||||
UVTLHEdZKx6svSDNhL0HfxxfWwePgHB4NVa2RUA3KQ5y5C96EXb8WbsCgYEA4iow
|
||||
nIIbRZ9ILDz1oThxE+dFifKWXWFOwa58EFBY+/y34itL7kXRu2+4ZIltwL0L8m5j
|
||||
GUALUabuoOASKg4CFBhCvoAAlWZRr6L6EOecrElUnrefUrKuCWPCVo3MnCMuLXDp
|
||||
p1mEGIwEZBCY+jrSBMrRCawsMRkcymLJhEBFYkcCgYB6xIey0vObF2ve6XPSIr09
|
||||
YtKObzF1jun4rnBwrXc5Zx0YXOK/0PemdtO6i6SqzCZYKI7nvGcIi80DfThi5cBU
|
||||
uj4eBTGEQBrgM6jT9iK2izOKKkxDlqqA0nWec6kTm4Rvpa1Lg3Ibz4lRiR3Pq7Pp
|
||||
v+8fp16SqUsUTkrWLADK2QKBgCRIhHf3X4yx2xBNz1JIDcwVpFBXPMxKWio0Ze7w
|
||||
FPaIOq/sJkhZpyYc7EYkzhjHu2zvTLK2VZqJ32qrx/47NRYoNjz9qBpPyfcVfGzN
|
||||
25LASPUVnFfWFpmnCXx9T0AVXMkpfjK857ZQcDvldcVfPmZKa3LTzlsqHjZR1uaC
|
||||
sR7tAoGBANBfInPZVZRJfqqkPN1K8j4P7uCGjTIBmys/vxoilh1d0scTgZrdqt92
|
||||
EKi/3UsJW2ndqQNDLbvi5kcW8a6UU3UB1LLvpyQ5zuS81x3+kKfv+5cDM8rt/M4A
|
||||
MXnJA5eDZZ4SlHFzdblUv/MZdT+1x0tivMn3zFKNNj2SmaSGkQ0m
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,71 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 4096 (0x1000)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
|
||||
Validity
|
||||
Not Before: Feb 7 21:54:16 2023 GMT
|
||||
Not After : Jun 25 21:54:16 2050 GMT
|
||||
Subject: CN=http-only.nginx-proxy.test
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:b4:62:61:07:54:2e:6d:55:83:2d:24:b7:e2:15:
|
||||
34:13:bd:79:21:e9:10:75:3f:4c:f8:ba:60:29:87:
|
||||
e5:8e:2a:1e:fd:33:51:5a:8a:3a:6f:60:ff:24:f1:
|
||||
1b:27:30:8c:ac:43:04:b7:79:cb:7a:ec:c6:08:a4:
|
||||
a0:15:b0:0f:ee:6b:15:84:24:11:bc:85:2b:48:06:
|
||||
04:0a:58:bb:8c:e8:4d:48:f5:06:c5:91:fe:5d:99:
|
||||
0a:29:31:8a:f1:9b:0c:e0:39:75:a1:06:9b:d4:f5:
|
||||
06:74:8f:46:5e:64:ba:2f:d0:3d:7c:3d:30:03:e9:
|
||||
7c:35:17:69:04:f6:2e:29:d4:93:d6:d6:d2:6c:04:
|
||||
38:06:21:06:05:30:8a:b9:9d:05:8d:12:6e:48:39:
|
||||
bb:f6:93:4f:ba:a5:84:c7:96:2f:be:92:25:e9:d0:
|
||||
95:2a:d9:23:8a:b3:28:0b:b6:19:1c:3b:be:a2:91:
|
||||
70:44:a8:77:18:94:4b:df:61:f4:5c:c9:78:76:34:
|
||||
b5:87:0f:c0:92:04:26:b6:ca:62:cd:9b:5d:eb:bf:
|
||||
10:ac:df:af:72:5f:af:09:38:b1:dc:e1:3d:13:db:
|
||||
a0:ac:b7:2e:ca:39:5c:4c:f1:1e:81:a8:b4:44:a2:
|
||||
72:d5:3b:c0:71:cc:dc:16:0d:fa:38:96:44:b3:00:
|
||||
d6:65
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:http-only.nginx-proxy.test
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
3b:54:95:48:4d:f6:93:38:42:40:02:ab:b7:17:3b:50:3b:ca:
|
||||
c7:12:69:b0:da:cb:d7:3e:0e:1f:bf:a2:59:c7:fe:c2:5c:43:
|
||||
84:92:b9:3a:be:8f:7e:2e:81:3c:ed:f3:a9:77:21:c2:35:f1:
|
||||
da:cf:3a:1e:e2:ee:a2:ce:72:55:97:87:0e:ad:59:61:f7:75:
|
||||
46:c0:2b:d4:88:b7:36:97:11:fb:5e:28:89:e9:2a:92:f1:15:
|
||||
f1:43:8e:c1:38:85:8d:3a:26:7d:25:72:93:17:96:8d:5a:ed:
|
||||
e8:73:3a:d5:8d:80:f2:af:38:84:ff:85:2e:d1:36:7d:2e:e1:
|
||||
f0:2c:d8:15:5f:fc:c5:70:5d:25:6a:22:f3:2a:cd:0f:25:ad:
|
||||
d4:93:d3:9a:3e:50:bc:da:a5:6c:86:ea:1d:d9:b9:c5:90:db:
|
||||
f5:02:c8:c9:77:5c:ef:77:fe:74:60:41:33:d9:3c:a2:e1:73:
|
||||
aa:14:18:5d:36:58:c8:41:63:4c:59:0e:4b:3d:c5:65:5a:01:
|
||||
b0:16:50:0f:d0:4f:0d:ca:97:f6:11:47:06:6b:b1:ae:bb:26:
|
||||
30:34:8b:7a:91:5d:8a:22:c7:f9:05:0d:bb:a5:b7:60:c0:20:
|
||||
ce:d0:0e:c0:66:b3:e7:c4:61:ec:c5:40:e6:52:11:41:c3:11:
|
||||
18:04:c7:1e
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDCzCCAfOgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
|
||||
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
|
||||
ZDAgFw0yMzAyMDcyMTU0MTZaGA8yMDUwMDYyNTIxNTQxNlowJTEjMCEGA1UEAwwa
|
||||
aHR0cC1vbmx5Lm5naW54LXByb3h5LnRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
||||
DwAwggEKAoIBAQC0YmEHVC5tVYMtJLfiFTQTvXkh6RB1P0z4umAph+WOKh79M1Fa
|
||||
ijpvYP8k8RsnMIysQwS3ect67MYIpKAVsA/uaxWEJBG8hStIBgQKWLuM6E1I9QbF
|
||||
kf5dmQopMYrxmwzgOXWhBpvU9QZ0j0ZeZLov0D18PTAD6Xw1F2kE9i4p1JPW1tJs
|
||||
BDgGIQYFMIq5nQWNEm5IObv2k0+6pYTHli++kiXp0JUq2SOKsygLthkcO76ikXBE
|
||||
qHcYlEvfYfRcyXh2NLWHD8CSBCa2ymLNm13rvxCs369yX68JOLHc4T0T26Csty7K
|
||||
OVxM8R6BqLREonLVO8BxzNwWDfo4lkSzANZlAgMBAAGjKTAnMCUGA1UdEQQeMByC
|
||||
Gmh0dHAtb25seS5uZ2lueC1wcm94eS50ZXN0MA0GCSqGSIb3DQEBCwUAA4IBAQA7
|
||||
VJVITfaTOEJAAqu3FztQO8rHEmmw2svXPg4fv6JZx/7CXEOEkrk6vo9+LoE87fOp
|
||||
dyHCNfHazzoe4u6iznJVl4cOrVlh93VGwCvUiLc2lxH7XiiJ6SqS8RXxQ47BOIWN
|
||||
OiZ9JXKTF5aNWu3oczrVjYDyrziE/4Uu0TZ9LuHwLNgVX/zFcF0laiLzKs0PJa3U
|
||||
k9OaPlC82qVshuod2bnFkNv1AsjJd1zvd/50YEEz2Tyi4XOqFBhdNljIQWNMWQ5L
|
||||
PcVlWgGwFlAP0E8Nypf2EUcGa7GuuyYwNIt6kV2KIsf5BQ27pbdgwCDO0A7AZrPn
|
||||
xGHsxUDmUhFBwxEYBMce
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAtGJhB1QubVWDLSS34hU0E715IekQdT9M+LpgKYfljioe/TNR
|
||||
Woo6b2D/JPEbJzCMrEMEt3nLeuzGCKSgFbAP7msVhCQRvIUrSAYECli7jOhNSPUG
|
||||
xZH+XZkKKTGK8ZsM4Dl1oQab1PUGdI9GXmS6L9A9fD0wA+l8NRdpBPYuKdST1tbS
|
||||
bAQ4BiEGBTCKuZ0FjRJuSDm79pNPuqWEx5YvvpIl6dCVKtkjirMoC7YZHDu+opFw
|
||||
RKh3GJRL32H0XMl4djS1hw/AkgQmtspizZtd678QrN+vcl+vCTix3OE9E9ugrLcu
|
||||
yjlcTPEegai0RKJy1TvAcczcFg36OJZEswDWZQIDAQABAoIBAAfDA/HQyX6i41YZ
|
||||
8l+kEe2XhZLT+IVTB/jb7C9dTZ9kaJj0kFeZAxKv1cq9JTH2gNcYuyc58muDrLHK
|
||||
g6jrPoQ/z1k0RB8ci9Q5jgrz7n4NsOWmxXfS5GMaprlHDHeA+HjdgBZBtorfUDvL
|
||||
vndpVimgiETETUCd115hd39jKHFcRcdV6yCix7ObywK3dMgLVpagCcnlyCWffS/r
|
||||
nhhMfJ+VstW0nUtfZ7JEYwT6Cg7lLAVtDkqPX8zGjJiRwUKH808bUyqEw1y5Cc8U
|
||||
U5hbmMgPWfXsKxsEC6FSVHBG9ZX2jymOMQXijLFcBSuWvADHmyU+ZxXcbtd1rv4E
|
||||
cGFj3wECgYEA5cNrr5WjrpEin6MYYVWxiQ+xEWPU2R17eApagrDRLM41JJpv7a5m
|
||||
TYuZRfIxb59CBPi718Gi168P3T2KMvo2/BTh9Lq5ZBYHx3aDqW2QvMFn7/tgamj8
|
||||
0DBxccd2QWfGIBrT1rAF7lD8TC86wtDDVKrvhucRSEXVKF/jWFFRGfUCgYEAyPt6
|
||||
48khr7sfNMVdkDLjQjZVV6H7ZUMoSn0FGybgKWxW+b0XCBPObUQWIpyCNTRr1+4A
|
||||
1TAUS+F/OVVfwnLNgemeE2wd6CaduxwiK1U4pHbyXCElH1ifonHWV3MoXOefYsiY
|
||||
q5z2jfJzUi0JZVUKsveu9rQsFLsc//1s/I5T1LECgYEAldY6fNg2VVp63OZsuNU8
|
||||
oSiljbSwEyMh6Oe/nOkYkIKtr4AzrCoGt11piG7ohGW0lS9suMijnMqiquI+JP5+
|
||||
KyinLoUy761aR17nf+9e62mpkZw6hUqQTGi7Irs0SHUXhMpaCfDi/Ua9MiW+yVuB
|
||||
ds6+xBgeciZwWxMlXOwy2p0CgYEAm+YWiSK3Mq0fo7uEvBn9Fps2z+ciLoZNdppL
|
||||
n6gkMX2MaeQ3PVi/wxoRYX+tsL+c973yf2vwEnw0R7Dlutt6dc9VgxNWj4GE0GMe
|
||||
Tiao7Uom7Tf4p7wC9+r9rI/zOz2f8OxRIK18wtbShWfR5fx1dCWUXmGb3+jUse1O
|
||||
4Qk2FcECgYAvSvGFoJb8tuHFEYYHBbjficmvTUsrTE+EhxPqWKFhKfF19fFFIupy
|
||||
XBCrN6nwrh+/YMxZXeIRbbTTf814cOO7PjLeNhnfhJZkaJq1HzbYe3bOurna3qrm
|
||||
Ra3xiM8Ld2PyGnZPXf8+AWhMhuPkLX1KFVTCAxwCpmTZCHtiGCmXMA==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,71 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 4096 (0x1000)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
|
||||
Validity
|
||||
Not Before: Feb 7 21:53:19 2023 GMT
|
||||
Not After : Jun 25 21:53:19 2050 GMT
|
||||
Subject: CN=https-and-http.nginx-proxy.test
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:b7:97:85:d1:7f:6b:50:29:f3:87:b7:4e:f5:25:
|
||||
40:6a:d8:fa:a1:63:3c:4a:2e:68:4a:c6:8b:38:df:
|
||||
07:81:d0:08:9d:fc:17:f5:37:28:7f:31:e6:f3:81:
|
||||
28:4e:22:b6:bd:a2:4e:f2:2f:e5:0f:dd:55:3c:e1:
|
||||
04:84:4c:45:1b:1a:ae:b7:f0:2a:da:43:05:71:91:
|
||||
92:b8:d1:49:fe:80:0a:53:b9:66:da:54:60:9a:fc:
|
||||
e1:b2:e8:28:48:7f:96:94:3c:92:a3:b2:37:f6:7a:
|
||||
c2:de:0b:12:f0:ae:4e:92:fe:2d:c1:b2:95:28:1f:
|
||||
88:8d:79:99:81:19:ae:22:a4:95:f5:9f:db:25:8e:
|
||||
1d:cf:43:cd:6f:85:93:5f:79:ee:f8:f3:d4:82:e1:
|
||||
e9:4d:c9:ad:ae:5b:92:43:3a:3c:71:51:70:f7:3e:
|
||||
bd:1b:24:52:6a:a3:cf:54:72:57:ed:fe:72:ea:96:
|
||||
9b:5a:02:02:a7:df:85:b7:68:ae:1e:07:77:9f:59:
|
||||
a5:a0:8b:28:c2:c8:b7:bb:8a:42:50:df:05:73:bf:
|
||||
9c:55:13:b5:82:79:77:40:57:a4:8f:88:a5:71:50:
|
||||
d7:70:b0:4d:0c:d9:86:b3:9b:db:8a:20:bd:19:68:
|
||||
10:52:2d:53:ba:0e:2e:1c:ad:80:54:bb:b6:c9:ab:
|
||||
11:39
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:https-and-http.nginx-proxy.test
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
2c:f3:e5:47:3f:8e:5a:28:b1:df:e5:95:50:85:6f:27:2f:a6:
|
||||
8d:f1:5e:cf:df:e2:52:66:97:61:36:59:81:26:25:19:99:c9:
|
||||
93:e5:85:cb:ca:69:af:4b:21:a3:d2:7a:bf:b5:5e:2d:42:fb:
|
||||
99:f8:22:58:e5:bf:79:b8:8a:74:7e:c6:94:14:d9:f2:27:63:
|
||||
b6:e5:74:21:5b:59:fb:f6:c8:a9:28:fb:60:f7:5e:bd:c2:e6:
|
||||
74:24:14:96:61:95:6c:c2:66:b4:52:25:a1:85:5a:97:e5:68:
|
||||
5c:62:cf:69:3b:b0:a9:56:d8:e3:5f:74:dc:84:18:d5:3e:4f:
|
||||
c9:35:39:26:88:dc:9b:80:d9:40:e1:4f:09:27:8d:d2:89:55:
|
||||
30:91:02:86:35:04:95:1e:1d:58:14:5b:c6:e0:2e:a7:bf:a8:
|
||||
f6:2b:76:8a:4e:71:79:bc:c0:04:cd:db:81:73:46:ce:68:ed:
|
||||
25:b0:0e:42:8d:96:64:77:3b:f4:9d:1a:c9:f6:78:4c:56:4f:
|
||||
92:17:29:3d:80:50:71:77:4b:a8:29:c2:12:fc:ad:0a:37:81:
|
||||
38:4c:fb:54:99:4d:12:5f:98:dc:d1:a9:7b:08:45:c4:6f:7e:
|
||||
fe:00:e0:db:79:fe:d1:28:e3:8e:82:d1:fb:bc:0a:c4:42:93:
|
||||
c9:5e:eb:ba
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDFTCCAf2gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
|
||||
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
|
||||
ZDAgFw0yMzAyMDcyMTUzMTlaGA8yMDUwMDYyNTIxNTMxOVowKjEoMCYGA1UEAwwf
|
||||
aHR0cHMtYW5kLWh0dHAubmdpbngtcHJveHkudGVzdDCCASIwDQYJKoZIhvcNAQEB
|
||||
BQADggEPADCCAQoCggEBALeXhdF/a1Ap84e3TvUlQGrY+qFjPEouaErGizjfB4HQ
|
||||
CJ38F/U3KH8x5vOBKE4itr2iTvIv5Q/dVTzhBIRMRRsarrfwKtpDBXGRkrjRSf6A
|
||||
ClO5ZtpUYJr84bLoKEh/lpQ8kqOyN/Z6wt4LEvCuTpL+LcGylSgfiI15mYEZriKk
|
||||
lfWf2yWOHc9DzW+Fk1957vjz1ILh6U3Jra5bkkM6PHFRcPc+vRskUmqjz1RyV+3+
|
||||
cuqWm1oCAqffhbdorh4Hd59ZpaCLKMLIt7uKQlDfBXO/nFUTtYJ5d0BXpI+IpXFQ
|
||||
13CwTQzZhrOb24ogvRloEFItU7oOLhytgFS7tsmrETkCAwEAAaMuMCwwKgYDVR0R
|
||||
BCMwIYIfaHR0cHMtYW5kLWh0dHAubmdpbngtcHJveHkudGVzdDANBgkqhkiG9w0B
|
||||
AQsFAAOCAQEALPPlRz+OWiix3+WVUIVvJy+mjfFez9/iUmaXYTZZgSYlGZnJk+WF
|
||||
y8ppr0sho9J6v7VeLUL7mfgiWOW/ebiKdH7GlBTZ8idjtuV0IVtZ+/bIqSj7YPde
|
||||
vcLmdCQUlmGVbMJmtFIloYVal+VoXGLPaTuwqVbY41903IQY1T5PyTU5Jojcm4DZ
|
||||
QOFPCSeN0olVMJEChjUElR4dWBRbxuAup7+o9it2ik5xebzABM3bgXNGzmjtJbAO
|
||||
Qo2WZHc79J0ayfZ4TFZPkhcpPYBQcXdLqCnCEvytCjeBOEz7VJlNEl+Y3NGpewhF
|
||||
xG9+/gDg23n+0SjjjoLR+7wKxEKTyV7rug==
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAt5eF0X9rUCnzh7dO9SVAatj6oWM8Si5oSsaLON8HgdAInfwX
|
||||
9TcofzHm84EoTiK2vaJO8i/lD91VPOEEhExFGxqut/Aq2kMFcZGSuNFJ/oAKU7lm
|
||||
2lRgmvzhsugoSH+WlDySo7I39nrC3gsS8K5Okv4twbKVKB+IjXmZgRmuIqSV9Z/b
|
||||
JY4dz0PNb4WTX3nu+PPUguHpTcmtrluSQzo8cVFw9z69GyRSaqPPVHJX7f5y6pab
|
||||
WgICp9+Ft2iuHgd3n1mloIsowsi3u4pCUN8Fc7+cVRO1gnl3QFekj4ilcVDXcLBN
|
||||
DNmGs5vbiiC9GWgQUi1Tug4uHK2AVLu2yasROQIDAQABAoIBACT4KSVHoEdzOyvw
|
||||
GME6sB8T9Fw9TG2vrKaqFmzsVGmqh6Gwmu5xHgGG/fe44XHigaPsJDOWu2yXaEur
|
||||
ECrH5P6RP++gODDdYCI/ayk2U80g4XN8mR6L8Swkkhphr4Lx1lOhYvH9uFE05Tqr
|
||||
RjQbFY16C6K+oFSFDQ1YGDYsAqnM3RD7PH+lHpo8UN1TO/vogdSQEpMYZDwLAYnW
|
||||
uD5G3c0u2PsGu9YLuz2p8hcs3chh+cqKJWXOeW0JLrNGx1bqeQWkn6nXRDdRYi9V
|
||||
cJlTgDqGuF54bieSyq9ABDZQP4Ol+moYKDoIz5PwurNjcYSklrT1tw0gqHZoQK1L
|
||||
fDjw3QECgYEA7QMRU1AFKTvO7/8WLHLN5BT63n31wm0e9PYpz/XVLWEfxBcp9Xmf
|
||||
xAIhXZ/U9P4dfNqxTjN9mVGzCHh5KfDJnUFqOXFy/zvfMeRzJf6dJo6/4OX9Bijr
|
||||
Tgd454vyGXYQP2t+F14UAwl6vlGOAjttiP5qY5Ef1gllBEeIPe9Ts9kCgYEAxkzZ
|
||||
pq4HJ/5/iDquMEHXNXzpNPavSvgxQdl1ILvJ49LJImmQFBCP9PqiOTIfePz1OqUI
|
||||
C4baFuc0FEDJ3x9CUNmMY1lEi2ZUq2agPSXaQNsMcKtEJH8SoJlJIRpkQA7unX09
|
||||
zb4dam6g79OaGmb8scePuezXMLv1Ee6WWtXbzGECgYEA6PYn9Gzl9cacu9dOUzgw
|
||||
2ewpPcIvawDY+cxwAsHO3MDneVWPX4JBoGa7pwvwRTL1hwBqYMRJwwbD5CKObcQI
|
||||
V/KxV28Eqo2N77tt1z2x9/E99u/4yTI1P0gm9ejfeVlL1RpyIMPPBcEujZ0Z6WXC
|
||||
X3I63k0KLtajHRa2erIf4tkCgYAfunAgwTuX5JqXO3xfcEl033WY6deGUUvgU2Dw
|
||||
Sdu1viY8gVNyQmwmMGwAZsquWxsJtRoibgM7IucsTml+b8v2j7hstP3IqCjn+9Wr
|
||||
swDG28WTyXNvu31JgP04dLaRoVIAlOdsofym6OiLNvozO0M3VsziXMjZnVlK8zfP
|
||||
dORkQQKBgQDXAJEJPygxVA+bF104dzCMWGmU7K8ShEWC5eOdKK4KWf9bNDpY6M6c
|
||||
i6zga/xBbj7e3Bxqprpp8Wy2gIsnYiVo4V9EQethbLdomPxOpBMNMARw81rL1CpO
|
||||
jbHB7bIDcKs2tQoZEXUW86ZxC8sdaDaWTJTfUO0RpJow6ZO3yvxVIQ==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,71 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 4096 (0x1000)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
|
||||
Validity
|
||||
Not Before: Feb 7 21:53:49 2023 GMT
|
||||
Not After : Jun 25 21:53:49 2050 GMT
|
||||
Subject: CN=https-only.nginx-proxy.test
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:d9:87:48:02:85:f4:5f:0d:90:7e:4c:4f:13:89:
|
||||
41:ca:41:15:c2:6f:fd:a8:c7:17:83:c6:dd:8c:fe:
|
||||
19:a4:b2:6b:0b:35:4f:b4:3d:7c:40:0a:04:33:2a:
|
||||
fd:10:72:f7:63:63:99:5b:3d:ec:78:ee:c6:4d:c8:
|
||||
0e:4c:be:f2:3f:e3:02:74:57:9a:c1:fe:15:95:63:
|
||||
4e:e7:2c:eb:70:f2:6b:c8:ba:01:a2:ca:a1:c7:76:
|
||||
ff:38:e4:c2:b0:66:fc:85:d2:af:0f:22:81:d4:82:
|
||||
eb:d5:b0:e6:69:14:37:dd:8d:ad:29:ce:93:68:5a:
|
||||
ce:f4:77:76:6f:78:13:b6:c8:2f:fe:e0:b6:7e:fb:
|
||||
29:16:be:e2:f5:45:3b:39:5b:52:dc:26:b7:ca:0c:
|
||||
b6:1c:fc:a8:38:0b:dd:c1:f4:04:9b:2d:38:c9:a5:
|
||||
2d:3e:f1:42:88:53:a2:3b:17:cf:d5:3c:2b:d6:6a:
|
||||
7f:6f:05:8d:c5:b7:5d:64:1e:83:1b:e7:ec:80:3d:
|
||||
6d:34:c1:66:b2:e6:5d:d9:a7:6e:46:75:14:bf:10:
|
||||
16:c5:fc:47:8e:63:fa:e5:b4:bd:f2:b9:e0:cb:ea:
|
||||
75:f9:68:ee:7d:8f:ea:8f:1a:9f:34:27:7a:4a:9f:
|
||||
85:fd:3e:17:a7:96:c3:d0:4e:50:a2:a2:e0:45:92:
|
||||
d0:b5
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:https-only.nginx-proxy.test
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
8a:52:46:42:a9:74:18:6a:52:90:ef:a4:e9:c5:54:d5:97:3a:
|
||||
ff:8b:c2:76:4f:9e:47:aa:e1:ea:e5:b9:af:9d:33:e3:85:17:
|
||||
54:7d:32:bd:ac:90:3f:5c:d2:a1:42:17:52:2b:b1:83:e5:c3:
|
||||
bf:81:f0:e7:38:e2:88:67:7b:d8:59:fe:f9:94:99:ba:be:f4:
|
||||
3c:24:b2:c7:9e:f0:98:21:c6:2d:c2:e8:f3:67:bd:62:00:aa:
|
||||
ce:34:fa:b4:53:6d:c1:09:5e:55:bd:43:aa:86:c6:f8:c5:83:
|
||||
46:3a:49:12:a2:ec:30:36:0c:99:44:74:09:9d:cc:4b:98:1f:
|
||||
7e:c9:9b:68:a0:f8:1e:00:14:d0:da:2a:bf:c8:ca:a8:1c:10:
|
||||
b5:68:a2:f1:41:93:0c:f3:3f:c0:c6:53:3c:8d:a7:dd:a5:7b:
|
||||
35:cc:44:e0:5b:6d:c5:cb:33:6f:c1:43:7e:06:df:21:99:11:
|
||||
b3:91:41:b4:5e:f0:37:1e:8e:e5:73:85:dc:4a:21:d5:41:f9:
|
||||
4e:b8:f5:ed:21:93:09:91:c2:8c:6b:04:a4:84:ab:3a:fe:35:
|
||||
64:fa:6b:a7:8d:40:a6:64:89:30:84:ac:28:99:5a:01:79:77:
|
||||
c0:df:88:da:a9:75:5f:c4:51:ae:a8:45:7b:d2:e1:a2:81:29:
|
||||
60:cd:7b:cd
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDDTCCAfWgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
|
||||
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
|
||||
ZDAgFw0yMzAyMDcyMTUzNDlaGA8yMDUwMDYyNTIxNTM0OVowJjEkMCIGA1UEAwwb
|
||||
aHR0cHMtb25seS5uZ2lueC1wcm94eS50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEA2YdIAoX0Xw2QfkxPE4lBykEVwm/9qMcXg8bdjP4ZpLJrCzVP
|
||||
tD18QAoEMyr9EHL3Y2OZWz3seO7GTcgOTL7yP+MCdFeawf4VlWNO5yzrcPJryLoB
|
||||
osqhx3b/OOTCsGb8hdKvDyKB1ILr1bDmaRQ33Y2tKc6TaFrO9Hd2b3gTtsgv/uC2
|
||||
fvspFr7i9UU7OVtS3Ca3ygy2HPyoOAvdwfQEmy04yaUtPvFCiFOiOxfP1Twr1mp/
|
||||
bwWNxbddZB6DG+fsgD1tNMFmsuZd2aduRnUUvxAWxfxHjmP65bS98rngy+p1+Wju
|
||||
fY/qjxqfNCd6Sp+F/T4Xp5bD0E5QoqLgRZLQtQIDAQABoyowKDAmBgNVHREEHzAd
|
||||
ghtodHRwcy1vbmx5Lm5naW54LXByb3h5LnRlc3QwDQYJKoZIhvcNAQELBQADggEB
|
||||
AIpSRkKpdBhqUpDvpOnFVNWXOv+LwnZPnkeq4erlua+dM+OFF1R9Mr2skD9c0qFC
|
||||
F1IrsYPlw7+B8Oc44ohne9hZ/vmUmbq+9Dwkssee8Jghxi3C6PNnvWIAqs40+rRT
|
||||
bcEJXlW9Q6qGxvjFg0Y6SRKi7DA2DJlEdAmdzEuYH37Jm2ig+B4AFNDaKr/Iyqgc
|
||||
ELVoovFBkwzzP8DGUzyNp92lezXMROBbbcXLM2/BQ34G3yGZEbORQbRe8DcejuVz
|
||||
hdxKIdVB+U649e0hkwmRwoxrBKSEqzr+NWT6a6eNQKZkiTCErCiZWgF5d8DfiNqp
|
||||
dV/EUa6oRXvS4aKBKWDNe80=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA2YdIAoX0Xw2QfkxPE4lBykEVwm/9qMcXg8bdjP4ZpLJrCzVP
|
||||
tD18QAoEMyr9EHL3Y2OZWz3seO7GTcgOTL7yP+MCdFeawf4VlWNO5yzrcPJryLoB
|
||||
osqhx3b/OOTCsGb8hdKvDyKB1ILr1bDmaRQ33Y2tKc6TaFrO9Hd2b3gTtsgv/uC2
|
||||
fvspFr7i9UU7OVtS3Ca3ygy2HPyoOAvdwfQEmy04yaUtPvFCiFOiOxfP1Twr1mp/
|
||||
bwWNxbddZB6DG+fsgD1tNMFmsuZd2aduRnUUvxAWxfxHjmP65bS98rngy+p1+Wju
|
||||
fY/qjxqfNCd6Sp+F/T4Xp5bD0E5QoqLgRZLQtQIDAQABAoIBAAWs//YA5MVuJy0E
|
||||
dLO/yxWp6RVvsqCqwTRRBgrdvnGLrjtWosPDLvDE0iM7peq99TKEsMWusfLd2BLD
|
||||
e4wJF20PUUsT1hflt050juR9SY9i4+kS4WQMAXig5DvpzCKqLUCYpLSyY8zVta2X
|
||||
tgtb2bFQNwp2N2ZrqCa8zzxNV8ZXGoW+ZlvBJEDtBwt1DCDhY39/pqHfIhFl4Vwk
|
||||
YhhbVjID145D1j/fP6vLceM2YA4uRmF1itj1iQ6YNNpXRspUGE4DXdqR6HcbduiX
|
||||
trZjmdtKXY8mJg6jyLZxYbjFlKV/LvqKRYF3Jb9K0vdd4juBdZoy7DQzoLhcnzui
|
||||
pEnPLakCgYEA9tN6KdQGKGBXGuF+ZqhXfB/XSkKUf8o/5j62cbu11ZIJ+iEBx+d6
|
||||
lQAxTz5hHUL6a3c5qiM+AWBxYuFD6oqptIlTlBfIXI978neDNvEWWffivPvQLbt9
|
||||
o9ohOirfK1iGPvtrpAwjv5ylE5SiTmJ/6wDvQWjNGAnJ3aaxkesJUSMCgYEA4Z0K
|
||||
UHZVtnKLtzzIY7KfLbuKF/fJEDfMNr4Wgl6ny21vqO9kJGmA7SaoNdhx8RDcKmeV
|
||||
/Vey4ug6YlOG48eapKLTthdRz5mx+jIkUfdOhj81m28xm/OPTqCrviTHCNOHeYDy
|
||||
NKAIlJMo2z0vTKJn5eP6CsYmDWLpHQNyXY5qcEcCgYAzDBWt5O3JF/Or2Yr8zEAb
|
||||
qbIq544yx69jfQDakMnQe72Yf48Quuz9N+b6zpnjJWEJLMU+TL+cJUgN/SzAqyDh
|
||||
96zTaf/ENOCbiuAWUtIelUfNcf7iFm6rnodUsl0pZ8uL5w+iA+i4zjrNy+WtdG2k
|
||||
OrNAwd345L1dHAaJeSSaJQKBgQCUnF3r7Fa/TCpt87LHwSQK+sqWyRf+/9IbiRDI
|
||||
pVL/s8FmVPHw7jIHhHwuo7lCImnz4LGy5C6oOnIizIRAy/04Ty0Hd8ri5YmPlbHI
|
||||
8A8gbMiB7zeNU1zlXP5jzFPyo2tMhLyGH5gnTdwOtfnPD/dCPe45ZJYyISIOg3O0
|
||||
3peMBwKBgH20cskAOCNclfoG+Nis52h8FqmDlflJ8waUarvk26JhO1e009kOytw8
|
||||
x/qSuttpGtTG+4fdc2wJvFNczr4h9ZlftBdgZXj8PKgRpcIe8q97Xg8PUj+Xfu/t
|
||||
vD/QV+tVcGoAMsQq4NeFxiTbPfwVyXdYFT1XVCu6JEdLL+gpWh5W
|
||||
-----END RSA PRIVATE KEY-----
|
36
test/test_fallback.data/withdefault.yml
Normal file
36
test/test_fallback.data/withdefault.yml
Normal file
|
@ -0,0 +1,36 @@
|
|||
services:
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./withdefault.certs:/etc/nginx/certs:ro
|
||||
https-and-http:
|
||||
image: web
|
||||
expose:
|
||||
- "81"
|
||||
environment:
|
||||
WEB_PORTS: "81"
|
||||
VIRTUAL_HOST: https-and-http.nginx-proxy.test
|
||||
https-only:
|
||||
image: web
|
||||
expose:
|
||||
- "82"
|
||||
environment:
|
||||
WEB_PORTS: "82"
|
||||
VIRTUAL_HOST: https-only.nginx-proxy.test
|
||||
HTTPS_METHOD: nohttp
|
||||
http-only:
|
||||
image: web
|
||||
expose:
|
||||
- "83"
|
||||
environment:
|
||||
WEB_PORTS: "83"
|
||||
VIRTUAL_HOST: http-only.nginx-proxy.test
|
||||
HTTPS_METHOD: nohttps
|
||||
missing-cert:
|
||||
image: web
|
||||
expose:
|
||||
- "84"
|
||||
environment:
|
||||
WEB_PORTS: "84"
|
||||
VIRTUAL_HOST: missing-cert.nginx-proxy.test
|
104
test/test_fallback.py
Normal file
104
test/test_fallback.py
Normal file
|
@ -0,0 +1,104 @@
|
|||
import os.path
|
||||
import re
|
||||
|
||||
import backoff
|
||||
import pytest
|
||||
import requests
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def data_dir():
|
||||
return f"{os.path.splitext(__file__)[0]}.data"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def docker_compose_file(data_dir, compose_file):
|
||||
return os.path.join(data_dir, compose_file)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def get(docker_compose, nginxproxy, want_err_re):
|
||||
|
||||
@backoff.on_exception(
|
||||
backoff.constant,
|
||||
requests.exceptions.RequestException,
|
||||
giveup=lambda e: want_err_re and want_err_re.search(str(e)),
|
||||
interval=.3,
|
||||
max_tries=30,
|
||||
jitter=None)
|
||||
def _get(url):
|
||||
return nginxproxy.get(url, allow_redirects=False)
|
||||
|
||||
return _get
|
||||
|
||||
|
||||
INTERNAL_ERR_RE = re.compile("TLSV1_ALERT_INTERNAL_ERROR")
|
||||
CONNECTION_REFUSED_RE = re.compile("Connection refused")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("compose_file,url,want_code,want_err_re", [
|
||||
# Has default.crt.
|
||||
("withdefault.yml", "http://https-and-http.nginx-proxy.test/", 301, None),
|
||||
("withdefault.yml", "https://https-and-http.nginx-proxy.test/", 200, None),
|
||||
("withdefault.yml", "http://https-only.nginx-proxy.test/", 503, None),
|
||||
("withdefault.yml", "https://https-only.nginx-proxy.test/", 200, None),
|
||||
("withdefault.yml", "http://http-only.nginx-proxy.test/", 200, None),
|
||||
("withdefault.yml", "https://http-only.nginx-proxy.test/", 503, None),
|
||||
("withdefault.yml", "http://missing-cert.nginx-proxy.test/", 200, None),
|
||||
("withdefault.yml", "https://missing-cert.nginx-proxy.test/", 500, None),
|
||||
("withdefault.yml", "http://unknown.nginx-proxy.test/", 503, None),
|
||||
("withdefault.yml", "https://unknown.nginx-proxy.test/", 503, None),
|
||||
# Same as withdefault.yml, except there is no default.crt.
|
||||
("nodefault.yml", "http://https-and-http.nginx-proxy.test/", 301, None),
|
||||
("nodefault.yml", "https://https-and-http.nginx-proxy.test/", 200, None),
|
||||
("nodefault.yml", "http://https-only.nginx-proxy.test/", 503, None),
|
||||
("nodefault.yml", "https://https-only.nginx-proxy.test/", 200, None),
|
||||
("nodefault.yml", "http://http-only.nginx-proxy.test/", 200, None),
|
||||
("nodefault.yml", "https://http-only.nginx-proxy.test/", None, INTERNAL_ERR_RE),
|
||||
("nodefault.yml", "http://missing-cert.nginx-proxy.test/", 200, None),
|
||||
("nodefault.yml", "https://missing-cert.nginx-proxy.test/", None, INTERNAL_ERR_RE),
|
||||
("nodefault.yml", "http://unknown.nginx-proxy.test/", 503, None),
|
||||
("nodefault.yml", "https://unknown.nginx-proxy.test/", None, INTERNAL_ERR_RE),
|
||||
# HTTPS_METHOD=nohttp on nginx-proxy, HTTPS_METHOD unset on the app container.
|
||||
("nohttp.yml", "http://https-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
|
||||
("nohttp.yml", "https://https-only.nginx-proxy.test/", 200, None),
|
||||
("nohttp.yml", "http://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
|
||||
("nohttp.yml", "https://unknown.nginx-proxy.test/", 503, None),
|
||||
# HTTPS_METHOD=redirect on nginx-proxy, HTTPS_METHOD=nohttp on the app container.
|
||||
("nohttp-on-app.yml", "http://https-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
|
||||
("nohttp-on-app.yml", "https://https-only.nginx-proxy.test/", 200, None),
|
||||
("nohttp-on-app.yml", "http://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
|
||||
("nohttp-on-app.yml", "https://unknown.nginx-proxy.test/", 503, None),
|
||||
# Same as nohttp.yml, except there is a vhost with a missing cert. This causes its
|
||||
# HTTPS_METHOD=nohttp setting to effectively become HTTPS_METHOD=noredirect. This means that
|
||||
# there will be a plain http server solely to support that vhost, so http requests to other
|
||||
# vhosts get a 503, not a connection refused error.
|
||||
("nohttp-with-missing-cert.yml", "http://https-only.nginx-proxy.test/", 503, None),
|
||||
("nohttp-with-missing-cert.yml", "https://https-only.nginx-proxy.test/", 200, None),
|
||||
("nohttp-with-missing-cert.yml", "http://missing-cert.nginx-proxy.test/", 200, None),
|
||||
("nohttp-with-missing-cert.yml", "https://missing-cert.nginx-proxy.test/", 500, None),
|
||||
("nohttp-with-missing-cert.yml", "http://unknown.nginx-proxy.test/", 503, None),
|
||||
("nohttp-with-missing-cert.yml", "https://unknown.nginx-proxy.test/", 503, None),
|
||||
# HTTPS_METHOD=nohttps on nginx-proxy, HTTPS_METHOD unset on the app container.
|
||||
("nohttps.yml", "http://http-only.nginx-proxy.test/", 200, None),
|
||||
("nohttps.yml", "https://http-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
|
||||
("nohttps.yml", "http://unknown.nginx-proxy.test/", 503, None),
|
||||
("nohttps.yml", "https://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
|
||||
# HTTPS_METHOD=redirect on nginx-proxy, HTTPS_METHOD=nohttps on the app container.
|
||||
("nohttps-on-app.yml", "http://http-only.nginx-proxy.test/", 200, None),
|
||||
("nohttps-on-app.yml", "https://http-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
|
||||
("nohttps-on-app.yml", "http://unknown.nginx-proxy.test/", 503, None),
|
||||
("nohttps-on-app.yml", "https://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
|
||||
# Custom nginx config that has a `server` directive that uses `default_server` and simply
|
||||
# returns 418. Nginx should successfully start (in particular, the `default_server` in the
|
||||
# custom config should not conflict with the fallback server generated by nginx-proxy) and nginx
|
||||
# should prefer that server for handling requests for unknown vhosts.
|
||||
("custom-fallback.yml", "http://unknown.nginx-proxy.test/", 418, None),
|
||||
])
|
||||
def test_fallback(get, url, want_code, want_err_re):
|
||||
if want_err_re is None:
|
||||
r = get(url)
|
||||
assert r.status_code == want_code
|
||||
else:
|
||||
with pytest.raises(requests.exceptions.RequestException, match=want_err_re):
|
||||
get(url)
|
|
@ -30,6 +30,19 @@ def test_X_Forwarded_Proto_is_passed_on(docker_compose, nginxproxy):
|
|||
assert "X-Forwarded-Proto: f00\n" in r.text
|
||||
|
||||
|
||||
##### Testing the handling of X-Forwarded-Host #####
|
||||
|
||||
def test_X_Forwarded_Host_is_generated(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://web.nginx-proxy.tld/headers")
|
||||
assert r.status_code == 200
|
||||
assert "X-Forwarded-Host: web.nginx-proxy.tld\n" in r.text
|
||||
|
||||
def test_X_Forwarded_Host_is_passed_on(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://web.nginx-proxy.tld/headers", headers={'X-Forwarded-Host': 'example.com'})
|
||||
assert r.status_code == 200
|
||||
assert "X-Forwarded-Host: example.com\n" in r.text
|
||||
|
||||
|
||||
##### Testing the handling of X-Forwarded-Port #####
|
||||
|
||||
def test_X_Forwarded_Port_is_generated(docker_compose, nginxproxy):
|
||||
|
|
|
@ -33,6 +33,19 @@ def test_X_Forwarded_Proto_is_passed_on(docker_compose, nginxproxy):
|
|||
assert "X-Forwarded-Proto: f00\n" in r.text
|
||||
|
||||
|
||||
##### Testing the handling of X-Forwarded-Host #####
|
||||
|
||||
def test_X_Forwarded_Host_is_generated(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("https://web.nginx-proxy.tld/headers")
|
||||
assert r.status_code == 200
|
||||
assert "X-Forwarded-Host: web.nginx-proxy.tld\n" in r.text
|
||||
|
||||
def test_X_Forwarded_Host_is_passed_on(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("https://web.nginx-proxy.tld/headers", headers={'X-Forwarded-Host': 'example.com'})
|
||||
assert r.status_code == 200
|
||||
assert "X-Forwarded-Host: example.com\n" in r.text
|
||||
|
||||
|
||||
##### Testing the handling of X-Forwarded-Port #####
|
||||
|
||||
def test_X_Forwarded_Port_is_generated(docker_compose, nginxproxy):
|
||||
|
|
31
test/test_keepalive.py
Normal file
31
test/test_keepalive.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
import re
|
||||
|
||||
|
||||
def test_keepalive_disabled(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://keepalive-disabled.nginx-proxy.test/headers")
|
||||
assert r.status_code == 200
|
||||
assert re.search(fr'(?m)^(?i:Connection): close$', r.text)
|
||||
|
||||
def test_keepalive_disabled_other_headers_ok(docker_compose, nginxproxy):
|
||||
"""Make sure the other proxy_set_header headers are still set.
|
||||
|
||||
According to the nginx docs [1], any proxy_set_header directive in a block
|
||||
disables inheritance of proxy_set_header directives in a parent block. Make
|
||||
sure that doesn't happen.
|
||||
|
||||
[1] https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
|
||||
"""
|
||||
r = nginxproxy.get("http://keepalive-disabled.nginx-proxy.test/headers")
|
||||
assert r.status_code == 200
|
||||
assert re.search(fr'(?m)^(?i:X-Real-IP): ', r.text)
|
||||
|
||||
def test_keepalive_enabled(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://keepalive-enabled.nginx-proxy.test/headers")
|
||||
assert r.status_code == 200
|
||||
assert not re.search(fr'(?m)^(?i:Connection):', r.text)
|
||||
|
||||
def test_keepalive_enabled_other_headers_ok(docker_compose, nginxproxy):
|
||||
"""See the docstring for the disabled case above."""
|
||||
r = nginxproxy.get("http://keepalive-enabled.nginx-proxy.test/headers")
|
||||
assert r.status_code == 200
|
||||
assert re.search(fr'(?m)^(?i:X-Real-IP): ', r.text)
|
25
test/test_keepalive.yml
Normal file
25
test/test_keepalive.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
keepalive-disabled:
|
||||
image: web
|
||||
expose:
|
||||
- "80"
|
||||
environment:
|
||||
WEB_PORTS: 80
|
||||
VIRTUAL_HOST: keepalive-disabled.nginx-proxy.test
|
||||
|
||||
keepalive-enabled:
|
||||
image: web
|
||||
expose:
|
||||
- "80"
|
||||
environment:
|
||||
WEB_PORTS: 80
|
||||
VIRTUAL_HOST: keepalive-enabled.nginx-proxy.test
|
||||
labels:
|
||||
com.github.nginx-proxy.nginx-proxy.keepalive: "64"
|
||||
|
||||
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
environment:
|
||||
HTTPS_METHOD: nohttps
|
16
test/test_loadbalancing.py
Normal file
16
test/test_loadbalancing.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
import pytest
|
||||
import re
|
||||
|
||||
def test_loadbalance_hash(docker_compose, nginxproxy):
|
||||
conf = nginxproxy.get_conf().decode('ASCII')
|
||||
r1 = nginxproxy.get("http://loadbalance-enabled.nginx-proxy.tld")
|
||||
r2 = nginxproxy.get("http://loadbalance-enabled.nginx-proxy.tld")
|
||||
assert re.search(r"hash \$remote_addr\;", conf)
|
||||
assert r1.status_code == 200
|
||||
assert r2.text == r1.text
|
||||
|
||||
def test_loadbalance_roundrobin(docker_compose, nginxproxy):
|
||||
r1 = nginxproxy.get("http://loadbalance-disabled.nginx-proxy.tld")
|
||||
r2 = nginxproxy.get("http://loadbalance-disabled.nginx-proxy.tld")
|
||||
assert r1.status_code == 200
|
||||
assert r2.text != r1.text
|
27
test/test_loadbalancing.yml
Normal file
27
test/test_loadbalancing.yml
Normal file
|
@ -0,0 +1,27 @@
|
|||
services:
|
||||
loadbalance-hash:
|
||||
image: web
|
||||
expose:
|
||||
- "81"
|
||||
environment:
|
||||
WEB_PORTS: 81
|
||||
VIRTUAL_HOST: loadbalance-enabled.nginx-proxy.tld
|
||||
labels:
|
||||
com.github.nginx-proxy.nginx-proxy.loadbalance: "hash $$remote_addr;"
|
||||
deploy:
|
||||
replicas: 2
|
||||
|
||||
loadbalance-roundrobin:
|
||||
image: web
|
||||
expose:
|
||||
- "82"
|
||||
environment:
|
||||
WEB_PORTS: 82
|
||||
VIRTUAL_HOST: loadbalance-disabled.nginx-proxy.tld
|
||||
deploy:
|
||||
replicas: 2
|
||||
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
39
test/test_location-override.py
Normal file
39
test/test_location-override.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
def test_explicit_root_nohash(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://explicit-root-nohash.nginx-proxy.test/port")
|
||||
assert r.status_code == 418
|
||||
r = nginxproxy.get("http://explicit-root-nohash.nginx-proxy.test/foo/port")
|
||||
assert r.status_code == 200
|
||||
assert r.text == "answer from port 82\n"
|
||||
|
||||
def test_explicit_root_hash(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://explicit-root-hash.nginx-proxy.test/port")
|
||||
assert r.status_code == 418
|
||||
r = nginxproxy.get("http://explicit-root-hash.nginx-proxy.test/foo/port")
|
||||
assert r.status_code == 200
|
||||
assert r.text == "answer from port 82\n"
|
||||
|
||||
def test_explicit_root_hash_and_nohash(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://explicit-root-hash-and-nohash.nginx-proxy.test/port")
|
||||
assert r.status_code == 418
|
||||
r = nginxproxy.get("http://explicit-root-hash-and-nohash.nginx-proxy.test/foo/port")
|
||||
assert r.status_code == 200
|
||||
assert r.text == "answer from port 82\n"
|
||||
|
||||
def test_explicit_nonroot(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://explicit-nonroot.nginx-proxy.test/port")
|
||||
assert r.status_code == 200
|
||||
assert r.text == "answer from port 81\n"
|
||||
r = nginxproxy.get("http://explicit-nonroot.nginx-proxy.test/foo/port")
|
||||
assert r.status_code == 418
|
||||
|
||||
def test_implicit_root_nohash(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://implicit-root-nohash.nginx-proxy.test/port")
|
||||
assert r.status_code == 418
|
||||
|
||||
def test_implicit_root_hash(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://implicit-root-hash.nginx-proxy.test/port")
|
||||
assert r.status_code == 418
|
||||
|
||||
def test_implicit_root_hash_and_nohash(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://implicit-root-hash-and-nohash.nginx-proxy.test/port")
|
||||
assert r.status_code == 418
|
|
@ -0,0 +1,3 @@
|
|||
location /foo/ {
|
||||
return 418;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
# This file should trump the file without the hash.
|
||||
location / {
|
||||
return 418;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
# The file with the hash should trump this file.
|
||||
location / {
|
||||
return 503;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
location / {
|
||||
return 418;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
location / {
|
||||
return 418;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
# This file should trump the file without the hash.
|
||||
location / {
|
||||
return 418;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
# The file with the hash should trump this file.
|
||||
location / {
|
||||
return 503;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
location / {
|
||||
return 418;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
location / {
|
||||
return 418;
|
||||
}
|
44
test/test_location-override.yml
Normal file
44
test/test_location-override.yml
Normal file
|
@ -0,0 +1,44 @@
|
|||
services:
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./test_location-override.vhost.d:/etc/nginx/vhost.d:ro
|
||||
|
||||
explicit-root:
|
||||
image: web
|
||||
expose:
|
||||
- "81"
|
||||
environment:
|
||||
WEB_PORTS: "81"
|
||||
VIRTUAL_HOST: >-
|
||||
explicit-root-nohash.nginx-proxy.test,
|
||||
explicit-root-hash.nginx-proxy.test,
|
||||
explicit-root-hash-and-nohash.nginx-proxy.test,
|
||||
explicit-nonroot.nginx-proxy.test
|
||||
VIRTUAL_PATH: /
|
||||
explicit-foo:
|
||||
image: web
|
||||
expose:
|
||||
- "82"
|
||||
environment:
|
||||
WEB_PORTS: "82"
|
||||
VIRTUAL_HOST: >-
|
||||
explicit-root-nohash.nginx-proxy.test,
|
||||
explicit-root-hash.nginx-proxy.test,
|
||||
explicit-root-hash-and-nohash.nginx-proxy.test,
|
||||
explicit-nonroot.nginx-proxy.test
|
||||
VIRTUAL_PATH: /foo/
|
||||
VIRTUAL_DEST: /
|
||||
|
||||
# Same as explicit-root except VIRTUAL_PATH is left unset.
|
||||
implicit-root:
|
||||
image: web
|
||||
expose:
|
||||
- "83"
|
||||
environment:
|
||||
WEB_PORTS: "83"
|
||||
VIRTUAL_HOST: >-
|
||||
implicit-root-nohash.nginx-proxy.test,
|
||||
implicit-root-hash.nginx-proxy.test,
|
||||
implicit-root-hash-and-nohash.nginx-proxy.test,
|
11
test/test_log_format.py
Normal file
11
test/test_log_format.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
import pytest
|
||||
|
||||
def test_log_format(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://nginx-proxy.test/port")
|
||||
assert r.status_code == 200
|
||||
assert r.text == "answer from port 81\n"
|
||||
sut_container = docker_compose.containers.get("sut")
|
||||
docker_logs = sut_container.logs(stdout=True, stderr=True, stream=False, follow=False)
|
||||
docker_logs = docker_logs.decode("utf-8").splitlines()
|
||||
docker_logs = [line for line in docker_logs if "GET /port" in line]
|
||||
assert "request_time=" in docker_logs[0]
|
15
test/test_log_format.yml
Normal file
15
test/test_log_format.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
web1:
|
||||
image: web
|
||||
expose:
|
||||
- "81"
|
||||
environment:
|
||||
WEB_PORTS: 81
|
||||
VIRTUAL_HOST: nginx-proxy.test
|
||||
|
||||
sut:
|
||||
container_name: sut
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
environment:
|
||||
LOG_FORMAT: "$$remote_addr - $$remote_user [$$time_local] \"$$request\" $$status $$body_bytes_sent \"$$http_referer\" \"$$http_user_agent\" request_time=$$request_time $$upstream_response_time"
|
|
@ -1,15 +1,28 @@
|
|||
import re
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_unknown_virtual_host(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://nginx-proxy/")
|
||||
assert r.status_code == 503
|
||||
|
||||
def test_forwards_to_web1(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://web1.nginx-proxy.local/port")
|
||||
assert r.status_code == 200
|
||||
assert r.status_code == 200
|
||||
assert r.text == "answer from port 81\n"
|
||||
|
||||
def test_forwards_to_web2(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://web2.nginx-proxy.local/port")
|
||||
assert r.status_code == 200
|
||||
assert r.text == "answer from port 82\n"
|
||||
assert r.status_code == 200
|
||||
assert r.text == "answer from port 82\n"
|
||||
|
||||
def test_multipath(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://web3.nginx-proxy.test/port")
|
||||
assert r.status_code == 200
|
||||
assert r.text == "answer from port 83\n"
|
||||
cfg = nginxproxy.get_conf().decode()
|
||||
lines = cfg.splitlines()
|
||||
web3_server_lines = [l for l in lines
|
||||
if re.search(r'(?m)^\s*server\s+[^\s]*:83;\s*$', l)]
|
||||
assert len(web3_server_lines) == 1
|
||||
|
|
|
@ -3,6 +3,8 @@ version: '2'
|
|||
networks:
|
||||
net1: {}
|
||||
net2: {}
|
||||
net3a: {}
|
||||
net3b: {}
|
||||
|
||||
services:
|
||||
nginx-proxy:
|
||||
|
@ -12,6 +14,8 @@ services:
|
|||
networks:
|
||||
- net1
|
||||
- net2
|
||||
- net3a
|
||||
- net3b
|
||||
|
||||
web1:
|
||||
image: web
|
||||
|
@ -32,3 +36,14 @@ services:
|
|||
VIRTUAL_HOST: web2.nginx-proxy.local
|
||||
networks:
|
||||
- net2
|
||||
|
||||
web3:
|
||||
image: web
|
||||
expose:
|
||||
- "83"
|
||||
environment:
|
||||
WEB_PORTS: 83
|
||||
VIRTUAL_HOST: web3.nginx-proxy.test
|
||||
networks:
|
||||
- net3a
|
||||
- net3b
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import re
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
import backoff
|
||||
import docker
|
||||
|
@ -219,7 +218,7 @@ def test_custom_dhparam_is_supported(docker_compose):
|
|||
|
||||
# Only `web2` has a site-specific DH param file (which overrides all other DH config)
|
||||
# Other tests here use `web5` explicitly, or implicitly (via ENV `DEFAULT_HOST`, otherwise first HTTPS server)
|
||||
def test_custom_dhparam_is_supported_per_site(docker_compose):
|
||||
def test_custom_dhparam_is_supported_per_site(docker_compose, ca_root_certificate):
|
||||
container_name="dh-file"
|
||||
sut_container = docker_client.containers.get(container_name)
|
||||
assert sut_container.status == "running"
|
||||
|
@ -242,7 +241,7 @@ def test_custom_dhparam_is_supported_per_site(docker_compose):
|
|||
# - `web2` has it's own cert provisioned at `/etc/nginx/certs/web2.nginx-proxy.tld.crt`.
|
||||
can_verify_chain_of_trust(
|
||||
sut_container,
|
||||
ca_cert = f"{os.getcwd()}/certs/ca-root.crt",
|
||||
ca_cert = ca_root_certificate,
|
||||
fqdn = 'web2.nginx-proxy.tld'
|
||||
)
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import pytest
|
||||
import requests
|
||||
|
||||
|
||||
def test_web2_http_is_not_forwarded(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://web2.nginx-proxy.tld/", allow_redirects=False)
|
||||
assert r.status_code == 503
|
||||
def test_web2_http_is_connection_refused(docker_compose, nginxproxy):
|
||||
with pytest.raises(requests.exceptions.RequestException, match="Connection refused"):
|
||||
nginxproxy.get("http://web2.nginx-proxy.tld/")
|
||||
|
||||
|
||||
def test_web2_https_is_forwarded(docker_compose, nginxproxy):
|
||||
|
|
|
@ -24,10 +24,10 @@ def test_https_get_served(docker_compose, nginxproxy, subdomain):
|
|||
assert f"answer from port 8{subdomain}\n" == r.text
|
||||
|
||||
@pytest.mark.filterwarnings('ignore::urllib3.exceptions.InsecureRequestWarning')
|
||||
def test_web3_https_is_500_and_SSL_validation_fails(docker_compose, nginxproxy):
|
||||
def test_https_request_to_nohttps_vhost_goes_to_fallback_server(docker_compose, nginxproxy):
|
||||
with pytest.raises( (CertificateError, SSLError) ) as excinfo:
|
||||
nginxproxy.get("https://3.web.nginx-proxy.tld/port")
|
||||
assert """hostname '3.web.nginx-proxy.tld' doesn't match 'nginx-proxy.tld'""" in str(excinfo.value)
|
||||
assert """certificate is not valid for '3.web.nginx-proxy.tld'""" in str(excinfo.value)
|
||||
|
||||
r = nginxproxy.get("https://3.web.nginx-proxy.tld/port", verify=False)
|
||||
assert r.status_code == 500
|
||||
assert r.status_code == 503
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 4096 (0x1000)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld
|
||||
Validity
|
||||
Not Before: Jan 13 03:06:39 2017 GMT
|
||||
Not After : May 31 03:06:39 2044 GMT
|
||||
Subject: CN=web.nginx-proxy.tld
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:95:56:c7:0d:48:a5:2b:3c:65:49:3f:26:e1:38:
|
||||
2b:61:30:56:e4:92:d7:63:e0:eb:ad:ac:f9:33:9b:
|
||||
b2:31:f1:39:13:0b:e5:43:7b:c5:bd:8a:85:c8:d9:
|
||||
3d:d8:ac:71:ba:16:e7:81:96:b2:ab:ae:c6:c0:bd:
|
||||
be:a7:d1:96:8f:b2:9b:df:ba:f9:4d:a1:3b:7e:21:
|
||||
4a:cd:b6:45:f9:6d:79:50:bf:24:8f:c1:6b:c1:09:
|
||||
19:5b:62:cb:96:e8:04:14:20:e8:d4:16:62:6a:f2:
|
||||
37:c1:96:e2:9d:53:05:0b:52:1d:e7:68:92:db:8b:
|
||||
36:68:cd:8d:5b:02:ff:12:f0:ac:5d:0c:c4:e0:7a:
|
||||
55:a2:49:60:9f:ff:47:1f:52:73:55:4d:d4:f2:d1:
|
||||
62:a2:f4:50:9d:c9:f6:f1:43:b3:dc:57:e1:31:76:
|
||||
b4:e0:a4:69:7e:f2:6d:34:ae:b9:8d:74:26:7b:d9:
|
||||
f6:07:00:ef:4b:36:61:b3:ef:7a:a1:36:3a:b6:d0:
|
||||
9e:f8:b8:a9:0d:4c:30:a2:ed:eb:ab:6b:eb:2e:e2:
|
||||
0b:28:be:f7:04:b1:e9:e0:84:d6:5d:31:77:7c:dc:
|
||||
d2:1f:d4:1d:71:6f:6f:6c:6d:1b:bf:31:e2:5b:c3:
|
||||
52:d0:14:fc:8b:fb:45:ea:41:ec:ca:c7:3b:67:12:
|
||||
c4:df
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Alternative Name:
|
||||
DNS:web.nginx-proxy.tld
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
4e:48:7d:81:66:ba:2f:50:3d:24:42:61:3f:1f:de:cf:ec:1b:
|
||||
1b:bd:0a:67:b6:62:c8:79:9d:31:a0:fd:a9:61:ce:ff:69:bf:
|
||||
0e:f4:f7:e6:15:2b:b0:f0:e4:f2:f4:d2:8f:74:02:b1:1e:4a:
|
||||
a8:6f:26:0a:77:32:29:cf:dc:b5:61:82:3e:58:47:61:92:f0:
|
||||
0c:20:25:f8:41:4d:34:09:44:bc:39:9e:aa:82:06:83:13:8b:
|
||||
1e:2c:3d:cf:cd:1a:f7:77:39:38:e0:a3:a7:f3:09:da:02:8d:
|
||||
73:75:38:b4:dd:24:a7:f9:03:db:98:c6:88:54:87:dc:e0:65:
|
||||
4c:95:c5:39:9c:00:30:dc:f0:d3:2c:19:ca:f1:f4:6c:c6:d9:
|
||||
b5:c4:4a:c7:bc:a1:2e:88:7b:b5:33:d0:ff:fb:48:5e:3e:29:
|
||||
fa:58:e5:03:de:d8:17:de:ed:96:fc:7e:1f:fe:98:f6:be:99:
|
||||
38:87:51:c0:d3:b7:9a:0f:26:92:e5:53:1b:d6:25:4c:ac:48:
|
||||
f3:29:fc:74:64:9d:07:6a:25:57:24:aa:a7:70:fa:8f:6c:a7:
|
||||
2b:b7:9d:81:46:10:32:93:b9:45:6d:0f:16:18:b2:21:1f:f3:
|
||||
30:24:62:3f:e1:6c:07:1d:71:28:cb:4c:bb:f5:39:05:f9:b2:
|
||||
5b:a0:05:1b
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC+zCCAeOgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp
|
||||
bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs
|
||||
ZDAeFw0xNzAxMTMwMzA2MzlaFw00NDA1MzEwMzA2MzlaMB4xHDAaBgNVBAMME3dl
|
||||
Yi5uZ2lueC1wcm94eS50bGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||
AQCVVscNSKUrPGVJPybhOCthMFbkktdj4OutrPkzm7Ix8TkTC+VDe8W9ioXI2T3Y
|
||||
rHG6FueBlrKrrsbAvb6n0ZaPspvfuvlNoTt+IUrNtkX5bXlQvySPwWvBCRlbYsuW
|
||||
6AQUIOjUFmJq8jfBluKdUwULUh3naJLbizZozY1bAv8S8KxdDMTgelWiSWCf/0cf
|
||||
UnNVTdTy0WKi9FCdyfbxQ7PcV+ExdrTgpGl+8m00rrmNdCZ72fYHAO9LNmGz73qh
|
||||
Njq20J74uKkNTDCi7eura+su4gsovvcEsenghNZdMXd83NIf1B1xb29sbRu/MeJb
|
||||
w1LQFPyL+0XqQezKxztnEsTfAgMBAAGjIjAgMB4GA1UdEQQXMBWCE3dlYi5uZ2lu
|
||||
eC1wcm94eS50bGQwDQYJKoZIhvcNAQELBQADggEBAE5IfYFmui9QPSRCYT8f3s/s
|
||||
Gxu9Cme2Ysh5nTGg/alhzv9pvw709+YVK7Dw5PL00o90ArEeSqhvJgp3MinP3LVh
|
||||
gj5YR2GS8AwgJfhBTTQJRLw5nqqCBoMTix4sPc/NGvd3OTjgo6fzCdoCjXN1OLTd
|
||||
JKf5A9uYxohUh9zgZUyVxTmcADDc8NMsGcrx9GzG2bXESse8oS6Ie7Uz0P/7SF4+
|
||||
KfpY5QPe2Bfe7Zb8fh/+mPa+mTiHUcDTt5oPJpLlUxvWJUysSPMp/HRknQdqJVck
|
||||
qqdw+o9spyu3nYFGEDKTuUVtDxYYsiEf8zAkYj/hbAcdcSjLTLv1OQX5slugBRs=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAlVbHDUilKzxlST8m4TgrYTBW5JLXY+Drraz5M5uyMfE5Ewvl
|
||||
Q3vFvYqFyNk92KxxuhbngZayq67GwL2+p9GWj7Kb37r5TaE7fiFKzbZF+W15UL8k
|
||||
j8FrwQkZW2LLlugEFCDo1BZiavI3wZbinVMFC1Id52iS24s2aM2NWwL/EvCsXQzE
|
||||
4HpVoklgn/9HH1JzVU3U8tFiovRQncn28UOz3FfhMXa04KRpfvJtNK65jXQme9n2
|
||||
BwDvSzZhs+96oTY6ttCe+LipDUwwou3rq2vrLuILKL73BLHp4ITWXTF3fNzSH9Qd
|
||||
cW9vbG0bvzHiW8NS0BT8i/tF6kHsysc7ZxLE3wIDAQABAoIBAEmK7IecKMq7+V0y
|
||||
3mC3GpXICmKR9cRX9XgX4LkLiZuSoXrBtuuevmhzGSMp6I0VjwQHV4a3wdFORs6Q
|
||||
Ip3eVvj5Ck4Jc9BJAFVC6+WWR6tnwACFwOmSZRAw/O3GH2B3bdrDwiT/yQPFuLN7
|
||||
LKoxQiCrFdLp6rh3PBosb9pMBXU7k/HUazIdgmSKg6/JIoo/4Gwyid04TF/4MI2l
|
||||
RscxtP5/ANtS8VgwBEqhgdafRJ4KnLEpgvswgIQvUKmduVhZQlzd0LMY8FbhKVqz
|
||||
Utg8gsXaTyH6df/nmgUIInxLMz/MKPnMkv99fS6Sp/hvYlGpLZFWBJ6unMq3lKEr
|
||||
LMbHfIECgYEAxB+5QWdVqG2r9loJlf8eeuNeMPml4P8Jmi5RKyJC7Cww6DMlMxOS
|
||||
78ZJfl4b3ZrWuyvhjOfX/aTq7kQaF1BI9o3KJBH8k6EtO4gI8KeNmDONyQk9zsrn
|
||||
ru8Zwr7hVbAo8fCXxCnmPzhDLsYg6f3BVOsQWoX2SFYKZ1GvkPfIReECgYEAwu6G
|
||||
qtgFb57Vim10ecfWGM6vrPxvyfqP+zlH/p4nR+aQ+2sFbt27D0B1byWBRZe4KQyw
|
||||
Vq6XiQ09Fk6MJr8E8iAr9GXPPHcqlYI6bbNc6YOP3jVSKut0tQdTUOHll4kYIY+h
|
||||
RS3VA3+BA//ADpWpywu+7RZRbaIECA+U2a224r8CgYB5PCMIixgoRaNHZeEHF+1/
|
||||
iY1wOOKRcxY8eOU0BLnZxHd3EiasrCzoi2pi80nGczDKAxYqRCcAZDHVl8OJJdf0
|
||||
kTGjmnrHx5pucmkUWn7s1vGOlGfgrQ0K1kLWX6hrj7m/1Tn7yOrLqbvd7hvqiTI5
|
||||
jBVP3/+eN5G2zIf61TC4AQKBgCX2Q92jojNhsF58AHHy+/vqzIWYx8CC/mVDe4TX
|
||||
kfjLqzJ7XhyAK/zFZdlWaX1/FYtRAEpxR+uV226rr1mgW7s3jrfS1/ADmRRyvyQ8
|
||||
CP0k9PCmW7EmF51lptEanRbMyRlIGnUZfuFmhF6eAO4WMXHsgKs1bHg4VCapuihG
|
||||
T1aLAoGACRGn1UxFuBGqtsh2zhhsBZE7GvXKJSk/eP7QJeEXUNpNjCpgm8kIZM5K
|
||||
GorpL7PSB8mwVlDl18TpMm3P7nz6YkJYte+HdjO7pg59H39Uvtg3tZnIrFxNxVNb
|
||||
YF62/yHfk2AyTgjQZQUSmDS84jq1zUK4oS90lxr+u8qwELTniMs=
|
||||
-----END RSA PRIVATE KEY-----
|
25
test/test_trust-downstream-proxy/test_default.py
Normal file
25
test/test_trust-downstream-proxy/test_default.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
import pytest
|
||||
import re
|
||||
|
||||
|
||||
@pytest.mark.parametrize('url,header,input,want', [
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Proto', None, 'http'),
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Proto', 'f00', 'f00'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Proto', None, 'https'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Proto', 'f00', 'f00'),
|
||||
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Host', None, 'web.nginx-proxy.tld'),
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Host', 'example.com', 'example.com'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Host', None, 'web.nginx-proxy.tld'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Host', 'example.com', 'example.com'),
|
||||
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Port', None, '80'),
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Port', '1234', '1234'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Port', None, '443'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Port', '1234', '1234'),
|
||||
])
|
||||
def test_downstream_proxy_header(docker_compose, nginxproxy, url, header, input, want):
|
||||
kwargs = {} if input is None else {'headers': {header: input}}
|
||||
r = nginxproxy.get(url, **kwargs)
|
||||
assert r.status_code == 200
|
||||
assert re.search(fr'(?m)^(?i:{re.escape(header)}): {re.escape(want)}$', r.text)
|
16
test/test_trust-downstream-proxy/test_default.yml
Normal file
16
test/test_trust-downstream-proxy/test_default.yml
Normal file
|
@ -0,0 +1,16 @@
|
|||
web:
|
||||
image: web
|
||||
expose:
|
||||
- "80"
|
||||
environment:
|
||||
WEB_PORTS: 80
|
||||
VIRTUAL_HOST: web.nginx-proxy.tld
|
||||
HTTPS_METHOD: noredirect
|
||||
|
||||
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro
|
||||
- ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro
|
25
test/test_trust-downstream-proxy/test_disabled.py
Normal file
25
test/test_trust-downstream-proxy/test_disabled.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
import pytest
|
||||
import re
|
||||
|
||||
|
||||
@pytest.mark.parametrize('url,header,input,want', [
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Proto', None, 'http'),
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Proto', 'f00', 'http'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Proto', None, 'https'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Proto', 'f00', 'https'),
|
||||
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Host', None, 'web.nginx-proxy.tld'),
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Host', 'example.com', 'web.nginx-proxy.tld'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Host', None, 'web.nginx-proxy.tld'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Host', 'example.com', 'web.nginx-proxy.tld'),
|
||||
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Port', None, '80'),
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Port', '1234', '80'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Port', None, '443'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Port', '1234', '443'),
|
||||
])
|
||||
def test_downstream_proxy_header(docker_compose, nginxproxy, url, header, input, want):
|
||||
kwargs = {} if input is None else {'headers': {header: input}}
|
||||
r = nginxproxy.get(url, **kwargs)
|
||||
assert r.status_code == 200
|
||||
assert re.search(fr'(?m)^(?i:{re.escape(header)}): {re.escape(want)}$', r.text)
|
18
test/test_trust-downstream-proxy/test_disabled.yml
Normal file
18
test/test_trust-downstream-proxy/test_disabled.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
web:
|
||||
image: web
|
||||
expose:
|
||||
- "80"
|
||||
environment:
|
||||
WEB_PORTS: 80
|
||||
VIRTUAL_HOST: web.nginx-proxy.tld
|
||||
HTTPS_METHOD: noredirect
|
||||
|
||||
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
environment:
|
||||
TRUST_DOWNSTREAM_PROXY: "false"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro
|
||||
- ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro
|
25
test/test_trust-downstream-proxy/test_enabled.py
Normal file
25
test/test_trust-downstream-proxy/test_enabled.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
import pytest
|
||||
import re
|
||||
|
||||
|
||||
@pytest.mark.parametrize('url,header,input,want', [
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Proto', None, 'http'),
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Proto', 'f00', 'f00'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Proto', None, 'https'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Proto', 'f00', 'f00'),
|
||||
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Host', None, 'web.nginx-proxy.tld'),
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Host', 'example.com', 'example.com'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Host', None, 'web.nginx-proxy.tld'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Host', 'example.com', 'example.com'),
|
||||
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Port', None, '80'),
|
||||
('http://web.nginx-proxy.tld/headers', 'X-Forwarded-Port', '1234', '1234'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Port', None, '443'),
|
||||
('https://web.nginx-proxy.tld/headers', 'X-Forwarded-Port', '1234', '1234'),
|
||||
])
|
||||
def test_downstream_proxy_header(docker_compose, nginxproxy, url, header, input, want):
|
||||
kwargs = {} if input is None else {'headers': {header: input}}
|
||||
r = nginxproxy.get(url, **kwargs)
|
||||
assert r.status_code == 200
|
||||
assert re.search(fr'(?m)^(?i:{re.escape(header)}): {re.escape(want)}$', r.text)
|
18
test/test_trust-downstream-proxy/test_enabled.yml
Normal file
18
test/test_trust-downstream-proxy/test_enabled.yml
Normal file
|
@ -0,0 +1,18 @@
|
|||
web:
|
||||
image: web
|
||||
expose:
|
||||
- "80"
|
||||
environment:
|
||||
WEB_PORTS: 80
|
||||
VIRTUAL_HOST: web.nginx-proxy.tld
|
||||
HTTPS_METHOD: noredirect
|
||||
|
||||
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
environment:
|
||||
TRUST_DOWNSTREAM_PROXY: "true"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- ./certs/web.nginx-proxy.tld.crt:/etc/nginx/certs/web.nginx-proxy.tld.crt:ro
|
||||
- ./certs/web.nginx-proxy.tld.key:/etc/nginx/certs/web.nginx-proxy.tld.key:ro
|
10
test/test_vhost-empty-string.py
Normal file
10
test/test_vhost-empty-string.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
import re
|
||||
|
||||
|
||||
def test_vhost_empty_string(docker_compose, nginxproxy):
|
||||
conf = nginxproxy.get_conf().decode()
|
||||
assert re.search(r"(?m)^\s*server_name\s+web2\.nginx-proxy\.test\s*;", conf)
|
||||
assert re.search(r"(?m)^\s*server_name\s+web3\.nginx-proxy\.test\s*;", conf)
|
||||
assert re.search(r"(?m)^\s*server_name\s+web4a\.nginx-proxy\.test\s*;", conf)
|
||||
assert re.search(r"(?m)^\s*server_name\s+web4b\.nginx-proxy\.test\s*;", conf)
|
||||
assert not re.search(r"(?m)^\s*server_name\s*;", conf)
|
37
test/test_vhost-empty-string.yml
Normal file
37
test/test_vhost-empty-string.yml
Normal file
|
@ -0,0 +1,37 @@
|
|||
services:
|
||||
sut:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
web1:
|
||||
image: web
|
||||
expose:
|
||||
- "81"
|
||||
environment:
|
||||
WEB_PORTS: "81"
|
||||
# The space is intentional (should be trimmed).
|
||||
VIRTUAL_HOST: " "
|
||||
web2:
|
||||
image: web
|
||||
expose:
|
||||
- "82"
|
||||
environment:
|
||||
WEB_PORTS: "82"
|
||||
# The space is intentional (should be trimmed).
|
||||
VIRTUAL_HOST: "web2.nginx-proxy.test ,"
|
||||
web3:
|
||||
image: web
|
||||
expose:
|
||||
- "83"
|
||||
environment:
|
||||
WEB_PORTS: "83"
|
||||
# The space is intentional (should be trimmed).
|
||||
VIRTUAL_HOST: " ,web3.nginx-proxy.test"
|
||||
web4:
|
||||
image: web
|
||||
expose:
|
||||
- "84"
|
||||
environment:
|
||||
WEB_PORTS: "84"
|
||||
# The spaces are intentional (should be trimmed).
|
||||
VIRTUAL_HOST: "web4a.nginx-proxy.test, , web4b.nginx-proxy.test"
|
29
test/test_vhost-in-multiple-networks.py
Normal file
29
test/test_vhost-in-multiple-networks.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
import pytest
|
||||
import logging
|
||||
import time
|
||||
|
||||
def test_forwards_to_web1(docker_compose, nginxproxy):
|
||||
r = nginxproxy.get("http://web1.nginx-proxy.local/port")
|
||||
assert r.status_code == 200
|
||||
assert r.text == "answer from port 81\n"
|
||||
|
||||
def test_nginx_config_remains_the_same_after_restart(docker_compose, nginxproxy):
|
||||
"""
|
||||
Restarts the Web container and returns nginx-proxy config after restart
|
||||
"""
|
||||
def get_conf_after_web_container_restart():
|
||||
web_containers = docker_compose.containers.list(filters={"ancestor": "web:latest"})
|
||||
assert len(web_containers) == 1
|
||||
web_containers[0].restart()
|
||||
time.sleep(3)
|
||||
|
||||
return nginxproxy.get_conf()
|
||||
|
||||
config_before_restart = nginxproxy.get_conf()
|
||||
|
||||
for i in range(1, 8):
|
||||
logging.info(f"Checking for the {i}-st time that config is the same")
|
||||
config_after_restart = get_conf_after_web_container_restart()
|
||||
if config_before_restart != config_after_restart:
|
||||
logging.debug(f"{config_before_restart!r} \n\n {config_after_restart!r}")
|
||||
pytest.fail("nginx-proxy config before and after restart of a web container does not match", pytrace=False)
|
26
test/test_vhost-in-multiple-networks.yml
Normal file
26
test/test_vhost-in-multiple-networks.yml
Normal file
|
@ -0,0 +1,26 @@
|
|||
version: '2'
|
||||
|
||||
networks:
|
||||
net1: {}
|
||||
net2: {}
|
||||
net3: {}
|
||||
|
||||
services:
|
||||
nginx-proxy:
|
||||
image: nginxproxy/nginx-proxy:test
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
networks:
|
||||
- net1
|
||||
|
||||
web:
|
||||
image: web
|
||||
expose:
|
||||
- "81"
|
||||
environment:
|
||||
WEB_PORTS: 81
|
||||
VIRTUAL_HOST: web1.nginx-proxy.local
|
||||
networks:
|
||||
- net1
|
||||
- net2
|
||||
- net3
|
Loading…
Reference in a new issue