Improve acme-challenge handling
So that there is no need anymore for the Let's Encrypt companion to fiddle with vhosts nginx configuration. When `HTTPS_METHOD=nohttp` and the certificate is missing, enforce nohttp instead of switching to `HTTPS_METHOD=redirect`.
This commit is contained in:
parent
db07d90ad8
commit
33a06f987d
3 changed files with 22 additions and 14 deletions
16
nginx.tmpl
16
nginx.tmpl
|
@ -642,7 +642,7 @@ proxy_set_header Proxy "";
|
||||||
{{- $default_https_exists := false }}
|
{{- $default_https_exists := false }}
|
||||||
{{- $http3_enabled := false }}
|
{{- $http3_enabled := false }}
|
||||||
{{- range $vhost := $globals.vhosts }}
|
{{- 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" }}
|
{{- $https := ne $vhost.https_method "nohttps" }}
|
||||||
{{- $http_exists = or $http_exists $http }}
|
{{- $http_exists = or $http_exists $http }}
|
||||||
{{- $https_exists = or $https_exists $https }}
|
{{- $https_exists = or $https_exists $https }}
|
||||||
|
@ -716,7 +716,7 @@ server {
|
||||||
{{ template "upstream" (dict "globals" $globals "Path" $path "VPath" $vpath) }}
|
{{ template "upstream" (dict "globals" $globals "Path" $path "VPath" $vpath) }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
{{- if and $vhost.cert_ok (eq $vhost.https_method "redirect") }}
|
{{- if and (or $vhost.cert_ok $globals.default_cert_ok) (eq $vhost.https_method "redirect") }}
|
||||||
server {
|
server {
|
||||||
server_name {{ $hostname }};
|
server_name {{ $hostname }};
|
||||||
{{- if $vhost.server_tokens }}
|
{{- if $vhost.server_tokens }}
|
||||||
|
@ -757,11 +757,21 @@ server {
|
||||||
{{- if $vhost.http2_enabled }}
|
{{- if $vhost.http2_enabled }}
|
||||||
http2 on;
|
http2 on;
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if or (eq $vhost.https_method "nohttps") (not $vhost.cert_ok) (eq $vhost.https_method "noredirect") }}
|
{{- if or (eq $vhost.https_method "nohttps") (and (not $vhost.cert_ok) (not $globals.default_cert_ok)) (eq $vhost.https_method "noredirect") }}
|
||||||
listen {{ $globals.external_http_port }} {{ $default_server }};
|
listen {{ $globals.external_http_port }} {{ $default_server }};
|
||||||
{{- if $globals.enable_ipv6 }}
|
{{- if $globals.enable_ipv6 }}
|
||||||
listen [::]:{{ $globals.external_http_port }} {{ $default_server }};
|
listen [::]:{{ $globals.external_http_port }} {{ $default_server }};
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if (eq $vhost.https_method "noredirect") }}
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
auth_basic off;
|
||||||
|
allow all;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
try_files $uri =404;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if ne $vhost.https_method "nohttps" }}
|
{{- if ne $vhost.https_method "nohttps" }}
|
||||||
listen {{ $globals.external_https_port }} ssl {{ $default_server }};
|
listen {{ $globals.external_https_port }} ssl {{ $default_server }};
|
||||||
|
|
|
@ -44,7 +44,7 @@ CONNECTION_REFUSED_RE = re.compile("Connection refused")
|
||||||
("withdefault.yml", "https://https-only.nginx-proxy.test/", 200, None),
|
("withdefault.yml", "https://https-only.nginx-proxy.test/", 200, None),
|
||||||
("withdefault.yml", "http://http-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", "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", "https://missing-cert.nginx-proxy.test/", 500, None),
|
||||||
("withdefault.yml", "http://unknown.nginx-proxy.test/", 503, None),
|
("withdefault.yml", "http://unknown.nginx-proxy.test/", 503, None),
|
||||||
("withdefault.yml", "https://unknown.nginx-proxy.test/", 503, None),
|
("withdefault.yml", "https://unknown.nginx-proxy.test/", 503, None),
|
||||||
|
@ -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", "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", "http://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
|
||||||
("nohttp-on-app.yml", "https://unknown.nginx-proxy.test/", 503, None),
|
("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
|
# Same as nohttp.yml, except there is a vhost with a missing cert.
|
||||||
# HTTPS_METHOD=nohttp setting to effectively become HTTPS_METHOD=noredirect. This means that
|
# nohttp should be enforced in this case as well.
|
||||||
# there will be a plain http server solely to support that vhost, so http requests to other
|
("nohttp-with-missing-cert.yml", "http://https-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE),
|
||||||
# vhosts get a 503, not a connection refused error.
|
|
||||||
("nohttp-with-missing-cert.yml", "http://https-only.nginx-proxy.test/", 503, None),
|
|
||||||
("nohttp-with-missing-cert.yml", "https://https-only.nginx-proxy.test/", 200, None),
|
("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", "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),
|
("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.
|
# HTTPS_METHOD=nohttps on nginx-proxy, HTTPS_METHOD unset on the app container.
|
||||||
("nohttps.yml", "http://http-only.nginx-proxy.test/", 200, None),
|
("nohttps.yml", "http://http-only.nginx-proxy.test/", 200, None),
|
||||||
|
|
|
@ -19,9 +19,9 @@ def test_web2_HSTS_policy_is_inactive(docker_compose, nginxproxy):
|
||||||
assert "Strict-Transport-Security" not in r.headers
|
assert "Strict-Transport-Security" not in r.headers
|
||||||
|
|
||||||
|
|
||||||
def test_web3_acme_challenge_does_not_work(docker_compose, nginxproxy, acme_challenge_path):
|
def test_web3_acme_challenge_does_work(docker_compose, nginxproxy, acme_challenge_path):
|
||||||
r = nginxproxy.get(
|
r = nginxproxy.get(
|
||||||
f"http://web3.nginx-proxy.tld/{acme_challenge_path}",
|
f"http://web3.nginx-proxy.tld/{acme_challenge_path}",
|
||||||
allow_redirects=False
|
allow_redirects=False
|
||||||
)
|
)
|
||||||
assert r.status_code == 404
|
assert r.status_code == 200
|
||||||
|
|
Loading…
Reference in a new issue