Compare commits

...

138 Commits
1.0.0 ... main

Author SHA1 Message Date
Nicolas Duchon
0d9cd2b45c
Merge pull request #2186 from rhansen/fallback
fix: Improve handling of unknown hosts and missing certs
2023-03-24 14:18:52 +01:00
Niek
7ca1da8358
feat: Add support for HTTP load balancing between the proxy and upstream server groups (#2173)
Add initial tests

Newlines

Remove unused variable

Co-authored-by: Richard Hansen <rhansen@rhansen.org>

Change comment value

Co-authored-by: Richard Hansen <rhansen@rhansen.org>

add missing services line

Co-authored-by: Richard Hansen <rhansen@rhansen.org>

Use deploy.replicas

Remove details about choosing a load balancing method

Feedback note

Co-authored-by: Nicolas Duchon <nicolas.duchon@gmail.com>
2023-03-21 07:49:27 +01:00
Nicolas Duchon
55d53e6659
Merge pull request #1934 from rhansen/keepalive
feat: Add support for HTTP keep-alive between the proxy and upstream
2023-03-21 07:31:13 +01:00
Nicolas Duchon
6c2d17586b
Merge pull request #2200 from nginx-proxy/docker-gen-0.10.2
build: dockergen 0.10.1 -> 0.10.2
2023-03-21 07:27:48 +01:00
Nicolas Duchon
4696944245
build: dockergen 0.10.1 -> 0.10.2 2023-03-21 07:15:34 +01:00
Richard Hansen
49bb37dfdb feat: Add support for HTTP keep-alive between the proxy and upstream 2023-03-14 04:20:17 -04:00
Nicolas Duchon
1f855fc7b3
Merge pull request #2191 from rhansen/nil-currentcontainer
fix: Don't error if `$globals.CurrentContainer` is `nil`
2023-03-14 06:49:21 +01:00
Richard Hansen
364beed773 fix: Don't error if $globals.CurrentContainer is nil
Also:
  * Note when there are no networks.
  * Fix "networks available" comment.
2023-03-10 15:23:44 -05:00
Richard Hansen
51fd6918ca
Merge pull request #2188 from nginx-proxy/dependabot/docker/golang-1.20.2-alpine
build: bump golang from 1.20.1-alpine to 1.20.2-alpine
2023-03-08 15:00:19 -05:00
dependabot[bot]
9906ccda42
build: bump golang from 1.20.1-alpine to 1.20.2-alpine
Bumps golang from 1.20.1-alpine to 1.20.2-alpine.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-08 04:58:06 +00:00
Richard Hansen
d990354e3d
Merge pull request #2187 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.2.2
ci: bump pytest from 7.2.1 to 7.2.2 in /test/requirements
2023-03-06 15:50:46 -05:00
dependabot[bot]
2fc3e6c28c
ci: bump pytest from 7.2.1 to 7.2.2 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.1 to 7.2.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.2.1...7.2.2)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 05:04:42 +00:00
Nicolas Duchon
abcef6be86
Merge pull request #2184 from nginx-proxy/dockergen-0.10.1
build: dockergen 0.10.0 -> 0.10.1
2023-02-28 08:50:19 +01:00
Nicolas Duchon
6e9d46e672
Merge pull request #2164 from rhansen/tests
chore: minor test improvements
2023-02-28 08:49:12 +01:00
Nicolas Duchon
16b8cde8e4
build: dockergen 0.10.0 -> 0.10.1 2023-02-28 08:36:27 +01:00
Nicolas Duchon
afd6544702
Merge pull request #2179 from rhansen/swarm
fix: Partially revert "chore: Remove support for legacy swarm"
2023-02-28 07:40:16 +01:00
Richard Hansen
4fc17d6139
Merge pull request #2183 from JanMalte/patch-1
fix: Sort networks and ports before iterating
2023-02-21 00:56:06 -05:00
Jan Malte Gerth
37134c44d7 fix: Sort networks and ports before iterating
This avoids unnecessary nginx restarts caused by config file churn.
2023-02-21 00:22:47 -05:00
Richard Hansen
b5a54ac219 tests: Reduce scope of docker_compose fixture (and friends)
This makes it possible to bring up different compose files for
different tests in the same test module.

This change does not negatively affect performance because the fixture
is a no-op if the docker compose filename is unchanged between tests.
2023-02-17 02:34:08 -05:00
Richard Hansen
4d8f878ba7 tests: Fixture that simplifies Docker compose file changes 2023-02-17 02:34:08 -05:00
Richard Hansen
f5a3492926 tests: Factor out DNS monkey patching to its own fixture 2023-02-17 02:34:08 -05:00
Richard Hansen
09a2f40633 tests: Turn helper function into docker_compose_file fixture
This makes it easier for tests to override the filename.
2023-02-17 02:34:08 -05:00
Richard Hansen
01745a836f tests: Fix path to ca-root.crt
`os.getcwd()` is not guaranteed to always return the `test/`
directory.
2023-02-17 02:34:08 -05:00
Richard Hansen
6207be5f8f fix: Partially revert "chore: Remove support for legacy swarm"
This partially reverts commit 2494e20784
by ignoring any network named "ingress" when searching for a
container's IP address.

That commit was technically a backwards-incompatible change: Some
users use nginx-proxy with Swarm mode even though it is not fully
supported.  In such cases nginx-proxy should ignore the `ingress`
network, otherwise nginx will not be able to reach the
server (container-to-container traffic apparently doesn't work over
the Swarm `ingress` network).

The parts of that commit that examine the `SwarmNode` structure are
not reverted here because docker-gen does not currently populate that
structure -- not even when both docker-gen and the service task
container are running on the same manager node.
2023-02-17 01:52:05 -05:00
Richard Hansen
6f2a549ef1
Merge pull request #2175 from nginx-proxy/dependabot/docker/golang-1.20.1
build: bump golang from 1.20.0 to 1.20.1
2023-02-15 03:47:19 -05:00
dependabot[bot]
de4386e440
build: bump golang from 1.20.0 to 1.20.1
Bumps golang from 1.20.0 to 1.20.1.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-15 04:57:57 +00:00
Nicolas Duchon
bc2ada1f44
Merge pull request #2163 from nginx-proxy/dockergen-0.10.0
build: dockergen 0.9.4 -> 0.10.0
2023-02-09 08:28:09 +01:00
Nicolas Duchon
c10c7bcbe9
build: dockergen 0.9.4 -> 0.10.0 2023-02-09 08:10:43 +01:00
Nicolas Duchon
41e025f0f0
Merge pull request #2159 from rhansen/refactor
chore: Factor out container IP:port lookup
2023-02-09 08:01:26 +01:00
Richard Hansen
9b4bb07b34
fix: Don't create fallback http(s) server when http(s) disabled
Before, a fallback http server was created to handle requests for
unknown virtual hosts even when `HTTPS_METHOD=nohttp`.  (In this case,
all http vhosts would be unknown.)  Likewise, a catch-all fallback
https server was still created even if `HTTPS_METHOD=nohttps`.

Now the fallback servers are created only if needed.  This brings the
behavior in line with the documentation and user expectation.  It will
also make it easier to implement a planned feature: different servers
on different ports.
2023-02-04 18:59:38 -05:00
Richard Hansen
9297e94389
fix: Emit TLS error if there are no certs available
Before, if neither the vhost-specific cert nor `default.crt` existed,
nginx-proxy would not create the https vhost.  This resulted in nginx
either refusing the connection or serving the wrong vhost depending on
whether there was another https vhost with a certificate.

Now nginx-proxy always creates an https server for a vhost, even if
the vhost-specific certificate and the default certificate are both
missing.  When both certs are missing, nginx is given empty
certificate data to make it possible for it to start up without an
error.  The empty certificate data causes the user to see a TLS error,
which is much easier to troubleshoot than a connection refused error
or serving the wrong vhost.
2023-02-02 22:02:06 -05:00
Richard Hansen
16066cab61
fix: Don't create cert error https server if https is not enabled 2023-02-02 17:17:00 -05:00
Richard Hansen
ee8d2cede4
Merge pull request #2162 from nginx-proxy/dependabot/docker/golang-1.20.0
build: bump golang from 1.19.5 to 1.20.0
2023-02-02 02:20:26 -05:00
dependabot[bot]
7b6b2f773d
build: bump golang from 1.19.5 to 1.20.0
Bumps golang from 1.19.5 to 1.20.0.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-02 04:01:39 +00:00
Richard Hansen
18d0671312
chore: Factor out duplicate checks for default.crt
for improved readability.
2023-02-01 18:56:16 -05:00
Richard Hansen
7a2b1f8833
chore: Split $is_https variable into two separate checks
for improved readability.
2023-02-01 18:17:43 -05:00
Richard Hansen
11a46f728c chore: Factor out container IP:port lookup
This will make planned future changes easier.
2023-02-01 03:06:39 -05:00
Richard Hansen
2494e20784 chore: Remove support for legacy swarm
It doesn't work with the newer Docker Swarm mode so it doesn't have
much value anymore.
2023-02-01 03:04:37 -05:00
Nicolas Duchon
1462ff019d
Merge pull request #1179 from harvdogg/master
Allow complete override of location blocks
2023-02-01 07:42:42 +01:00
Richard Hansen
2115974e93 feat: Add ability to completely override location blocks
Co-authored-by: Trent Harvey <trent@harvdog.net>
2023-01-31 04:53:12 -05:00
Nicolas Duchon
8ac8b021b8
Merge pull request #2155 from rhansen/docker-pull
chore: Pass `--pull` to `docker build` to get fresh images
2023-01-30 07:57:44 +01:00
Nicolas Duchon
926bd43cff
Merge pull request #2153 from rhansen/upstream-cleanup
fix: Generate at most one `server` directive per container
2023-01-30 07:56:50 +01:00
Richard Hansen
912a065406 chore: Pass --pull to docker build to get fresh images
This is a no-op if the images are already up to date, and it prevents
puzzling problems when the images are old.
2023-01-28 18:17:40 -05:00
Richard Hansen
6162427c45 fix: Generate at most one server directive per container 2023-01-28 18:01:19 -05:00
Richard Hansen
bcec2d9075 chore: Refactor upstream template for readability
In particular, reduce the nesting depth to make it easier to
understand what the code is doing by:

  * converting an $O(nm)$ nested loop into two serial $O(n)+O(m)$
    loops, and
  * consolidating similar nested `if` cases.
2023-01-28 18:01:19 -05:00
Richard Hansen
daeed502cb feat: Add a warning comment if the container port is published 2023-01-28 18:01:19 -05:00
Richard Hansen
5a8a6ceae2 chore: Improve debug comments in upstream template 2023-01-28 18:01:19 -05:00
Richard Hansen
2760ead490 chore: Remove warning comment when port is not exposed
Exposing ports is largely deprecated because it doesn't actually do
anything in Docker.
2023-01-28 18:01:19 -05:00
Richard Hansen
e97bf606c8 chore: Move version comment to the top of the template
to ensure that the version is always the first output line.

Also, always output `# nginx-proxy`, even if the version isn't known.
This makes it easier to find the start of the generated config in the
output of `nginx -T`.
2023-01-28 18:01:19 -05:00
Richard Hansen
d6d53893e8
Merge pull request #2152 from vincent-herlemont/documentation-log-format
Documentation custom log format.
2023-01-28 03:32:21 -05:00
Vincent Herlemont
aa50116272 Documentation custom log format. 2023-01-27 23:16:49 +01:00
Vincent Herlemont
07cc80ac6b
feat: Support LOG_FORMAT env variable (#2151) 2023-01-27 12:28:40 -05:00
Richard Hansen
8346b68a28 fix: Ignore VIRTUAL_HOST set to the empty string
Fixes #2144
2023-01-23 20:48:16 -05:00
Richard Hansen
f8ae0a4b00 feat: DEFAULT_ROOT=none disables the default location / block 2023-01-23 20:47:00 -05:00
Nicolas Duchon
d3ded293ac
Merge pull request #2147 from nginx-proxy/dockergen-0.9.4
build: dockergen 0.9.3 -> 0.9.4
2023-01-24 00:27:54 +01:00
Nicolas Duchon
fa52426d54
ci: set Dependabot commit prefixs 2023-01-23 23:24:58 +01:00
Nicolas Duchon
8df67cdde8
build: dockergen 0.9.3 -> 0.9.4 2023-01-23 23:14:42 +01:00
Richard Hansen
98b6473c84
Merge pull request #2141 from rhansen/debug
feat: Unconditionally produce debug comments
2023-01-21 19:02:27 -05:00
Richard Hansen
8fbc8514ef feat: Unconditionally produce debug comments
Rationale for eliminating the check to see if the `DEBUG` environment
variable holds a true value:
  * The `DEBUG` environment variable might be set on a container (for
    purposes specific to that container, not `nginx-proxy`) to a value
    that cannot be parsed as a bool, which would break `nginx-proxy`.
  * It simplifies the template.
  * It eliminates a cold code path.
  * It avoids heisenbugs.
  * It makes debugging easier for users.

Also delete the debug info tests, as they are fragile and they provide
limited value.

Alternatively, we could avoid collision with the container's use of
the `DEBUG` environment variable by using a container label [1] such
as `com.google.nginx-proxy.nginx-proxy.debug`.  I think doing so has
dubious value, especially if we want to attempt backwards
compatibility with the `DEBUG` environment variable.

Fixes #2139

[1] https://docs.docker.com/engine/reference/commandline/run/#-set-metadata-on-container--l---label---label-file

Co-authored-by: Nicolas Duchon <nicolas.duchon@gmail.com>
2023-01-18 17:27:04 -05:00
Nicolas Duchon
1775420592
Merge pull request #2140 from rhansen/tests
Minor test fixes
2023-01-18 08:02:02 +01:00
Richard Hansen
92e1a6567e tests: Remove extraction of nginx.tmpl (now unnecessary) 2023-01-17 18:02:30 -05:00
Richard Hansen
486addd144 tests: Bind-mount the entire nginx-proxy directory in the container 2023-01-17 18:02:30 -05:00
Richard Hansen
569953521a tests: Exit non-zero if creation of nginx-proxy-tester image fails 2023-01-17 18:02:30 -05:00
Richard Hansen
55cfae9636 tests: Avoid unnecessary bashisms 2023-01-17 18:02:30 -05:00
Richard Hansen
d56b5b370d tests: Whitespace fixes 2023-01-17 18:02:30 -05:00
Richard Hansen
26b0b05f73 tests: Fix test_debug/* tests when IPv6 is enabled 2023-01-17 18:02:29 -05:00
Nicolas Duchon
5d22134ee6
Merge pull request #2137 from nginx-proxy/dockergen-0.9.3
build: dockergen 0.9.2 -> 0.9.3
2023-01-17 08:35:18 +01:00
Nicolas Duchon
b16ad27878
build: dockergen 0.9.2 -> 0.9.3 2023-01-17 08:17:02 +01:00
Nicolas Duchon
017a731302
Merge pull request #2127 from rhansen/chores
Various code health chores
2023-01-17 07:44:57 +01:00
Richard Hansen
2427b383b5 chore: Move global variables to a $globals dict
Planned future changes will introduce more embedded templates, and the ability
to pass the globals to the templates will be useful.
2023-01-17 00:42:20 -05:00
Richard Hansen
1b253cd908 chore: Wrap long comments 2023-01-17 00:42:20 -05:00
Richard Hansen
0da38122bd chore: Consistent indentation 2023-01-17 00:42:20 -05:00
Richard Hansen
f20662eeaa chore: Use {{- instead of {{ to clean up whitespace 2023-01-17 00:42:20 -05:00
Richard Hansen
d6d8b2205f chore: Fix comment terminators 2023-01-17 00:42:20 -05:00
Richard Hansen
4651bf411d chore: Fix comment for $proxy_connection variable 2023-01-17 00:42:20 -05:00
Richard Hansen
744bd82c54 chore: Combine identical HTTP and HTTPS servers 2023-01-17 00:42:20 -05:00
Richard Hansen
491642b1e9 chore: Factor out duplicate virtual path code 2023-01-17 00:42:20 -05:00
Richard Hansen
14d0f3f222 chore: Rename $container to $containers
The value is actually a slice/array of containers so it should be
pluralized.
2023-01-17 00:42:20 -05:00
Richard Hansen
05423c681a fix: Use parseBool to parse boolean strings 2023-01-17 00:42:20 -05:00
Richard Hansen
c117ae8fd8 chore: Use boolean for $server_found variable 2023-01-17 00:42:20 -05:00
Richard Hansen
05eee4b7a3
Merge pull request #2136 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.2.1
chore(deps): bump pytest from 7.2.0 to 7.2.1 in /test/requirements
2023-01-16 23:28:47 -05:00
dependabot[bot]
9c9545bf7f
chore(deps): bump pytest from 7.2.0 to 7.2.1 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.0 to 7.2.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.2.0...7.2.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 04:12:49 +00:00
Richard Hansen
cc9edec1c6
Merge pull request #2134 from nginx-proxy/dependabot/pip/test/requirements/requests-2.28.2
chore(deps): bump requests from 2.28.1 to 2.28.2 in /test/requirements
2023-01-13 16:35:16 -05:00
dependabot[bot]
831615fdd4
chore(deps): bump requests from 2.28.1 to 2.28.2 in /test/requirements
Bumps [requests](https://github.com/psf/requests) from 2.28.1 to 2.28.2.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.28.1...v2.28.2)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-13 04:04:20 +00:00
Richard Hansen
3531fa4d37
Merge pull request #2132 from nginx-proxy/dependabot/docker/golang-1.19.5
chore(deps): bump golang from 1.19.4 to 1.19.5
2023-01-11 14:10:23 -05:00
dependabot[bot]
146b7933a9
chore(deps): bump golang from 1.19.4 to 1.19.5
Bumps golang from 1.19.4 to 1.19.5.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-11 04:03:07 +00:00
Nicolas Duchon
2f898566fc
Merge pull request #2121 from rhansen/patch-X-Forwarded-Host
feat: Add proxy header `X-Forwarded-Host`
2022-12-27 09:58:48 +01:00
浊酒
af877cf784 feat: Add proxy header X-Forwarded-Host
Co-authored-by: Richard Hansen <rhansen@rhansen.org>
2022-12-26 17:59:50 -05:00
Nicolas Duchon
6f4f9ec20c
Merge pull request #1927 from rhansen/untrusted-headers
feat: Option to not trust `X-Forwarded-*` headers from clients
2022-12-26 20:47:05 +01:00
Nicolas Duchon
7c0d38cd2e
Merge pull request #1985 from hiqdev/networks-order
Make sure networks order is the same
2022-12-26 16:59:41 +01:00
Nicolas Duchon
cb82aad4c0
Merge pull request #2118 from nginx-proxy/dockergen-0.9.2
build: dockergen 0.9.1 -> 0.9.2
2022-12-23 19:53:27 +01:00
Nicolas Duchon
ba8f5a4eb8
build: dockergen 0.9.1 -> 0.9.2 2022-12-23 19:45:04 +01:00
Nicolas Duchon
ee0d68c34e
docs: nginx badge 1.23.2 -> 1.23.3 2022-12-23 19:42:48 +01:00
Nicolas Duchon
216e0b5e12
Merge pull request #2110 from nginx-proxy/dependabot/docker/golang-1.19.4
chore(deps): bump golang from 1.18.8 to 1.19.4
2022-12-23 19:41:21 +01:00
Nicolas Duchon
aadeabe4a6
Merge pull request #2115 from nginx-proxy/dependabot/docker/nginx-1.23.3
chore(deps): bump nginx from 1.23.2 to 1.23.3
2022-12-21 00:24:14 +01:00
Richard Hansen
8aa00fcea2 feat: Option to not trust X-Forwarded-* headers from clients
If header values from a malicious client are passed to the backend
server unchecked and unchanged, the client may be able to subvert
security checks done by the backend server.
2022-12-19 02:48:01 -05:00
Richard Hansen
5f15f04556 docs: Document the request headers sent to the backend server 2022-12-19 02:48:01 -05:00
Richard Hansen
9cb21132a4 docs: Sync README.md with default proxy.conf settings 2022-12-19 02:48:01 -05:00
dependabot[bot]
1aadd9ba8c
chore(deps): bump nginx from 1.23.2 to 1.23.3
Bumps nginx from 1.23.2 to 1.23.3.

---
updated-dependencies:
- dependency-name: nginx
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-14 04:02:52 +00:00
dependabot[bot]
f1fb85865d
chore(deps): bump golang from 1.18.8 to 1.19.4
Bumps golang from 1.18.8 to 1.19.4.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-07 04:02:52 +00:00
Nicolas Duchon
9c2b2cec38
ci: use actions/checkout@v3 2022-12-03 19:36:31 +01:00
Nicolas Duchon
9f9e5b8cd4
ci: update Actions versions 2022-12-03 14:34:15 +01:00
Nicolas Duchon
02d3a37cfb
style: linting on CI yaml files 2022-12-03 14:30:40 +01:00
Nicolas Duchon
75c7b1399b
build: golang 1.18.1 -> 1.18.8 2022-12-02 00:21:56 +01:00
Nicolas Duchon
284a935f3c
Merge pull request #2102 from nginx-proxy/dockergen-0.9.1
build: dockergen 0.9.0 -> 0.9.1
2022-12-01 23:44:14 +01:00
Nicolas Duchon
050d9da7bd
docs: nginx badge 1.21.6 -> 1.23.2 2022-12-01 23:24:53 +01:00
Nicolas Duchon
b4dd1a4ba8
build: dockergen 0.9.0 -> 0.9.1 2022-12-01 23:22:02 +01:00
Nicolas Duchon
22d58656a0
Merge pull request #2042 from valerebron/patch-1
Simple mistake in DEFAULT_ROOT variable name
2022-12-01 22:54:18 +01:00
Nicolas Duchon
7a1fe49841
Merge pull request #2081 from nginx-proxy/dependabot/pip/test/requirements/docker-6.0.1
chore(deps): bump docker from 5.0.3 to 6.0.1 in /test/requirements
2022-12-01 22:11:37 +01:00
dependabot[bot]
e5b340cb6f
chore(deps): bump docker from 5.0.3 to 6.0.1 in /test/requirements
Bumps [docker](https://github.com/docker/docker-py) from 5.0.3 to 6.0.1.
- [Release notes](https://github.com/docker/docker-py/releases)
- [Commits](https://github.com/docker/docker-py/compare/5.0.3...6.0.1)

---
updated-dependencies:
- dependency-name: docker
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 14:30:16 +00:00
Nicolas Duchon
4f11827752
Merge pull request #2058 from nginx-proxy/dependabot/pip/test/requirements/backoff-2.2.1
chore(deps): bump backoff from 1.11.1 to 2.2.1 in /test/requirements
2022-12-01 15:29:28 +01:00
dependabot[bot]
b53e09373a
chore(deps): bump backoff from 1.11.1 to 2.2.1 in /test/requirements
Bumps [backoff](https://github.com/litl/backoff) from 1.11.1 to 2.2.1.
- [Release notes](https://github.com/litl/backoff/releases)
- [Changelog](https://github.com/litl/backoff/blob/master/CHANGELOG.md)
- [Commits](https://github.com/litl/backoff/compare/v1.11.1...v2.2.1)

---
updated-dependencies:
- dependency-name: backoff
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 13:02:13 +00:00
Nicolas Duchon
91fac60aae
Merge pull request #2008 from nginx-proxy/dependabot/pip/test/requirements/requests-2.28.1
chore(deps): bump requests from 2.27.1 to 2.28.1 in /test/requirements
2022-12-01 14:01:00 +01:00
dependabot[bot]
302ecfff51
chore(deps): bump requests from 2.27.1 to 2.28.1 in /test/requirements
Bumps [requests](https://github.com/psf/requests) from 2.27.1 to 2.28.1.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.27.1...v2.28.1)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 12:00:48 +00:00
Nicolas Duchon
515c736d5a
Merge pull request #2077 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.2.0
chore(deps): bump pytest from 7.1.2 to 7.2.0 in /test/requirements
2022-12-01 13:00:08 +01:00
Nicolas Duchon
14ccabf45a
Merge pull request #2072 from nginx-proxy/dependabot/docker/nginx-1.23.2
chore(deps): bump nginx from 1.21.6 to 1.23.2
2022-12-01 12:50:00 +01:00
dependabot[bot]
d23a746833
chore(deps): bump pytest from 7.1.2 to 7.2.0 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.1.2 to 7.2.0.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.1.2...7.2.0)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-26 04:21:21 +00:00
dependabot[bot]
0fbd71362b
chore(deps): bump nginx from 1.21.6 to 1.23.2
Bumps nginx from 1.21.6 to 1.23.2.

---
updated-dependencies:
- dependency-name: nginx
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-20 04:07:57 +00:00
Valère BRON
9218caef71
Simple mistake in DEFAULT_ROOT variable name
`DEFAUL_ROOT` should be `DEFAULT_ROOT`
2022-08-23 12:45:45 +02:00
SilverFire - Dmitry Naumenko
510d376f00 Make sure networks order is the same 2022-05-11 12:56:18 +00:00
Nicolas Duchon
c4ad18fecc
Merge pull request #1971 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.1.2
chore(deps): bump pytest from 7.1.1 to 7.1.2 in /test/requirements
2022-04-26 07:55:46 +02:00
dependabot[bot]
20e76ac7a6
chore(deps): bump pytest from 7.1.1 to 7.1.2 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.1.1 to 7.1.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.1.1...7.1.2)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-25 04:22:00 +00:00
Nicolas Duchon
70d33d976b
Merge pull request #1939 from ntnj/main
chore: indent location, upstream in template
2022-04-18 16:16:00 +02:00
Nicolas Duchon
705b29c14f
Merge pull request #1960 from nginx-proxy/dependabot/docker/golang-1.18.1
chore(deps): bump golang from 1.18.0 to 1.18.1
2022-04-18 15:52:55 +02:00
Nitin Jain
998d56c473 chore: indent location, upstream in template 2022-04-14 13:32:58 +05:30
dependabot[bot]
ae0faa43cd
chore(deps): bump golang from 1.18.0 to 1.18.1
Bumps golang from 1.18.0 to 1.18.1.

---
updated-dependencies:
- dependency-name: golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-14 04:10:10 +00:00
Nicolas Duchon
2f82265891
Merge pull request #1940 from nginx-proxy/dockergen-0.9.0
Bump docker-gen from 0.8.4 to 0.9.0
2022-04-10 13:35:44 +02:00
Nicolas Duchon
2e1da37f9a
build: bump docker-gen from 0.8.4 to 0.9.0 2022-04-10 13:15:02 +02:00
Nicolas Duchon
576ccc7009
Merge pull request #1933 from nginx-proxy/dockergen-0.8.4
Bump docker-gen from 0.8.2 to 0.8.4
2022-04-10 12:58:42 +02:00
Nicolas Duchon
6a0a1f6782
build: bump docker-gen from 0.8.2 to 0.8.4 2022-03-25 11:05:17 +01:00
Nicolas Duchon
0442ed9b72
Merge pull request #1929 from nginx-proxy/dependabot/pip/test/requirements/pytest-7.1.1
chore(deps): bump pytest from 7.0.1 to 7.1.1 in /test/requirements
2022-03-23 16:38:10 +01:00
Nicolas Duchon
d851908c67
Merge pull request #1931 from rhansen/http-port
Fix IPv6 HTTP listen port
2022-03-23 16:37:47 +01:00
Richard Hansen
55d913255d Fix IPv6 HTTP listen port 2022-03-20 18:54:07 -04:00
dependabot[bot]
1cc3bbf5ce
chore(deps): bump pytest from 7.0.1 to 7.1.1 in /test/requirements
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.0.1 to 7.1.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.0.1...7.1.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-18 04:16:58 +00:00
Nicolas Duchon
4ea3437dfa
chore: include license into the Docker images 2022-03-09 12:05:56 +01:00
Nicolas Duchon
6b48e11e5c
Merge pull request #1444 from pini-gh/app-folder
Do not copy useless files into the image
2022-03-07 16:22:39 +01:00
Nicolas Duchon
fea6cc7537
chore: update .dockerignore 2022-03-07 16:01:15 +01:00
Gilles Filippini
5aba125fb7
chore: do not copy useless files into the image
Move required files but 'nginx.tmpl' into a local 'app' folder and copy the
folder content into the image.

'nginx.tmpl' should be moved as well, but this is a breaking change for
configuration with a separate 'docker-gen' container.
2022-03-07 16:01:15 +01:00
87 changed files with 2438 additions and 667 deletions

View File

@ -1,6 +1,9 @@
.git
.github
test
.dockerignore
circle.yml
.gitignore
*.yml
Dockerfile*
Makefile
README.md
test

View File

@ -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"
@ -15,5 +16,7 @@ updates:
directory: "/test/requirements"
schedule:
interval: "daily"
commit-message:
prefix: "ci"
labels:
- "type/ci"

View File

@ -3,28 +3,27 @@ name: DockerHub
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:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
@ -33,7 +32,7 @@ jobs:
- 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,25 +41,25 @@ 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 }}
- 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 }}
@ -68,7 +67,7 @@ jobs:
- name: Build and push the Debian based image
id: docker_build_debian
uses: docker/build-push-action@v2
uses: docker/build-push-action@v3
with:
context: .
file: Dockerfile
@ -84,9 +83,8 @@ jobs:
multiarch-build-alpine:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
@ -95,7 +93,7 @@ jobs:
- 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,26 +102,26 @@ 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 }}
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 }}
@ -131,7 +129,7 @@ jobs:
- name: Build and push the Alpine based image
id: docker_build_alpine
uses: docker/build-push-action@v2
uses: docker/build-push-action@v3
with:
context: .
file: Dockerfile.alpine

View File

@ -4,12 +4,12 @@ on:
workflow_dispatch:
push:
paths-ignore:
- 'LICENSE'
- '**.md'
- "LICENSE"
- "**.md"
pull_request:
paths-ignore:
- 'LICENSE'
- '**.md'
- "LICENSE"
- "**.md"
jobs:
unit:
@ -21,7 +21,7 @@ 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

View File

@ -1,9 +1,9 @@
# setup build arguments for version of dependencies to use
ARG DOCKER_GEN_VERSION=0.8.2
ARG DOCKER_GEN_VERSION=0.10.2
ARG FOREGO_VERSION=v0.17.0
# Use a specific version of golang to build both binaries
FROM golang:1.17.8 as gobuilder
FROM golang:1.20.2 as gobuilder
# Build docker-gen from scratch
FROM gobuilder as dockergen
@ -36,7 +36,7 @@ RUN git clone https://github.com/nginx-proxy/forego/ \
&& rm -rf /go/forego
# Build the final image
FROM nginx:1.21.6
FROM nginx:1.23.3
ARG NGINX_PROXY_VERSION
# Add DOCKER_GEN_VERSION environment variable
@ -67,7 +67,7 @@ COPY --from=dockergen /usr/local/bin/docker-gen /usr/local/bin/docker-gen
COPY network_internal.conf /etc/nginx/
COPY . /app/
COPY app nginx.tmpl LICENSE /app/
WORKDIR /app/
ENTRYPOINT ["/app/docker-entrypoint.sh"]

View File

@ -1,9 +1,9 @@
# setup build arguments for version of dependencies to use
ARG DOCKER_GEN_VERSION=0.8.2
ARG DOCKER_GEN_VERSION=0.10.2
ARG FOREGO_VERSION=v0.17.0
# Use a specific version of golang to build both binaries
FROM golang:1.17.8-alpine as gobuilder
FROM golang:1.20.2-alpine as gobuilder
RUN apk add --no-cache git musl-dev
# Build docker-gen from scratch
@ -37,7 +37,7 @@ RUN git clone https://github.com/nginx-proxy/forego/ \
&& rm -rf /go/forego
# Build the final image
FROM nginx:1.21.6-alpine
FROM nginx:1.23.3-alpine
ARG NGINX_PROXY_VERSION
# Add DOCKER_GEN_VERSION environment variable
@ -64,7 +64,7 @@ COPY --from=dockergen /usr/local/bin/docker-gen /usr/local/bin/docker-gen
COPY network_internal.conf /etc/nginx/
COPY . /app/
COPY app nginx.tmpl LICENSE /app/
WORKDIR /app/
ENTRYPOINT ["/app/docker-entrypoint.sh"]

View File

@ -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
View File

@ -1,6 +1,6 @@
[![Test](https://github.com/nginx-proxy/nginx-proxy/actions/workflows/test.yml/badge.svg)](https://github.com/nginx-proxy/nginx-proxy/actions/workflows/test.yml)
[![GitHub release](https://img.shields.io/github/v/release/nginx-proxy/nginx-proxy)](https://github.com/nginx-proxy/nginx-proxy/releases)
![nginx 1.21.6](https://img.shields.io/badge/nginx-1.21.6-brightgreen.svg)
![nginx 1.23.3](https://img.shields.io/badge/nginx-1.23.3-brightgreen.svg)
[![Docker Image Size](https://img.shields.io/docker/image-size/nginxproxy/nginx-proxy?sort=semver)](https://hub.docker.com/r/nginxproxy/nginx-proxy "Click to view the image on Docker Hub")
[![Docker stars](https://img.shields.io/docker/stars/nginxproxy/nginx-proxy.svg)](https://hub.docker.com/r/nginxproxy/nginx-proxy 'DockerHub')
[![Docker pulls](https://img.shields.io/docker/pulls/nginxproxy/nginx-proxy.svg)](https://hub.docker.com/r/nginxproxy/nginx-proxy 'DockerHub')
@ -122,7 +122,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.
@ -152,10 +152,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`
@ -220,6 +227,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
@ -335,10 +347,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.
@ -346,6 +357,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
@ -361,6 +397,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.
@ -378,10 +480,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 "";
@ -389,8 +492,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`.
@ -457,6 +558,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.
@ -468,12 +595,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

View File

@ -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 "$@"

File diff suppressed because it is too large Load Diff

View File

@ -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()

View File

@ -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
# 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 "$@"

View File

@ -1,5 +1,5 @@
backoff==1.11.1
backoff==2.2.1
docker-compose==1.29.2
docker==5.0.3
pytest==7.0.1
requests==2.27.1
docker==6.0.1
pytest==7.2.2
requests==2.28.2

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View 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)

View 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

View File

@ -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")

View File

@ -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

View File

@ -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")

View File

@ -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:

View File

@ -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-----

View File

@ -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-----

View File

@ -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-----

View File

@ -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-----

View File

@ -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-----

View File

@ -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-----

View 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

View 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

View 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

View 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

View 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

View 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

View 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-----

View 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-----

View File

@ -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-----

View File

@ -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-----

View File

@ -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-----

View File

@ -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-----

View File

@ -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-----

View File

@ -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-----

View 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

99
test/test_fallback.py Normal file
View File

@ -0,0 +1,99 @@
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),
])
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)

View File

@ -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):

View File

@ -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
View 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
View 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

View 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

View 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

View 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

View File

@ -0,0 +1,4 @@
# This file should trump the file without the hash.
location / {
return 418;
}

View File

@ -0,0 +1,4 @@
# The file with the hash should trump this file.
location / {
return 503;
}

View File

@ -0,0 +1,3 @@
location / {
return 418;
}

View File

@ -0,0 +1,4 @@
# This file should trump the file without the hash.
location / {
return 418;
}

View File

@ -0,0 +1,4 @@
# The file with the hash should trump this file.
location / {
return 503;
}

View File

@ -0,0 +1,3 @@
location / {
return 418;
}

View 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
View 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
View 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"

View File

@ -1,5 +1,8 @@
import re
import pytest
def test_unknown_virtual_host(docker_compose, nginxproxy):
r = nginxproxy.get("http://nginx-proxy/")
assert r.status_code == 503
@ -13,3 +16,13 @@ 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"
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

View File

@ -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

View File

@ -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'
)

View File

@ -54,7 +54,7 @@ with_custom_file:
volumes:
- *docker-sock
- *nginx-certs
- ../../dhparam/ffdhe3072.pem:/etc/nginx/dhparam/dhparam.pem:ro
- ../../app/dhparam/ffdhe3072.pem:/etc/nginx/dhparam/dhparam.pem:ro
with_skip:
container_name: dh-skip

View File

@ -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):

View File

@ -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)
r = nginxproxy.get("https://3.web.nginx-proxy.tld/port", verify=False)
assert r.status_code == 500
assert r.status_code == 503

View 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: 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-----

View File

@ -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-----

View 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)

View 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

View 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)

View 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

View 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)

View 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

View 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)

View 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"

View 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)

View 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