Sfoglia il codice sorgente

Merge pull request #2452 from pini-gh/pini-enforce-HTTPS_METHOD

fix: enforce HTTPS_METHOD on missing cert as well
Nicolas Duchon 1 anno fa
parent
commit
50608d7826

+ 1 - 0
docs/README.md

@@ -582,6 +582,7 @@ If no matching certificate is found for a given virtual host, nginx-proxy will:
 
 - configure nginx to use the default certificate (`default.crt` with `default.key`) and return a 500 error for HTTPS,
 - force enable HTTP; i.e. `HTTPS_METHOD` will switch to `noredirect` if it was set to `nohttp` or `redirect`.
+  If this switch to HTTP is not wanted set `ENABLE_HTTP_ON_MISSING_CERT=false` (default is `true`).
 
 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:
 

+ 2 - 1
nginx.tmpl

@@ -590,8 +590,9 @@ proxy_set_header Proxy "";
 
     {{- $default := eq $globals.Env.DEFAULT_HOST $hostname }}
     {{- $https_method := or (first (groupByKeys $vhost_containers "Env.HTTPS_METHOD")) $globals.Env.HTTPS_METHOD "redirect" }}
+    {{- $enable_http_on_missing_cert := parseBool (or (first (groupByKeys $vhost_containers "Env.ENABLE_HTTP_ON_MISSING_CERT")) $globals.Env.ENABLE_HTTP_ON_MISSING_CERT "true") }}
     {{- /* When the certificate is missing we want to ensure that HTTP is enabled; hence switching from 'nohttp' or 'redirect' to 'noredirect' */}}
-    {{- if (and (not $cert_ok) (or (eq $https_method "nohttp") (eq $https_method "redirect"))) }}
+    {{- if (and $enable_http_on_missing_cert (not $cert_ok) (or (eq $https_method "nohttp") (eq $https_method "redirect"))) }}
         {{- $https_method = "noredirect" }}
     {{- end }}
     {{- $http2_enabled := parseBool (or (first (keys (groupByLabel $vhost_containers "com.github.nginx-proxy.nginx-proxy.http2.enable"))) $globals.Env.ENABLE_HTTP2 "true")}}

+ 18 - 0
test/test_enable_http_on_missing_cert.py

@@ -0,0 +1,18 @@
+import pytest
+
+
+def test_nohttp_missing_cert_disabled(docker_compose, nginxproxy):
+    r = nginxproxy.get("http://nohttp-missing-cert-disabled.nginx-proxy.tld/", allow_redirects=False)
+    assert r.status_code == 503
+
+def test_nohttp_missing_cert_enabled(docker_compose, nginxproxy):
+    r = nginxproxy.get("http://nohttp-missing-cert-enabled.nginx-proxy.tld/", allow_redirects=False)
+    assert r.status_code == 200
+
+def test_redirect_missing_cert_disabled(docker_compose, nginxproxy):
+    r = nginxproxy.get("http://redirect-missing-cert-disabled.nginx-proxy.tld/", allow_redirects=False)
+    assert r.status_code == 301
+
+def test_redirect_missing_cert_enabled(docker_compose, nginxproxy):
+    r = nginxproxy.get("http://redirect-missing-cert-enabled.nginx-proxy.tld/", allow_redirects=False)
+    assert r.status_code == 200

+ 46 - 0
test/test_enable_http_on_missing_cert.yml

@@ -0,0 +1,46 @@
+version: "2"
+
+services:
+  sut:
+    image: nginxproxy/nginx-proxy:test
+    volumes:
+      - /var/run/docker.sock:/tmp/docker.sock:ro
+      - ./withdefault.certs:/etc/nginx/certs:ro
+    environment:
+      ENABLE_HTTP_ON_MISSING_CERT: "false"
+
+  nohttp-missing-cert-disabled:
+    image: web
+    expose:
+      - "81"
+    environment:
+      WEB_PORTS: "81"
+      VIRTUAL_HOST: nohttp-missing-cert-disabled.nginx-proxy.tld
+      HTTPS_METHOD: nohttp
+
+  nohttp-missing-cert-enabled:
+    image: web
+    expose:
+      - "82"
+    environment:
+      WEB_PORTS: "82"
+      VIRTUAL_HOST: nohttp-missing-cert-enabled.nginx-proxy.tld
+      HTTPS_METHOD: nohttp
+      ENABLE_HTTP_ON_MISSING_CERT: "true"
+
+  redirect-missing-cert-disabled:
+    image: web
+    expose:
+      - "83"
+    environment:
+      WEB_PORTS: "83"
+      VIRTUAL_HOST: redirect-missing-cert-disabled.nginx-proxy.tld
+
+  redirect-missing-cert-enabled:
+    image: web
+    expose:
+      - "84"
+    environment:
+      WEB_PORTS: "84"
+      VIRTUAL_HOST: redirect-missing-cert-enabled.nginx-proxy.tld
+      ENABLE_HTTP_ON_MISSING_CERT: "true"