From fa4cab9f6f61ae34941978df6548f768437b0743 Mon Sep 17 00:00:00 2001 From: Darrin Thompson Date: Fri, 25 Sep 2015 17:03:55 -0400 Subject: [PATCH] Allow vhosts to serve both http and https. --- README.md | 3 ++- nginx.tmpl | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b4b1df7..34e5e56 100644 --- a/README.md +++ b/README.md @@ -112,8 +112,9 @@ session caches. The 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 +* By default, if a container has a usable cert, port 80 will redirect to 443 for that container so that HTTPS is always preferred when available. +* Set NO_HTTPS_REDIRECT=1 on the backend container if it is desired to serve both http and https from it. * 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 diff --git a/nginx.tmpl b/nginx.tmpl index 08f6c01..8928221 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -93,6 +93,9 @@ upstream {{ $host }} { {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}} {{ $proto := or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http" }} +{{/* Sometimes we don't want port 80 redirected to 443. */}} +{{ $no_https_redirect := (first (groupByKeys $containers "Env.NO_HTTPS_REDIRECT")) }} + {{/* Get the first cert name defined by containers w/ the same vhost */}} {{ $certName := (first (groupByKeys $containers "Env.CERT_NAME")) }} @@ -106,7 +109,50 @@ upstream {{ $host }} { {{/* Use the cert specifid on the container or fallback to the best vhost match */}} {{ $cert := (coalesce $certName $vhostCert) }} -{{ if (and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert))) }} +{{ if (and $no_https_redirect (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert))) }} + +server { + server_name {{ $host }}; + listen 443 ssl spdy {{ $default_server }}; + listen 80 {{ $default_server }}; + access_log /var/log/nginx/access.log vhost; + + 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_prefer_server_ciphers on; + ssl_session_timeout 5m; + ssl_session_cache shared:SSL:50m; + + ssl_certificate /etc/nginx/certs/{{ (printf "%s.crt" $cert) }}; + ssl_certificate_key /etc/nginx/certs/{{ (printf "%s.key" $cert) }}; + + {{ if (exists (printf "/etc/nginx/certs/%s.dhparam.pem" $cert)) }} + ssl_dhparam {{ printf "/etc/nginx/certs/%s.dhparam.pem" $cert }}; + {{ end }} + + add_header Strict-Transport-Security "max-age=31536000"; + + {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} + include {{ printf "/etc/nginx/vhost.d/%s" $host }}; + {{ else if (exists "/etc/vhost.d/default") }} + include /etc/nginx/vhost.d/default; + {{ end }} + + location / { + proxy_pass {{ $proto }}://{{ $host }}; + {{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }} + auth_basic "Restricted {{ $host }}"; + auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; + {{ end }} + {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} + include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; + {{ else if (exists "/etc/vhost.d/default_location") }} + include /etc/nginx/vhost.d/default_location; + {{ end }} + } +} +{{ else if (and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert))) }} server { server_name {{ $host }};