1
0
mirror of https://github.com/thib8956/nginx-proxy synced 2025-07-03 15:25:45 +00:00

78 Commits
0.3.0 ... 0.5.0

Author SHA1 Message Date
51aeee9a2c Merge pull request #619 from max-wilkinson/master
Clarified a couple parts in the README
2016-11-27 13:19:34 -07:00
fddae94ed8 Clarified a couple parts in the README 2016-10-28 14:46:37 -04:00
0670a13d92 Merge pull request #581 from chulkilee/ssl_session_tickets
add ssl_session_tickets to default site
2016-09-24 20:22:16 -06:00
4661bf4dd9 add ssl_session_tickets to default site
Fixes #580
2016-09-23 21:58:09 -07:00
760936d9ea Merge pull request #572 from pvlg/patch-2
Replace "replace" to "trimSuffix"
2016-09-17 09:58:27 -06:00
fe9a538ec8 Replace "replace" to "trimSuffix"
I have a domain key-mydomain.com. When I add domain www.key-mydomain.com with ssl cert I did not get the desired result. Function replace cut name ssl cert "www.key-mydomain.com.key" to "www-mydomain.com".
2016-09-17 16:53:01 +03:00
f02bc98a6e Merge pull request #566 from mplx/patch/hsts-no-subdomains
do not enable HSTS for subdomains
2016-09-13 09:18:27 -06:00
37323320c8 do not enable HSTS for subdomains 2016-09-12 09:46:59 +02:00
40d433ae80 Merge pull request #493 from ryneeverett/docker_compose_separate_containers
Add docker-compose file for separate containers.
2016-09-09 14:18:06 -06:00
ec7169c112 Merge pull request #323 from pabra/master
connect to uWSGI backends
2016-09-09 14:16:08 -06:00
e95d3e9fdf Merge pull request #555 from freakinruben/patch-1
Update ciphers and HTST settings to get A+ rating
2016-09-01 09:21:56 -06:00
87879c1ee2 Update ciphers and HTST settings to get A+ rating
The default config gets you an 'A' rating. Cipher settings are copied from [Mozilla SSL Configartion Generator](https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=nginx-1.10.1&openssl=1.0.1t&hsts=yes&profile=intermediate)
2016-09-01 11:34:56 +02:00
579bc1bf6e Merge pull request #518 from huiwang/nginx_upgrade
upgrade nginx to 1.11.3
2016-08-25 20:55:54 -06:00
176b78943e upgrade nginx to 1.11.3 in makefile 2016-08-25 21:46:57 +02:00
a6287d7df1 Merge pull request #545 from auchri/patch-1
Update .travis.yml
2016-08-25 12:30:16 -06:00
c113e7ac82 Update .travis.yml 2016-08-25 20:22:35 +02:00
03e863d838 upgrade nginx to 1.11.3 2016-08-25 20:16:37 +02:00
478ad17adb Remove proxy-tier network in favor of the default.
As @huiwang pointed out, using a custom network is unnecessary since the
default bridge network works just as well.
2016-07-29 17:23:10 -04:00
86c408bbdd upgrade nginx to 1.11.0 2016-07-29 21:17:14 +02:00
30128cfda0 Merge pull request #511 from kamermans/master
Mitigate httpoxy attack by suppressing `Proxy` request header
2016-07-19 12:15:35 -06:00
fd127517b9 Added comments about httpoxy 2016-07-19 11:03:41 -04:00
357d58ad97 Mitigate httpoxy attack (httpoxy.org, CVE-2016-(5385-5388,1000109-1000110) 2016-07-18 13:34:37 -04:00
5f684d4fc5 Add docker-compose file for separate containers.
Demonstrate that this pattern works.

This is based on the example at
<https://github.com/fatk/docker-letsencrypt-nginx-proxy-companion-examples/blob/master/docker-compose/v2/simple-site/docker-compose.yml>.
2016-07-13 17:31:53 -04:00
a2ab8363ca Merge pull request #483 from jwilder/jw-docker-gen
Update to docker-gen 0.7.3
2016-06-13 08:18:07 -06:00
8ed5ab38b8 Update to docker-gen 0.7.3 2016-06-13 00:24:21 -06:00
db3ef67a7f Merge pull request #482 from jwilder/jw-revert
Revert 9c93efa
2016-06-13 00:21:38 -06:00
580517725f Revert 9c93efa 2016-06-13 00:10:49 -06:00
d1e6e1c0be Merge pull request #344 from schmunk42/feature/error-code
changed error code for non-usable/default SSL cert, fixes #341
2016-06-12 15:54:40 -06:00
fc619d63ad Merge pull request #460 from kumy/patch-1
Fix a typo in comment
2016-06-12 15:28:40 -06:00
c36b42933d Merge pull request #462 from kamermans/master
Disable HSTS when HTTPS_METHOD=noredirect
2016-06-12 15:28:08 -06:00
a0dee5c833 Remove -only-exposed from separate container instructions 2016-06-12 15:25:32 -06:00
fdfb0becd2 Merge pull request #480 from jwilder/jw-certs
Fix template error when /etc/nginx/certs does not exist
2016-06-12 14:28:35 -06:00
fdf93cafba Add docker-compose.yml v2 example 2016-06-12 14:10:46 -06:00
b325dad98d Remove -only-exposed from Procfile 2016-06-12 14:10:46 -06:00
9c93efaef9 Fix template error when /etc/nginx/certs does not exist 2016-06-12 14:10:40 -06:00
adf4573de4 Remove Circle CI badge 2016-06-12 10:45:59 -06:00
8393a57f1f Merge pull request #477 from jwilder/jw-nginx
Nginx updates
2016-06-10 20:22:07 -06:00
9b0138f944 Remove docker compose v2 notes 2016-06-10 20:11:58 -06:00
c256f31728 Update nginx 1.9.15 2016-06-10 20:08:10 -06:00
da3e257843 Removed HSTS when HTTPS_METHOD=noredirect, added tests, improved docs wrt HSTS 2016-05-19 23:20:43 -04:00
3d77979efb Expanded documentation on HTTPS_METHOD 2016-05-19 23:16:19 -04:00
8c76ea9f9b Fix a typo in comment 2016-05-17 01:46:46 +02:00
0ef8dca98c Merge pull request #443 from jwilder/jw-circle
Remove circle.yml
2016-05-04 16:52:41 -06:00
c30640b024 Remove circle.yml
Using travis now
2016-05-04 16:05:03 -06:00
e964b9d29f Merge pull request #441 from jwilder/jw-0.7.1
Update to docker-gen 0.7.1
2016-05-04 16:03:52 -06:00
d40d1d4052 Update to docker-gen 0.7.1 2016-05-04 14:51:30 -06:00
5b9264d945 Merge pull request #298 from kamermans/master
Added env var to disable SSL redirect
2016-05-01 17:45:45 -06:00
1c98df2de4 Merge pull request #337 from baptistedonaux/master
Support Overlay Network
2016-05-01 17:35:48 -06:00
786a2375aa Using different path method to hopefully fix cert volume issue in CI systems 2016-04-20 12:47:14 -04:00
f296b273ce Normalized indentation, added explicit CERT_NAME 2016-04-20 12:33:21 -04:00
1d0a5d9194 Added SSL/HTTPS tests 2016-04-20 12:20:08 -04:00
f294582ae8 Merge branch 'master' of https://github.com/jwilder/nginx-proxy 2016-04-20 11:05:20 -04:00
f66934567e Merge remote-tracking branch 'upstream/master' 2016-04-05 09:22:31 +02:00
6928d62e1e Upgrade Docker dependency from 1.9 to 1.10 2016-03-24 14:40:50 +01:00
88cc096aaf [FIX] expose port for separated containers test 2016-03-24 11:16:22 +01:00
6b88365465 Merge remote-tracking branch 'upstream/master' 2016-03-24 08:41:23 +01:00
74fb2acc4b Merge remote-tracking branch 'upstream/master' 2016-03-23 08:52:58 +01:00
9671e0c1a2 Merge branch 'master' of https://github.com/jwilder/nginx-proxy 2016-03-18 13:47:11 -04:00
b42cd85570 Unit test - removed network creation 2016-02-26 09:12:11 +01:00
47631eb5de Merge remote-tracking branch 'upstream/master' 2016-02-25 09:59:04 +01:00
2b418319f2 Test to support overlay networks 2016-02-25 09:58:17 +01:00
163d1ce174 Upgrade docker-gen from 0.5.0 to 0.7.0 2016-02-25 08:26:41 +01:00
ebab7cf2b9 [TEMPLATE] fix variable call 2016-02-23 13:59:30 +01:00
658e20f661 Support container in one network shared with current container 2016-02-05 09:16:43 +01:00
9341f54e51 Merge pull request #1 from appropriate/overlay-support
Update README wording for overlay networking
2016-01-22 08:44:43 +01:00
b4e5f780e3 changed error code for non-usable/default SSL cert, fixes #341 2016-01-21 12:31:03 +01:00
5c828cb50a Update README wording for overlay networking 2016-01-20 23:30:55 -08:00
2eb977589c Complete documentation 2016-01-20 08:54:57 +01:00
99963b4ab0 Merge branch 'master' of https://github.com/jwilder/nginx-proxy 2016-01-18 16:37:03 -05:00
13bb99c4d2 Update README - Nginx proxy must use host network to support overlay network 2016-01-17 12:35:29 +01:00
a66115f560 Use new Network interface to support new overlay network 2016-01-17 12:29:55 +01:00
deb4050fa4 UPGRADE docker-gen release from 0.4.2 to 0.5.0 2016-01-17 12:28:59 +01:00
51c219d651 connect to uWSGI backends 2015-12-22 21:20:44 +01:00
4a95d84d0d Trying to trigger CI 2015-12-02 21:46:05 -05:00
58fc298dea Semantic change to trigger CI rebuild 2015-12-02 00:29:32 -05:00
4bf7f888d0 Documented HTTPS_METHOD 2015-11-20 17:47:08 -05:00
97c6340a9f Implemented HTTPS noredir 2015-11-20 17:37:06 -05:00
9dd6ad8503 First try at HTTPS_METHOD 2015-11-20 16:53:50 -05:00
15 changed files with 403 additions and 62 deletions

View File

@ -4,7 +4,7 @@ services:
env: env:
global: global:
- DOCKER_VERSION=1.10.1-0~trusty - DOCKER_VERSION=1.12.1-0~trusty
before_install: before_install:
# list docker-engine versions # list docker-engine versions

View File

@ -1,4 +1,4 @@
FROM nginx:1.9.12 FROM nginx:1.11.3
MAINTAINER Jason Wilder mail@jasonwilder.com MAINTAINER Jason Wilder mail@jasonwilder.com
# Install wget and install/updates certificates # Install wget and install/updates certificates
@ -17,7 +17,7 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf \
ADD https://github.com/jwilder/forego/releases/download/v0.16.1/forego /usr/local/bin/forego ADD https://github.com/jwilder/forego/releases/download/v0.16.1/forego /usr/local/bin/forego
RUN chmod u+x /usr/local/bin/forego RUN chmod u+x /usr/local/bin/forego
ENV DOCKER_GEN_VERSION 0.7.0 ENV DOCKER_GEN_VERSION 0.7.3
RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VERSION/docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VERSION/docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \
&& tar -C /usr/local/bin -xvzf docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ && tar -C /usr/local/bin -xvzf docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \

View File

@ -2,12 +2,12 @@
.PHONY : test .PHONY : test
update-dependencies: update-dependencies:
docker pull jwilder/docker-gen:0.7.0 docker pull jwilder/docker-gen:0.7.3
docker pull nginx:1.9.12 docker pull nginx:1.11.3
docker pull python:3 docker pull python:3
docker pull rancher/socat-docker:latest docker pull rancher/socat-docker:latest
docker pull appropriate/curl:latest docker pull appropriate/curl:latest
docker pull docker:1.9 docker pull docker:1.10
test: test:
docker build -t jwilder/nginx-proxy:bats . docker build -t jwilder/nginx-proxy:bats .

View File

@ -1,2 +1,2 @@
nginx: nginx nginx: nginx
dockergen: docker-gen -watch -only-exposed -notify "nginx -s reload" /app/nginx.tmpl /etc/nginx/conf.d/default.conf dockergen: docker-gen -watch -notify "nginx -s reload" /app/nginx.tmpl /etc/nginx/conf.d/default.conf

View File

@ -1,4 +1,4 @@
![nginx 1.9.12](https://img.shields.io/badge/nginx-1.9.12-brightgreen.svg) ![License MIT](https://img.shields.io/badge/license-MIT-blue.svg) [![Build](https://circleci.com/gh/jwilder/nginx-proxy.svg?&style=shield&circle-token=2da3ee844076a47371bd45da81cf27409ca7306a)](https://circleci.com/gh/jwilder/nginx-proxy) [![Build Status](https://travis-ci.org/jwilder/nginx-proxy.svg?branch=master)](https://travis-ci.org/jwilder/nginx-proxy) [![](https://img.shields.io/docker/stars/jwilder/nginx-proxy.svg)](https://hub.docker.com/r/jwilder/nginx-proxy 'DockerHub') [![](https://img.shields.io/docker/pulls/jwilder/nginx-proxy.svg)](https://hub.docker.com/r/jwilder/nginx-proxy 'DockerHub') ![nginx 1.11.3](https://img.shields.io/badge/nginx-1.11.3-brightgreen.svg) ![License MIT](https://img.shields.io/badge/license-MIT-blue.svg) [![Build Status](https://travis-ci.org/jwilder/nginx-proxy.svg?branch=master)](https://travis-ci.org/jwilder/nginx-proxy) [![](https://img.shields.io/docker/stars/jwilder/nginx-proxy.svg)](https://hub.docker.com/r/jwilder/nginx-proxy 'DockerHub') [![](https://img.shields.io/docker/pulls/jwilder/nginx-proxy.svg)](https://hub.docker.com/r/jwilder/nginx-proxy 'DockerHub')
nginx-proxy sets up a container running nginx and [docker-gen][1]. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped. nginx-proxy sets up a container running nginx and [docker-gen][1]. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped.
@ -19,10 +19,31 @@ The containers being proxied must [expose](https://docs.docker.com/reference/run
Provided your DNS is setup to forward foo.bar.com to the a host running nginx-proxy, the request will be routed to a container with the VIRTUAL_HOST env var set. Provided your DNS is setup to forward foo.bar.com to the a host running nginx-proxy, the request will be routed to a container with the VIRTUAL_HOST env var set.
### Docker-compose ### Docker Compose
Currently this does not work with the new v2 syntax of docker-compose (due to not being compatible with the new network overlay see [#304](https://github.com/jwilder/nginx-proxy/issues/304)). It does work when using the old docker-composer syntax. ```yaml
version: '2'
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
whoami:
image: jwilder/whoami
container_name: whoami
environment:
- VIRTUAL_HOST=whoami.local
```
```shell
$ docker-compose up
$ curl -H "Host: whoami.local" localhost
I'm 5b129ab83266
```
### Multiple Ports ### Multiple Ports
@ -39,9 +60,29 @@ If you need to support multiple virtual hosts for a container, you can separate
You can also use wildcards at the beginning and the end of host name, like `*.bar.com` or `foo.bar.*`. Or even a regular expression, which can be very useful in conjunction with a wildcard DNS service like [xip.io](http://xip.io), using `~^foo\.bar\..*\.xip\.io` will match `foo.bar.127.0.0.1.xip.io`, `foo.bar.10.0.2.2.xip.io` and all other given IPs. More information about this topic can be found in the nginx documentation about [`server_names`](http://nginx.org/en/docs/http/server_names.html). You can also use wildcards at the beginning and the end of host name, like `*.bar.com` or `foo.bar.*`. Or even a regular expression, which can be very useful in conjunction with a wildcard DNS service like [xip.io](http://xip.io), using `~^foo\.bar\..*\.xip\.io` will match `foo.bar.127.0.0.1.xip.io`, `foo.bar.10.0.2.2.xip.io` and all other given IPs. More information about this topic can be found in the nginx documentation about [`server_names`](http://nginx.org/en/docs/http/server_names.html).
### Multiple Networks
With the addition of [overlay networking](https://docs.docker.com/engine/userguide/networking/get-started-overlay/) in Docker 1.9, your `nginx-proxy` container may need to connect to backend containers on multiple networks. By default, if you don't pass the `--net` flag when your `nginx-proxy` container is created, it will only be attached to the default `bridge` network. This means that it will not be able to connect to containers on networks other than `bridge`.
If you want your `nginx-proxy` container to be attached to a different network, you must pass the `--net=my-network` option in your `docker create` or `docker run` command. At the time of this writing, only a single network can be specified at container creation time. To attach to other networks, you can use the `docker network connect` command after your container is created:
```console
$ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro \
--name my-nginx-proxy --net my-network jwilder/nginx-proxy
$ docker network connect my-other-network my-nginx-proxy
```
In this example, the `my-nginx-proxy` container will be connected to `my-network` and `my-other-network` and will be able to proxy to other containers attached to those networks.
### SSL Backends ### SSL Backends
If you would like to connect to your backend using HTTPS instead of HTTP, set `VIRTUAL_PROTO=https` on the backend container. If you would like the reverse proxy to connect to your backend using HTTPS instead of HTTP, set `VIRTUAL_PROTO=https` on the backend container.
### uWSGI Backends
If you would like to connect to uWSGI backend, set `VIRTUAL_PROTO=uwsgi` on the
backend container. Your backend container should than listen on a port rather
than a socket and expose that port.
### Default Host ### Default Host
@ -57,6 +98,14 @@ image and the official [nginx](https://registry.hub.docker.com/_/nginx/) image.
You may want to do this to prevent having the docker socket bound to a publicly exposed container service. You may want to do this to prevent having the docker socket bound to a publicly exposed container service.
You can demo this pattern with docker-compose:
```console
$ docker-compose --file docker-compose-separate-containers.yml up
$ curl -H "Host: whoami.local" localhost
I'm 5b129ab83266
```
To run nginx proxy as a separate container you'll need to have [nginx.tmpl](https://github.com/jwilder/nginx-proxy/blob/master/nginx.tmpl) on your host system. To run nginx proxy as a separate container you'll need to have [nginx.tmpl](https://github.com/jwilder/nginx-proxy/blob/master/nginx.tmpl) on your host system.
First start nginx with a volume: First start nginx with a volume:
@ -70,7 +119,7 @@ Then start the docker-gen container with the shared volume and template:
$ docker run --volumes-from nginx \ $ docker run --volumes-from nginx \
-v /var/run/docker.sock:/tmp/docker.sock:ro \ -v /var/run/docker.sock:/tmp/docker.sock:ro \
-v $(pwd):/etc/docker-gen/templates \ -v $(pwd):/etc/docker-gen/templates \
-t jwilder/docker-gen -notify-sighup nginx -watch -only-exposed /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf -t jwilder/docker-gen -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
``` ```
Finally, start your containers with `VIRTUAL_HOST` environment variables. Finally, start your containers with `VIRTUAL_HOST` environment variables.
@ -91,6 +140,10 @@ hosts in use. The certificate and keys should be named after the virtual host w
`.key` extension. For example, a container with `VIRTUAL_HOST=foo.bar.com` should have a `.key` extension. For example, a container with `VIRTUAL_HOST=foo.bar.com` should have a
`foo.bar.com.crt` and `foo.bar.com.key` file in the certs directory. `foo.bar.com.crt` and `foo.bar.com.key` file in the certs directory.
If you are running the container in a virtualized environment (Hyper-V, VirtualBox, etc...),
/path/to/certs must exist in that environment or be made accessible to that environment.
By default, Docker is not able to mount directories on the host machine to containers running in a virtual machine.
#### Diffie-Hellman Groups #### Diffie-Hellman Groups
If you have Diffie-Hellman groups enabled, the files should be named after the virtual host with a If you have Diffie-Hellman groups enabled, the files should be named after the virtual host with a
@ -116,7 +169,7 @@ should provide compatibility with clients back to Firefox 1, Chrome 1, IE 7, Ope
Windows XP IE8, Android 2.3, Java 7. The configuration also enables HSTS, and SSL Windows XP IE8, Android 2.3, Java 7. The configuration also enables HSTS, and SSL
session caches. session caches.
The behavior for the proxy when port 80 and 443 are exposed is as follows: 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 * If a container has a usable cert, port 80 will redirect to 443 for that container so that HTTPS
is always preferred when available. is always preferred when available.
@ -127,6 +180,15 @@ to establish a connection. A self-signed or generic cert named `default.crt` an
will allow a client browser to make a SSL connection (likely w/ a warning) and subsequently receive will allow a client browser to make a SSL connection (likely w/ a warning) and subsequently receive
a 503. a 503.
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`. `HTTPS_METHOD` must be specified
on each container for which you want to override the default behavior. 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.
### Basic Authentication Support ### 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 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
@ -161,10 +223,15 @@ proxy_set_header Connection $proxy_connection;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
# Mitigate httpoxy attack (see README for details)
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***: 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 #### 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`. To add settings on a proxy-wide basis, add your configuration file under `/etc/nginx/conf.d` using a name ending in `.conf`.

View File

@ -1,17 +0,0 @@
machine:
pre:
- sudo curl -L -o /usr/bin/docker 'https://s3-external-1.amazonaws.com/circle-downloads/docker-1.9.1-circleci'
- sudo chmod 0755 /usr/bin/docker
services:
- docker
dependencies:
override:
- sudo add-apt-repository ppa:duggan/bats --yes
- sudo apt-get update -qq
- sudo apt-get install -qq bats
- make update-dependencies
test:
override:
- make test

View File

@ -0,0 +1,23 @@
version: '2'
services:
nginx:
image: nginx
container_name: nginx
ports:
- "80:80"
volumes:
- /etc/nginx/conf.d
dockergen:
image: jwilder/docker-gen
command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
volumes_from:
- nginx
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
whoami:
image: jwilder/whoami
environment:
- VIRTUAL_HOST=whoami.local

15
docker-compose.yml Normal file
View File

@ -0,0 +1,15 @@
version: '2'
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
whoami:
image: jwilder/whoami
environment:
- VIRTUAL_HOST=whoami.local

View File

@ -1,3 +1,5 @@
{{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }}
{{ define "upstream" }} {{ define "upstream" }}
{{ if .Address }} {{ if .Address }}
{{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}} {{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}}
@ -5,13 +7,13 @@
# {{ .Container.Node.Name }}/{{ .Container.Name }} # {{ .Container.Node.Name }}/{{ .Container.Name }}
server {{ .Container.Node.Address.IP }}:{{ .Address.HostPort }}; server {{ .Container.Node.Address.IP }}:{{ .Address.HostPort }};
{{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}} {{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}}
{{ else }} {{ else if .Network }}
# {{ .Container.Name }} # {{ .Container.Name }}
server {{ .Address.IP }}:{{ .Address.Port }}; server {{ .Network.IP }}:{{ .Address.Port }};
{{ end }} {{ end }}
{{ else }} {{ else if .Network }}
# {{ .Container.Name }} # {{ .Container.Name }}
server {{ .Container.IP }} down; server {{ .Network.IP }} down;
{{ end }} {{ end }}
{{ end }} {{ end }}
@ -49,6 +51,9 @@ proxy_set_header Connection $proxy_connection;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";
{{ end }} {{ end }}
server { server {
@ -65,6 +70,7 @@ server {
access_log /var/log/nginx/access.log vhost; access_log /var/log/nginx/access.log vhost;
return 503; return 503;
ssl_session_tickets off;
ssl_certificate /etc/nginx/certs/default.crt; ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key; ssl_certificate_key /etc/nginx/certs/default.key;
} }
@ -75,15 +81,24 @@ server {
upstream {{ $host }} { upstream {{ $host }} {
{{ range $container := $containers }} {{ range $container := $containers }}
{{ $addrLen := len $container.Addresses }} {{ $addrLen := len $container.Addresses }}
{{ range $knownNetwork := $CurrentContainer.Networks }}
{{ range $containerNetwork := $container.Networks }}
{{ if eq $knownNetwork.Name $containerNetwork.Name }}
## Can be connect with "{{ $containerNetwork.Name }}" network
{{/* If only 1 port exposed, use that */}} {{/* If only 1 port exposed, use that */}}
{{ if eq $addrLen 1 }} {{ if eq $addrLen 1 }}
{{ $address := index $container.Addresses 0 }} {{ $address := index $container.Addresses 0 }}
{{ template "upstream" (dict "Container" $container "Address" $address) }} {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }}
{{/* If more than one port exposed, use the one matching VIRTUAL_PORT env var, falling back to standard web port 80 */}} {{/* If more than one port exposed, use the one matching VIRTUAL_PORT env var, falling back to standard web port 80 */}}
{{ else }} {{ else }}
{{ $port := coalesce $container.Env.VIRTUAL_PORT "80" }} {{ $port := coalesce $container.Env.VIRTUAL_PORT "80" }}
{{ $address := where $container.Addresses "Port" $port | first }} {{ $address := where $container.Addresses "Port" $port | first }}
{{ template "upstream" (dict "Container" $container "Address" $address) }} {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }}
{{ end }}
{{ end }}
{{ end }}
{{ end }} {{ end }}
{{ end }} {{ end }}
} }
@ -94,6 +109,9 @@ upstream {{ $host }} {
{{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}} {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}}
{{ $proto := or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http" }} {{ $proto := or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http" }}
{{/* Get the HTTPS_METHOD defined by containers w/ the same vhost, falling back to "redirect" */}}
{{ $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) "redirect" }}
{{/* Get the first cert name defined by containers w/ the same vhost */}} {{/* Get the first cert name defined by containers w/ the same vhost */}}
{{ $certName := (first (groupByKeys $containers "Env.CERT_NAME")) }} {{ $certName := (first (groupByKeys $containers "Env.CERT_NAME")) }}
@ -101,20 +119,24 @@ upstream {{ $host }} {
{{ $vhostCert := (closest (dir "/etc/nginx/certs") (printf "%s.crt" $host))}} {{ $vhostCert := (closest (dir "/etc/nginx/certs") (printf "%s.crt" $host))}}
{{/* vhostCert is actually a filename so remove any suffixes since they are added later */}} {{/* vhostCert is actually a filename so remove any suffixes since they are added later */}}
{{ $vhostCert := replace $vhostCert ".crt" "" -1 }} {{ $vhostCert := trimSuffix ".crt" $vhostCert }}
{{ $vhostCert := replace $vhostCert ".key" "" -1 }} {{ $vhostCert := trimSuffix ".key" $vhostCert }}
{{/* Use the cert specifid on the container or fallback to the best vhost match */}} {{/* Use the cert specified on the container or fallback to the best vhost match */}}
{{ $cert := (coalesce $certName $vhostCert) }} {{ $cert := (coalesce $certName $vhostCert) }}
{{ if (and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert))) }} {{ $is_https := (and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert))) }}
{{ if $is_https }}
{{ if eq $https_method "redirect" }}
server { server {
server_name {{ $host }}; server_name {{ $host }};
listen 80 {{ $default_server }}; listen 80 {{ $default_server }};
access_log /var/log/nginx/access.log vhost; access_log /var/log/nginx/access.log vhost;
return 301 https://$host$request_uri; return 301 https://$host$request_uri;
} }
{{ end }}
server { server {
server_name {{ $host }}; server_name {{ $host }};
@ -122,11 +144,12 @@ server {
access_log /var/log/nginx/access.log vhost; access_log /var/log/nginx/access.log vhost;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on; ssl_prefer_server_ciphers on;
ssl_session_timeout 5m; ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m; ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_certificate /etc/nginx/certs/{{ (printf "%s.crt" $cert) }}; ssl_certificate /etc/nginx/certs/{{ (printf "%s.crt" $cert) }};
ssl_certificate_key /etc/nginx/certs/{{ (printf "%s.key" $cert) }}; ssl_certificate_key /etc/nginx/certs/{{ (printf "%s.key" $cert) }};
@ -135,7 +158,9 @@ server {
ssl_dhparam {{ printf "/etc/nginx/certs/%s.dhparam.pem" $cert }}; ssl_dhparam {{ printf "/etc/nginx/certs/%s.dhparam.pem" $cert }};
{{ end }} {{ end }}
{{ if (ne $https_method "noredirect") }}
add_header Strict-Transport-Security "max-age=31536000"; add_header Strict-Transport-Security "max-age=31536000";
{{ end }}
{{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }}
include {{ printf "/etc/nginx/vhost.d/%s" $host }}; include {{ printf "/etc/nginx/vhost.d/%s" $host }};
@ -144,7 +169,12 @@ server {
{{ end }} {{ end }}
location / { location / {
{{ if eq $proto "uwsgi" }}
include uwsgi_params;
uwsgi_pass {{ trim $proto }}://{{ trim $host }};
{{ else }}
proxy_pass {{ trim $proto }}://{{ trim $host }}; proxy_pass {{ trim $proto }}://{{ trim $host }};
{{ end }}
{{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }} {{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
auth_basic "Restricted {{ $host }}"; auth_basic "Restricted {{ $host }}";
auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }};
@ -156,7 +186,10 @@ server {
{{ end }} {{ end }}
} }
} }
{{ else }}
{{ end }}
{{ if or (not $is_https) (eq $https_method "noredirect") }}
server { server {
server_name {{ $host }}; server_name {{ $host }};
@ -170,7 +203,12 @@ server {
{{ end }} {{ end }}
location / { location / {
{{ if eq $proto "uwsgi" }}
include uwsgi_params;
uwsgi_pass {{ trim $proto }}://{{ trim $host }};
{{ else }}
proxy_pass {{ trim $proto }}://{{ trim $host }}; proxy_pass {{ trim $proto }}://{{ trim $host }};
{{ end }}
{{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }} {{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
auth_basic "Restricted {{ $host }}"; auth_basic "Restricted {{ $host }}";
auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }};
@ -183,12 +221,12 @@ server {
} }
} }
{{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} {{ if (and (not $is_https) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
server { server {
server_name {{ $host }}; server_name {{ $host }};
listen 443 ssl http2 {{ $default_server }}; listen 443 ssl http2 {{ $default_server }};
access_log /var/log/nginx/access.log vhost; access_log /var/log/nginx/access.log vhost;
return 503; return 500;
ssl_certificate /etc/nginx/certs/default.crt; ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key; ssl_certificate_key /etc/nginx/certs/default.key;

View File

@ -73,7 +73,8 @@ load test_helpers
-v /var/run/docker.sock:/tmp/docker.sock:ro \ -v /var/run/docker.sock:/tmp/docker.sock:ro \
-v $BATS_TEST_DIRNAME/../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro \ -v $BATS_TEST_DIRNAME/../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro \
--volumes-from bats-nginx \ --volumes-from bats-nginx \
jwilder/docker-gen:0.7.0 \ --expose 80 \
jwilder/docker-gen:0.7.3 \
-notify-sighup bats-nginx \ -notify-sighup bats-nginx \
-watch \ -watch \
-only-exposed \ -only-exposed \
@ -120,4 +121,3 @@ function assert_nginxproxy_behaves {
run curl_container $container /data --header "Host: webFOO.bats" --head run curl_container $container /data --header "Host: webFOO.bats" --head
assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r' assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r'
} }

View File

@ -62,5 +62,5 @@ function docker_tcp {
--expose 2375 \ --expose 2375 \
-v /var/run/docker.sock:/var/run/docker.sock \ -v /var/run/docker.sock:/var/run/docker.sock \
rancher/socat-docker rancher/socat-docker
docker run --label bats-type="docker" --link "$container_name:docker" docker:1.9 version docker run --label bats-type="docker" --link "$container_name:docker" docker:1.10 version
} }

View File

@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIID7TCCAtWgAwIBAgIJAOGkf5EnexJVMA0GCSqGSIb3DQEBCwUAMIGMMQswCQYD
VQQGEwJVUzERMA8GA1UECAwIVmlyZ2luaWExDzANBgNVBAcMBlJlc3RvbjERMA8G
A1UECgwIRmFrZSBPcmcxGzAZBgNVBAMMEioubmdpbngtcHJveHkuYmF0czEpMCcG
CSqGSIb3DQEJARYad2VibWFzdGVyQG5naW54LXByb3h5LmJhdHMwHhcNMTYwNDIw
MTUzOTUxWhcNMjYwNDE4MTUzOTUxWjCBjDELMAkGA1UEBhMCVVMxETAPBgNVBAgM
CFZpcmdpbmlhMQ8wDQYDVQQHDAZSZXN0b24xETAPBgNVBAoMCEZha2UgT3JnMRsw
GQYDVQQDDBIqLm5naW54LXByb3h5LmJhdHMxKTAnBgkqhkiG9w0BCQEWGndlYm1h
c3RlckBuZ2lueC1wcm94eS5iYXRzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA0Amkj3iaQn8Z2CW6n24zSuWu2OoLCkHZAk8eprkI4kKoPBvjusynkm8E
phq65jebToHoldfuQ0wM61DzhD15bHwS3x9CrOVbShsmdnGALz+wdR0/4Likx50I
YZdecTOAlkoZudnX5FZ4ngOxjqcym7p5T8TrSS97a0fx99gitZY0p+Nu2tip4o3t
WBMs+SoPWTlQ1SrSmL8chC8O2knyBl/w1nHmDnMuR6FGcHdhLncApw9t5spgfv7p
OrMF4tQxJQNk10TnflmEMkGmy+pfk2e0cQ1Kwp3Nmzm7ECkggxxyjU3ihKiFK+09
8aSCi7gDAY925+mV6LZ5oLMpO3KJvQIDAQABo1AwTjAdBgNVHQ4EFgQU+NvFo37z
9Dyq8Mu82SPtV7q1gYQwHwYDVR0jBBgwFoAU+NvFo37z9Dyq8Mu82SPtV7q1gYQw
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAI1ityDV0UsCVHSpB2LN+
QXlk8XS0ACIJ8Q0hbOj3BmYrdAVglG4P6upDEueaaxwsaBTagkTP8nxZ9dhfZHyZ
5YLNwYsiG5iqb8e0ecHx3uJT/0YiXn/8rBvxEZna4Fl8seGdp7BjOWUAS2Nv8tn4
EJJvRdfX/O8XgPc95DM4lwQ/dvyWmavMI4lnl0n1IQV9WPGaIQhYPU9WEQK6iMUB
o1kx8YbOJQD0ZBRfqpriNt1/8ylkkSYYav8QT9JFvQFCWEvaX71QF+cuOwC7ZYBH
4ElXwEUrYBHKiPo0q0VsTtMvLh7h/T5czrIhG/NpfVJPtQOk8aVwNScL3/n+TGU8
6g==
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDQCaSPeJpCfxnY
JbqfbjNK5a7Y6gsKQdkCTx6muQjiQqg8G+O6zKeSbwSmGrrmN5tOgeiV1+5DTAzr
UPOEPXlsfBLfH0Ks5VtKGyZ2cYAvP7B1HT/guKTHnQhhl15xM4CWShm52dfkVnie
A7GOpzKbunlPxOtJL3trR/H32CK1ljSn427a2Knije1YEyz5Kg9ZOVDVKtKYvxyE
Lw7aSfIGX/DWceYOcy5HoUZwd2EudwCnD23mymB+/uk6swXi1DElA2TXROd+WYQy
QabL6l+TZ7RxDUrCnc2bObsQKSCDHHKNTeKEqIUr7T3xpIKLuAMBj3bn6ZXotnmg
syk7com9AgMBAAECggEAa7wCp3XqVPNjW+c1/ShhkbDeWmDhtL8i9aopkmeSbTHd
07sRtQQU56Vsf+Sp010KpZ5q52Z6cglpS1eRtHLtdbvPPhL/QXBJVVg4E/B1VIKk
DBJIqUSVuPXeiEOOWgs01R+ssO1ae1o4foQlKF33vGPWPPQacL0RKh6I9TPNzcD7
n4rujlHk72N/bNydyK2rnyKB4vAI5TbZPLps+Xe123CmgZnW3JClcWV9B4foRmiu
a5Iq1WYAK2GYKbYwgqDRyYBC27m91a7U31pE4GQD+xQdlz6kcOlCU5hAcPK3h7j0
fLQqn8g+YAtc0nBKKB4NZe3QEzTiVMorT0VitxI71QKBgQDnirardZaXOFzYGzB3
j+FGB9BUW54hnHr5BxOYrfmEJ5umJjJWaGupfYrQsPArrJP1//WbqVZIPvdQParD
mQhLmSp1r/VNzGB6pISmzU1ZGDHsmBxYseh366om5YBQUFU2vmbil9VkrkM4fsJG
tcS9V/nVY/EM7Yp3PzjfLlhC1wKBgQDmA1YJmnZvIbLp3PoKqM69QiCLKztVm7nX
xpu3b3qbXEzXkt2sP5PHmr+s13hOPQFKRJ2hk4UN9WqpnFoHw5E5eWWhSa/peUZm
r10Y5XspiFtRHHiu6ABXB49eB4fen+vHEZHKyRJ4rFthKjjBHdNPC8bmwnT3jE85
/8a26FLZiwKBgQDXEi8JZslBn9YF2oOTm28KCLoHka551AsaA+u892T8z3mxxGsf
fhD7N6TYonIEb2Jkr6OpOortwqcgvpc+5oghCJ27AX2fDUdUxDp/YdYF+wZsmQJD
lMW1lo7PYIBmmaf9mLCiq5xIz+GauYul+LNNmUl0YEgI1SC4EV63WCodswKBgDMX
GJxHd/kVViVGFTAa8NjvAEWJU8OfNHduQRZMp8IsjVDw6VYiRRP4Fo0wyyMtv8Sc
WxsRpmNEWO3VsdW5pd9LTLy3nmBQtMeIOjiWeHXwOMBaf5/yHmk2X6z2JULY6Mkt
6OFPKlAtkJqTg0m58z7Ckeqd1NdLjimG27+y+PwjAoGAFt0cbC1Ust2BE6YEspSX
ofpAnJsyKrbF9iVUyXDUP99sdqYQfPJ5uqPGkP59lJGkTLtebuitqi6FCyrsT6Fq
AWLiExbqebAqcuAZw2S+iuK27S4rrkjVGF53J7vH3rOzCBUXaRx6GKfTjUqedHdg
9Kw+LP6IFnMTb+EGLo+GqHs=
-----END PRIVATE KEY-----

146
test/ssl.bats Normal file
View File

@ -0,0 +1,146 @@
#!/usr/bin/env bats
load test_helpers
SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE}
function setup {
# make sure to stop any web container before each test so we don't
# have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set
stop_bats_containers web
}
@test "[$TEST_FILE] start a nginx-proxy container" {
run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro -v ${DIR}/lib/ssl:/etc/nginx/certs:ro
assert_success
docker_wait_for_log $SUT_CONTAINER 9 "Watching docker events"
}
@test "[$TEST_FILE] test SSL for VIRTUAL_HOST=*.nginx-proxy.bats" {
# WHEN
prepare_web_container bats-ssl-hosts-1 "80 443" \
-e VIRTUAL_HOST=*.nginx-proxy.bats \
-e CERT_NAME=nginx-proxy.bats
dockergen_wait_for_event $SUT_CONTAINER start bats-ssl-hosts-1
sleep 1
# THEN
assert_301 test.nginx-proxy.bats
assert_200_https test.nginx-proxy.bats
}
@test "[$TEST_FILE] test HTTPS_METHOD=nohttp" {
# WHEN
prepare_web_container bats-ssl-hosts-2 "80 443" \
-e VIRTUAL_HOST=*.nginx-proxy.bats \
-e CERT_NAME=nginx-proxy.bats \
-e HTTPS_METHOD=nohttp
dockergen_wait_for_event $SUT_CONTAINER start bats-ssl-hosts-2
sleep 1
# THEN
assert_503 test.nginx-proxy.bats
assert_200_https test.nginx-proxy.bats
}
@test "[$TEST_FILE] test HTTPS_METHOD=noredirect" {
# WHEN
prepare_web_container bats-ssl-hosts-3 "80 443" \
-e VIRTUAL_HOST=*.nginx-proxy.bats \
-e CERT_NAME=nginx-proxy.bats \
-e HTTPS_METHOD=noredirect
dockergen_wait_for_event $SUT_CONTAINER start bats-ssl-hosts-3
sleep 1
# THEN
assert_200 test.nginx-proxy.bats
assert_200_https test.nginx-proxy.bats
}
@test "[$TEST_FILE] test SSL Strict-Transport-Security" {
# WHEN
prepare_web_container bats-ssl-hosts-4 "80 443" \
-e VIRTUAL_HOST=*.nginx-proxy.bats \
-e CERT_NAME=nginx-proxy.bats
dockergen_wait_for_event $SUT_CONTAINER start bats-ssl-hosts-1
sleep 1
# THEN
assert_301 test.nginx-proxy.bats
assert_200_https test.nginx-proxy.bats
assert_output -p "Strict-Transport-Security: max-age=31536000"
}
@test "[$TEST_FILE] test HTTPS_METHOD=noredirect disables Strict-Transport-Security" {
# WHEN
prepare_web_container bats-ssl-hosts-5 "80 443" \
-e VIRTUAL_HOST=*.nginx-proxy.bats \
-e CERT_NAME=nginx-proxy.bats \
-e HTTPS_METHOD=noredirect
dockergen_wait_for_event $SUT_CONTAINER start bats-ssl-hosts-3
sleep 1
# THEN
assert_200 test.nginx-proxy.bats
assert_200_https test.nginx-proxy.bats
refute_output -p "Strict-Transport-Security: max-age=31536000"
}
@test "[$TEST_FILE] stop all bats containers" {
stop_bats_containers
}
# assert that querying nginx-proxy with the given Host header produces a `HTTP 200` response
# $1 Host HTTP header to use when querying nginx-proxy
function assert_200 {
local -r host=$1
run curl_container $SUT_CONTAINER / --head --header "Host: $host"
assert_output -l 0 $'HTTP/1.1 200 OK\r'
}
# assert that querying nginx-proxy with the given Host header produces a `HTTP 503` response
# $1 Host HTTP header to use when querying nginx-proxy
function assert_503 {
local -r host=$1
run curl_container $SUT_CONTAINER / --head --header "Host: $host"
assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r'
}
# assert that querying nginx-proxy with the given Host header produces a `HTTP 503` response
# $1 Host HTTP header to use when querying nginx-proxy
function assert_301 {
local -r host=$1
run curl_container $SUT_CONTAINER / --head --header "Host: $host"
assert_output -l 0 $'HTTP/1.1 301 Moved Permanently\r'
}
# assert that querying nginx-proxy with the given Host header produces a `HTTP 200` response
# $1 Host HTTP header to use when querying nginx-proxy
function assert_200_https {
local -r host=$1
run curl_container_https $SUT_CONTAINER / --head --header "Host: $host"
assert_output -l 0 $'HTTP/1.1 200 OK\r'
}
# assert that querying nginx-proxy with the given Host header produces a `HTTP 503` response
# $1 Host HTTP header to use when querying nginx-proxy
function assert_503_https {
local -r host=$1
run curl_container_https $SUT_CONTAINER / --head --header "Host: $host"
assert_output -l 0 $'HTTP/1.1 503 Service Temporarily Unavailable\r'
}
# assert that querying nginx-proxy with the given Host header produces a `HTTP 503` response
# $1 Host HTTP header to use when querying nginx-proxy
function assert_301_https {
local -r host=$1
run curl_container_https $SUT_CONTAINER / --head --header "Host: $host"
assert_output -l 0 $'HTTP/1.1 301 Moved Permanently\r'
}

View File

@ -74,6 +74,23 @@ function curl_container {
http://$(docker_ip $container)${path} http://$(docker_ip $container)${path}
} }
# Send a HTTPS request to container $1 for path $2 and
# Additional curl options can be passed as $@
#
# $1 container name
# $2 HTTPS path to query
# $@ additional options to pass to the curl command
function curl_container_https {
local -r container=$1
local -r path=$2
shift 2
docker run --label bats-type="curl" appropriate/curl --silent \
--connect-timeout 5 \
--max-time 20 \
--insecure \
"$@" \
https://$(docker_ip $container)${path}
}
# start a container running (one or multiple) webservers listening on given ports # start a container running (one or multiple) webservers listening on given ports
# #