Merge pull request #298 from kamermans/master
Added env var to disable SSL redirect
This commit is contained in:
commit
5b9264d945
6 changed files with 204 additions and 4 deletions
|
@ -130,7 +130,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.
|
||||||
|
@ -141,6 +141,10 @@ 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`.
|
||||||
|
|
||||||
### 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
|
||||||
|
|
16
nginx.tmpl
16
nginx.tmpl
|
@ -105,6 +105,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")) }}
|
||||||
|
|
||||||
|
@ -118,14 +121,18 @@ upstream {{ $host }} {
|
||||||
{{/* Use the cert specifid on the container or fallback to the best vhost match */}}
|
{{/* Use the cert specifid 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 }};
|
||||||
|
@ -167,7 +174,10 @@ server {
|
||||||
{{ end }}
|
{{ end }}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{ else }}
|
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if or (not $is_https) (eq $https_method "noredirect") }}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
server_name {{ $host }};
|
server_name {{ $host }};
|
||||||
|
@ -194,7 +204,7 @@ 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 }};
|
||||||
|
|
24
test/lib/ssl/nginx-proxy.bats.crt
Normal file
24
test/lib/ssl/nginx-proxy.bats.crt
Normal 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-----
|
28
test/lib/ssl/nginx-proxy.bats.key
Normal file
28
test/lib/ssl/nginx-proxy.bats.key
Normal 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-----
|
117
test/ssl.bats
Normal file
117
test/ssl.bats
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
#!/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] 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'
|
||||||
|
}
|
|
@ -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
|
||||||
#
|
#
|
||||||
|
|
Reference in a new issue