1
0
Fork 0
mirror of https://github.com/nginx-proxy/nginx-proxy synced 2024-04-27 04:15:26 +02:00

fix: Don't downgrade from https to http if certificate is missing

Before, if a site's certificate was not found, the site was served
over http rather than https.  Failing open like this is problematic
for sites where security is important.  Presumably the user set
`HTTPS_METHOD` to a non-`noredirect` value (or left it unset) for a
good reason; we should honor it even if it means serving error
messages.

WARNING: This change breaks compatibility.  Any vhost where all of the
following are true will fail after this change:

  * `HTTPS_METHOD` is either unset or set to a value other than
    `nohttps`.
  * The vhost does not have its own certificate (`default.crt` doesn't
    count).
  * Clients expect to be able to access the vhost by using plain http
    to nginx-proxy.

To get the previous behavior, set `HTTPS_METHOD` to `nohttps` for the
vhost.
This commit is contained in:
Richard Hansen 2023-02-03 02:31:08 -05:00
parent 87108892f6
commit dfd4f54c61
42 changed files with 84 additions and 19 deletions

View File

@ -349,8 +349,8 @@ proxy_set_header Proxy "";
{{- /*
* Precompute some information about each vhost. This is done early because
* the creation of fallback servers depends on DEFAULT_HOST, HTTPS_METHOD,
* and whether there are any missing certs.
* the creation of fallback servers depends on DEFAULT_HOST and
* HTTPS_METHOD.
*/}}
{{- range $vhost, $containers := groupByMulti $globals.containers "Env.VIRTUAL_HOST" "," }}
{{- $vhost := trim $vhost }}
@ -389,7 +389,7 @@ proxy_set_header Proxy "";
{{- $default_http_exists := false }}
{{- $default_https_exists := false }}
{{- range $vhost := $globals.vhosts }}
{{- $http := or (ne $vhost.https_method "nohttp") (not $vhost.cert_ok) }}
{{- $http := ne $vhost.https_method "nohttp" }}
{{- $https := ne $vhost.https_method "nohttps" }}
{{- $http_exists = or $http_exists $http }}
{{- $https_exists = or $https_exists $https }}
@ -493,7 +493,7 @@ server {
{{- /* Get the VIRTUAL_ROOT By containers w/ use fastcgi root */}}
{{- $vhost_root := or (first (groupByKeys $containers "Env.VIRTUAL_ROOT")) "/var/www/public" }}
{{- if and $cert_ok (eq $https_method "redirect") }}
{{- if eq $https_method "redirect" }}
server {
server_name {{ $host }};
{{- if $server_tokens }}
@ -531,7 +531,7 @@ server {
server_tokens {{ $server_tokens }};
{{- end }}
{{ $globals.access_log }}
{{- if or (eq $https_method "nohttps") (not $cert_ok) (eq $https_method "noredirect") }}
{{- if or (eq $https_method "nohttps") (eq $https_method "noredirect") }}
listen {{ $globals.external_http_port }} {{ $default_server }};
{{- if $globals.enable_ipv6 }}
listen [::]:{{ $globals.external_http_port }} {{ $default_server }};

View File

@ -12,6 +12,8 @@ services:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps
webA:
networks:

View File

@ -21,3 +21,4 @@ sut:
- /var/run/docker.sock:/f00.sock:ro
environment:
DOCKER_HOST: unix:///f00.sock
HTTPS_METHOD: nohttps

View File

@ -4,6 +4,8 @@ services:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps
web:
image: web

View File

@ -4,6 +4,8 @@ nginx-proxy:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./my_custom_proxy_settings.conf:/etc/nginx/vhost.d/default_location:ro
- ./my_custom_proxy_settings_bar.conf:/etc/nginx/vhost.d/web3.nginx-proxy.local_location:ro
environment:
HTTPS_METHOD: nohttps
web1:
image: web

View File

@ -5,6 +5,8 @@ services:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./my_custom_proxy_settings.conf:/etc/nginx/proxy.conf:ro
environment:
HTTPS_METHOD: nohttps
web1:
image: web

View File

@ -5,6 +5,8 @@ services:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./my_custom_proxy_settings.conf:/etc/nginx/vhost.d/web1.nginx-proxy.local_location:ro
environment:
HTTPS_METHOD: nohttps
web1:
image: web

View File

@ -5,6 +5,8 @@ services:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./my_custom_proxy_settings.conf:/etc/nginx/vhost.d/web1.nginx-proxy.local:ro
environment:
HTTPS_METHOD: nohttps
web1:
image: web

View File

@ -5,6 +5,8 @@ services:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./my_custom_proxy_settings.conf:/etc/nginx/conf.d/my_custom_proxy_settings.conf:ro
environment:
HTTPS_METHOD: nohttps
web1:
image: web

View File

@ -15,3 +15,4 @@ sut:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
DEFAULT_HOST: web1.tld
HTTPS_METHOD: nohttps

View File

@ -5,6 +5,7 @@ services:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
DEFAULT_ROOT: none
HTTPS_METHOD: nohttps
web:
image: web
expose:

View File

@ -15,6 +15,8 @@ services:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ../../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
environment:
HTTPS_METHOD: nohttps
web:
image: web

View File

@ -13,6 +13,8 @@ services:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ../../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl
- nginx_conf:/etc/nginx/conf.d
environment:
HTTPS_METHOD: nohttps
web:
image: web

View File

@ -2,3 +2,5 @@ nginxproxy:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -44,7 +44,7 @@ CONNECTION_REFUSED_RE = re.compile("Connection refused")
("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", "http://missing-cert.nginx-proxy.test/", 301, 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),
@ -55,7 +55,7 @@ CONNECTION_REFUSED_RE = re.compile("Connection refused")
("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", "http://missing-cert.nginx-proxy.test/", 301, 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),
@ -69,15 +69,13 @@ CONNECTION_REFUSED_RE = re.compile("Connection refused")
("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),
# Same as nohttp.yml, except there is a vhost with a missing cert. The missing cert should not
# cause that vhost to downgrade from https to http.
("nohttp-with-missing-cert.yml", "http://https-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
("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", "http://missing-cert.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
("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", "http://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
("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),

View File

@ -20,3 +20,5 @@ sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -11,4 +11,5 @@ sut:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTP_PORT: 8080
HTTP_PORT: 8080
HTTPS_METHOD: nohttps

View File

@ -20,4 +20,5 @@ sut:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./network_internal.conf:/etc/nginx/network_internal.conf:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -24,4 +24,5 @@ sut:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./network_internal.conf:/etc/nginx/network_internal.conf:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -35,5 +35,6 @@ services:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
ENABLE_IPV6: "true"
HTTPS_METHOD: nohttps
networks:
- net1

View File

@ -4,6 +4,8 @@ services:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./test_location-override.vhost.d:/etc/nginx/vhost.d:ro
environment:
HTTPS_METHOD: nohttps
explicit-root:
image: web

View File

@ -12,4 +12,5 @@ sut:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps
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

@ -11,3 +11,5 @@ sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -16,6 +16,8 @@ services:
- net2
- net3a
- net3b
environment:
HTTPS_METHOD: nohttps
web1:
image: web

View File

@ -12,3 +12,5 @@ sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -12,3 +12,5 @@ sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -11,3 +11,5 @@ sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -11,3 +11,5 @@ sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -35,3 +35,5 @@ services:
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:
- net1
environment:
HTTPS_METHOD: nohttps

View File

@ -39,6 +39,7 @@ services:
image: nginxproxy/nginx-proxy:test
environment:
ENABLE_IPV6: "true"
HTTPS_METHOD: nohttps
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:

View File

@ -27,3 +27,5 @@ sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -10,3 +10,5 @@ sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -11,3 +11,5 @@ sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -13,3 +13,5 @@ services:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -14,4 +14,5 @@ services:
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps
SHA1_UPSTREAM_NAME: "true"

View File

@ -3,6 +3,8 @@ services:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps
web1:
image: web
expose:

View File

@ -12,6 +12,8 @@ services:
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:
- net1
environment:
HTTPS_METHOD: nohttps
web:
image: web

View File

@ -40,6 +40,7 @@ sut:
image: nginxproxy/nginx-proxy:test
environment:
DEFAULT_ROOT: 418
HTTPS_METHOD: nohttps
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./foo.conf:/etc/nginx/vhost.d/foo.nginx-proxy.test:ro

View File

@ -12,6 +12,6 @@ sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./certs:/etc/nginx/certs:ro
environment:
- DEFAULT_ROOT=301 http://$$host/web1$$request_uri
DEFAULT_ROOT: 301 http://$$host/web1$$request_uri
HTTPS_METHOD: nohttps

View File

@ -35,3 +35,5 @@ sut:
- ./default.conf:/etc/nginx/vhost.d/default_location:ro
- ./host.conf:/etc/nginx/vhost.d/bar.nginx-proxy.test_location:ro
- ./path.conf:/etc/nginx/vhost.d/bar.nginx-proxy.test_99f2db0ed8aa95dbb5b87fca79c7eff2ff6bb8bd_location:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -40,3 +40,5 @@ sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps

View File

@ -35,3 +35,5 @@ sut:
image: nginxproxy/nginx-proxy:test
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
HTTPS_METHOD: nohttps