From 7a2b1f8833d33fa99d20c34e104e4041f857422d Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Wed, 1 Feb 2023 18:17:43 -0500 Subject: [PATCH 1/5] chore: Split `$is_https` variable into two separate checks for improved readability. --- nginx.tmpl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 98ab38e..5e26ce3 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -444,10 +444,9 @@ server { * match. */}} {{- $cert := (coalesce $certName $vhostCert) }} + {{- $cert_ok := and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert)) }} - {{- $is_https := (and (ne $https_method "nohttps") (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert))) }} - - {{- if and $is_https (eq $https_method "redirect") }} + {{- if and $cert_ok (eq $https_method "redirect") }} server { server_name {{ $host }}; {{- if $server_tokens }} @@ -485,13 +484,13 @@ server { server_tokens {{ $server_tokens }}; {{- end }} {{ $globals.access_log }} - {{- if or (not $is_https) (eq $https_method "noredirect") }} + {{- if or (eq $https_method "nohttps") (not $cert_ok) (eq $https_method "noredirect") }} listen {{ $globals.external_http_port }} {{ $default_server }}; {{- if $globals.enable_ipv6 }} listen [::]:{{ $globals.external_http_port }} {{ $default_server }}; {{- end }} {{- end }} - {{- if $is_https }} + {{- if and (ne $https_method "nohttps") $cert_ok }} listen {{ $globals.external_https_port }} ssl http2 {{ $default_server }}; {{- if $globals.enable_ipv6 }} listen [::]:{{ $globals.external_https_port }} ssl http2 {{ $default_server }}; @@ -559,7 +558,7 @@ server { {{- end }} } - {{- if (and (not $is_https) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} + {{- if and (or (eq $https_method "nohttps") (not $cert_ok)) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key") }} server { server_name {{ $host }}; {{- if $server_tokens }} From 18d0671312fa81245b3bbbe35495c61760b7c46a Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Wed, 1 Feb 2023 18:56:16 -0500 Subject: [PATCH 2/5] chore: Factor out duplicate checks for `default.crt` for improved readability. --- nginx.tmpl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 5e26ce3..bc7e12b 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -11,6 +11,7 @@ {{- $_ := set $globals "Env" $.Env }} {{- $_ := set $globals "Docker" $.Docker }} {{- $_ := set $globals "CurrentContainer" (where $globals.containers "ID" $globals.Docker.CurrentContainerID | first) }} +{{- $_ := set $globals "default_cert_ok" (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} {{- $_ := set $globals "external_http_port" (coalesce $globals.Env.HTTP_PORT "80") }} {{- $_ := set $globals "external_https_port" (coalesce $globals.Env.HTTPS_PORT "443") }} {{- $_ := set $globals "sha1_upstream_name" (parseBool (coalesce $globals.Env.SHA1_UPSTREAM_NAME "false")) }} @@ -355,7 +356,7 @@ server { {{ $globals.access_log }} return 503; -{{- if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} +{{- if $globals.default_cert_ok }} listen {{ $globals.external_https_port }} ssl http2; {{- if $globals.enable_ipv6 }} listen [::]:{{ $globals.external_https_port }} ssl http2; @@ -558,7 +559,7 @@ server { {{- end }} } - {{- if and (or (eq $https_method "nohttps") (not $cert_ok)) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key") }} + {{- if and (or (eq $https_method "nohttps") (not $cert_ok)) $globals.default_cert_ok }} server { server_name {{ $host }}; {{- if $server_tokens }} From 16066cab61aa10547f1b87c740ce2b34ec8fb0c0 Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Thu, 2 Feb 2023 17:17:00 -0500 Subject: [PATCH 3/5] fix: Don't create cert error https server if https is not enabled --- nginx.tmpl | 2 +- .../withdefault.certs/default.crt | 70 ++++++++++++++++++ .../withdefault.certs/default.key | 27 +++++++ .../http-only.nginx-proxy.test.crt | 71 +++++++++++++++++++ .../http-only.nginx-proxy.test.key | 27 +++++++ .../https-and-http.nginx-proxy.test.crt | 71 +++++++++++++++++++ .../https-and-http.nginx-proxy.test.key | 27 +++++++ .../https-only.nginx-proxy.test.crt | 71 +++++++++++++++++++ .../https-only.nginx-proxy.test.key | 27 +++++++ test/test_fallback.data/withdefault.yml | 36 ++++++++++ test/test_fallback.py | 53 ++++++++++++++ .../test_wildcard_cert_nohttps.py | 4 +- 12 files changed, 483 insertions(+), 3 deletions(-) create mode 100644 test/test_fallback.data/withdefault.certs/default.crt create mode 100644 test/test_fallback.data/withdefault.certs/default.key create mode 100644 test/test_fallback.data/withdefault.certs/http-only.nginx-proxy.test.crt create mode 100644 test/test_fallback.data/withdefault.certs/http-only.nginx-proxy.test.key create mode 100644 test/test_fallback.data/withdefault.certs/https-and-http.nginx-proxy.test.crt create mode 100644 test/test_fallback.data/withdefault.certs/https-and-http.nginx-proxy.test.key create mode 100644 test/test_fallback.data/withdefault.certs/https-only.nginx-proxy.test.crt create mode 100644 test/test_fallback.data/withdefault.certs/https-only.nginx-proxy.test.key create mode 100644 test/test_fallback.data/withdefault.yml create mode 100644 test/test_fallback.py diff --git a/nginx.tmpl b/nginx.tmpl index bc7e12b..c8b704d 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -559,7 +559,7 @@ server { {{- end }} } - {{- if and (or (eq $https_method "nohttps") (not $cert_ok)) $globals.default_cert_ok }} + {{- if and (ne $https_method "nohttps") (not $cert_ok) $globals.default_cert_ok }} server { server_name {{ $host }}; {{- if $server_tokens }} diff --git a/test/test_fallback.data/withdefault.certs/default.crt b/test/test_fallback.data/withdefault.certs/default.crt new file mode 100644 index 0000000..f855457 --- /dev/null +++ b/test/test_fallback.data/withdefault.certs/default.crt @@ -0,0 +1,70 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld + Validity + Not Before: Feb 9 04:02:23 2023 GMT + Not After : Jun 27 04:02:23 2050 GMT + Subject: CN=*.nginx-proxy.test + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:db:bd:54:de:01:7e:82:4e:c0:f1:5d:12:fd:3a: + fb:21:19:4d:44:25:47:ea:ad:d8:11:5c:d1:65:88: + af:49:fc:8e:4b:c3:01:c1:0d:6d:22:67:bd:31:66: + 9f:4a:50:17:9e:47:b3:3b:b3:21:73:1f:81:55:73: + 52:47:9b:fb:85:6b:e8:d8:09:cc:e1:7d:1c:14:03: + 1c:ae:84:b4:5b:e5:e5:c7:71:fc:1f:74:33:4f:ae: + f7:8d:21:1f:55:8d:93:c7:84:4d:93:01:a1:1c:37: + ae:85:5c:70:2c:21:ec:87:35:c3:86:d3:b3:0f:9a: + b0:9d:8a:cd:0e:49:e8:99:c5:4c:50:bd:a8:6e:a7: + 01:3e:a7:dc:cf:c3:48:37:8e:c6:8a:89:b0:41:01: + 58:ee:45:94:fa:90:eb:df:c8:0e:b7:dd:79:75:13: + 1e:07:69:ee:54:47:92:18:9d:e0:a9:ee:4e:22:d1: + f4:a2:4d:a1:47:ed:9b:35:2a:70:cc:66:fb:3e:f0: + 49:f7:ee:62:2a:27:a1:d3:52:7b:ff:e9:12:d9:5b: + 6b:f6:18:bf:9c:9d:5f:00:29:d2:54:b5:f8:a4:a2: + 9b:3f:fe:a6:ed:14:ae:a0:fe:13:33:18:33:17:a9: + 8b:fe:fc:75:65:0c:fb:c2:d1:1e:81:ca:43:89:bd: + 78:dd + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:*.nginx-proxy.test + Signature Algorithm: sha256WithRSAEncryption + 43:a7:1f:4b:ec:ff:1d:70:c7:f8:6e:eb:fd:15:25:27:b2:54: + c7:92:cf:ed:51:31:28:56:76:5c:da:8b:17:31:55:8c:a1:c2: + 37:95:27:7b:b6:58:e5:92:ef:1e:fe:35:f1:44:ca:c7:1b:7b: + 75:bf:e1:91:61:6d:8a:6f:35:8b:73:f4:d9:08:60:25:07:7a: + 3e:c2:79:e7:ae:b4:70:cc:8a:30:cb:80:aa:47:1a:40:82:00: + a0:5e:01:67:d1:95:21:3c:b1:52:7d:f5:87:b6:43:41:df:b2: + a7:ee:3b:73:17:c4:19:2c:6b:7b:3c:26:9e:4c:00:e3:e8:07: + f2:e1:a1:31:79:57:be:b6:b1:a7:93:70:4e:e1:7d:bf:08:c5: + e7:a0:de:7d:82:20:24:f7:b0:3f:c2:94:36:88:ef:7b:7d:c0: + 7f:8a:78:a1:8e:56:42:82:ce:82:e6:8e:3d:1b:b7:ca:dd:a9: + a8:e6:f9:a3:f4:4a:a4:a0:9c:15:6f:44:8c:48:20:e5:85:ed: + 6f:85:22:41:1d:1f:fe:58:e5:43:ad:f2:c4:10:5a:10:ed:36: + 10:98:ad:73:97:6a:e0:19:18:d6:32:26:03:3d:dd:84:5c:2e: + 97:ca:a2:f5:63:f2:7a:16:f1:55:ca:d2:a1:54:09:8a:bb:23: + f0:53:36:51 +-----BEGIN CERTIFICATE----- +MIIC+zCCAeOgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp +bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs +ZDAgFw0yMzAyMDkwNDAyMjNaGA8yMDUwMDYyNzA0MDIyM1owHTEbMBkGA1UEAwwS +Ki5uZ2lueC1wcm94eS50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA271U3gF+gk7A8V0S/Tr7IRlNRCVH6q3YEVzRZYivSfyOS8MBwQ1tIme9MWaf +SlAXnkezO7Mhcx+BVXNSR5v7hWvo2AnM4X0cFAMcroS0W+Xlx3H8H3QzT673jSEf +VY2Tx4RNkwGhHDeuhVxwLCHshzXDhtOzD5qwnYrNDknomcVMUL2obqcBPqfcz8NI +N47GiomwQQFY7kWU+pDr38gOt915dRMeB2nuVEeSGJ3gqe5OItH0ok2hR+2bNSpw +zGb7PvBJ9+5iKieh01J7/+kS2Vtr9hi/nJ1fACnSVLX4pKKbP/6m7RSuoP4TMxgz +F6mL/vx1ZQz7wtEegcpDib143QIDAQABoyEwHzAdBgNVHREEFjAUghIqLm5naW54 +LXByb3h5LnRlc3QwDQYJKoZIhvcNAQELBQADggEBAEOnH0vs/x1wx/hu6/0VJSey +VMeSz+1RMShWdlzaixcxVYyhwjeVJ3u2WOWS7x7+NfFEyscbe3W/4ZFhbYpvNYtz +9NkIYCUHej7CeeeutHDMijDLgKpHGkCCAKBeAWfRlSE8sVJ99Ye2Q0HfsqfuO3MX +xBksa3s8Jp5MAOPoB/LhoTF5V762saeTcE7hfb8Ixeeg3n2CICT3sD/ClDaI73t9 +wH+KeKGOVkKCzoLmjj0bt8rdqajm+aP0SqSgnBVvRIxIIOWF7W+FIkEdH/5Y5UOt +8sQQWhDtNhCYrXOXauAZGNYyJgM93YRcLpfKovVj8noW8VXK0qFUCYq7I/BTNlE= +-----END CERTIFICATE----- diff --git a/test/test_fallback.data/withdefault.certs/default.key b/test/test_fallback.data/withdefault.certs/default.key new file mode 100644 index 0000000..79ccb0b --- /dev/null +++ b/test/test_fallback.data/withdefault.certs/default.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA271U3gF+gk7A8V0S/Tr7IRlNRCVH6q3YEVzRZYivSfyOS8MB +wQ1tIme9MWafSlAXnkezO7Mhcx+BVXNSR5v7hWvo2AnM4X0cFAMcroS0W+Xlx3H8 +H3QzT673jSEfVY2Tx4RNkwGhHDeuhVxwLCHshzXDhtOzD5qwnYrNDknomcVMUL2o +bqcBPqfcz8NIN47GiomwQQFY7kWU+pDr38gOt915dRMeB2nuVEeSGJ3gqe5OItH0 +ok2hR+2bNSpwzGb7PvBJ9+5iKieh01J7/+kS2Vtr9hi/nJ1fACnSVLX4pKKbP/6m +7RSuoP4TMxgzF6mL/vx1ZQz7wtEegcpDib143QIDAQABAoIBAGUd9QXMTjkMoIDx +QaHCGHocuI+ZUETQBtPGkJ1WjsNPMvPuIsqBsSzZ7Bflj3uU66lseTAJuGTPpKZ7 +0Ose/llhVN7Fc8B34AndfL9aVdzMKDblXw3iXRJYA5awHUkzQ0PWwBPb9hWUEf1Q +klXcrolx1i4fEREnMArvKnlezWikpXcqDYRcmUfEvVozaq75heavHpOcOq2dg7vo +N/gcJmfG4aDOhrZC1f22u5cNePvbVj+DdXOUHMEEfXOFbxk97VhmcIaH75ugvVh4 +EMMg87mcGLZiqPO5k6SYcuGyquc32Tf5sK80mpt/+SAEHCvSmUt9c1ynQrS9IhNp +OGfZhQkCgYEA+LonwScVGVEgHg1A9E7BKhIrgUOlwWNM43s+o8Uuz1T72VUVZ6N/ +aO0+2Panw1qjsb0CUC2zft3zZTiZd81gWRmBYQ0R9dHWyWHbJlOv8rAmJ+60Gr2a +UVTLHEdZKx6svSDNhL0HfxxfWwePgHB4NVa2RUA3KQ5y5C96EXb8WbsCgYEA4iow +nIIbRZ9ILDz1oThxE+dFifKWXWFOwa58EFBY+/y34itL7kXRu2+4ZIltwL0L8m5j +GUALUabuoOASKg4CFBhCvoAAlWZRr6L6EOecrElUnrefUrKuCWPCVo3MnCMuLXDp +p1mEGIwEZBCY+jrSBMrRCawsMRkcymLJhEBFYkcCgYB6xIey0vObF2ve6XPSIr09 +YtKObzF1jun4rnBwrXc5Zx0YXOK/0PemdtO6i6SqzCZYKI7nvGcIi80DfThi5cBU +uj4eBTGEQBrgM6jT9iK2izOKKkxDlqqA0nWec6kTm4Rvpa1Lg3Ibz4lRiR3Pq7Pp +v+8fp16SqUsUTkrWLADK2QKBgCRIhHf3X4yx2xBNz1JIDcwVpFBXPMxKWio0Ze7w +FPaIOq/sJkhZpyYc7EYkzhjHu2zvTLK2VZqJ32qrx/47NRYoNjz9qBpPyfcVfGzN +25LASPUVnFfWFpmnCXx9T0AVXMkpfjK857ZQcDvldcVfPmZKa3LTzlsqHjZR1uaC +sR7tAoGBANBfInPZVZRJfqqkPN1K8j4P7uCGjTIBmys/vxoilh1d0scTgZrdqt92 +EKi/3UsJW2ndqQNDLbvi5kcW8a6UU3UB1LLvpyQ5zuS81x3+kKfv+5cDM8rt/M4A +MXnJA5eDZZ4SlHFzdblUv/MZdT+1x0tivMn3zFKNNj2SmaSGkQ0m +-----END RSA PRIVATE KEY----- diff --git a/test/test_fallback.data/withdefault.certs/http-only.nginx-proxy.test.crt b/test/test_fallback.data/withdefault.certs/http-only.nginx-proxy.test.crt new file mode 100644 index 0000000..33fa2f7 --- /dev/null +++ b/test/test_fallback.data/withdefault.certs/http-only.nginx-proxy.test.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld + Validity + Not Before: Feb 7 21:54:16 2023 GMT + Not After : Jun 25 21:54:16 2050 GMT + Subject: CN=http-only.nginx-proxy.test + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:b4:62:61:07:54:2e:6d:55:83:2d:24:b7:e2:15: + 34:13:bd:79:21:e9:10:75:3f:4c:f8:ba:60:29:87: + e5:8e:2a:1e:fd:33:51:5a:8a:3a:6f:60:ff:24:f1: + 1b:27:30:8c:ac:43:04:b7:79:cb:7a:ec:c6:08:a4: + a0:15:b0:0f:ee:6b:15:84:24:11:bc:85:2b:48:06: + 04:0a:58:bb:8c:e8:4d:48:f5:06:c5:91:fe:5d:99: + 0a:29:31:8a:f1:9b:0c:e0:39:75:a1:06:9b:d4:f5: + 06:74:8f:46:5e:64:ba:2f:d0:3d:7c:3d:30:03:e9: + 7c:35:17:69:04:f6:2e:29:d4:93:d6:d6:d2:6c:04: + 38:06:21:06:05:30:8a:b9:9d:05:8d:12:6e:48:39: + bb:f6:93:4f:ba:a5:84:c7:96:2f:be:92:25:e9:d0: + 95:2a:d9:23:8a:b3:28:0b:b6:19:1c:3b:be:a2:91: + 70:44:a8:77:18:94:4b:df:61:f4:5c:c9:78:76:34: + b5:87:0f:c0:92:04:26:b6:ca:62:cd:9b:5d:eb:bf: + 10:ac:df:af:72:5f:af:09:38:b1:dc:e1:3d:13:db: + a0:ac:b7:2e:ca:39:5c:4c:f1:1e:81:a8:b4:44:a2: + 72:d5:3b:c0:71:cc:dc:16:0d:fa:38:96:44:b3:00: + d6:65 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:http-only.nginx-proxy.test + Signature Algorithm: sha256WithRSAEncryption + 3b:54:95:48:4d:f6:93:38:42:40:02:ab:b7:17:3b:50:3b:ca: + c7:12:69:b0:da:cb:d7:3e:0e:1f:bf:a2:59:c7:fe:c2:5c:43: + 84:92:b9:3a:be:8f:7e:2e:81:3c:ed:f3:a9:77:21:c2:35:f1: + da:cf:3a:1e:e2:ee:a2:ce:72:55:97:87:0e:ad:59:61:f7:75: + 46:c0:2b:d4:88:b7:36:97:11:fb:5e:28:89:e9:2a:92:f1:15: + f1:43:8e:c1:38:85:8d:3a:26:7d:25:72:93:17:96:8d:5a:ed: + e8:73:3a:d5:8d:80:f2:af:38:84:ff:85:2e:d1:36:7d:2e:e1: + f0:2c:d8:15:5f:fc:c5:70:5d:25:6a:22:f3:2a:cd:0f:25:ad: + d4:93:d3:9a:3e:50:bc:da:a5:6c:86:ea:1d:d9:b9:c5:90:db: + f5:02:c8:c9:77:5c:ef:77:fe:74:60:41:33:d9:3c:a2:e1:73: + aa:14:18:5d:36:58:c8:41:63:4c:59:0e:4b:3d:c5:65:5a:01: + b0:16:50:0f:d0:4f:0d:ca:97:f6:11:47:06:6b:b1:ae:bb:26: + 30:34:8b:7a:91:5d:8a:22:c7:f9:05:0d:bb:a5:b7:60:c0:20: + ce:d0:0e:c0:66:b3:e7:c4:61:ec:c5:40:e6:52:11:41:c3:11: + 18:04:c7:1e +-----BEGIN CERTIFICATE----- +MIIDCzCCAfOgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp +bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs +ZDAgFw0yMzAyMDcyMTU0MTZaGA8yMDUwMDYyNTIxNTQxNlowJTEjMCEGA1UEAwwa +aHR0cC1vbmx5Lm5naW54LXByb3h5LnRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC0YmEHVC5tVYMtJLfiFTQTvXkh6RB1P0z4umAph+WOKh79M1Fa +ijpvYP8k8RsnMIysQwS3ect67MYIpKAVsA/uaxWEJBG8hStIBgQKWLuM6E1I9QbF +kf5dmQopMYrxmwzgOXWhBpvU9QZ0j0ZeZLov0D18PTAD6Xw1F2kE9i4p1JPW1tJs +BDgGIQYFMIq5nQWNEm5IObv2k0+6pYTHli++kiXp0JUq2SOKsygLthkcO76ikXBE +qHcYlEvfYfRcyXh2NLWHD8CSBCa2ymLNm13rvxCs369yX68JOLHc4T0T26Csty7K +OVxM8R6BqLREonLVO8BxzNwWDfo4lkSzANZlAgMBAAGjKTAnMCUGA1UdEQQeMByC +Gmh0dHAtb25seS5uZ2lueC1wcm94eS50ZXN0MA0GCSqGSIb3DQEBCwUAA4IBAQA7 +VJVITfaTOEJAAqu3FztQO8rHEmmw2svXPg4fv6JZx/7CXEOEkrk6vo9+LoE87fOp +dyHCNfHazzoe4u6iznJVl4cOrVlh93VGwCvUiLc2lxH7XiiJ6SqS8RXxQ47BOIWN +OiZ9JXKTF5aNWu3oczrVjYDyrziE/4Uu0TZ9LuHwLNgVX/zFcF0laiLzKs0PJa3U +k9OaPlC82qVshuod2bnFkNv1AsjJd1zvd/50YEEz2Tyi4XOqFBhdNljIQWNMWQ5L +PcVlWgGwFlAP0E8Nypf2EUcGa7GuuyYwNIt6kV2KIsf5BQ27pbdgwCDO0A7AZrPn +xGHsxUDmUhFBwxEYBMce +-----END CERTIFICATE----- diff --git a/test/test_fallback.data/withdefault.certs/http-only.nginx-proxy.test.key b/test/test_fallback.data/withdefault.certs/http-only.nginx-proxy.test.key new file mode 100644 index 0000000..3834584 --- /dev/null +++ b/test/test_fallback.data/withdefault.certs/http-only.nginx-proxy.test.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAtGJhB1QubVWDLSS34hU0E715IekQdT9M+LpgKYfljioe/TNR +Woo6b2D/JPEbJzCMrEMEt3nLeuzGCKSgFbAP7msVhCQRvIUrSAYECli7jOhNSPUG +xZH+XZkKKTGK8ZsM4Dl1oQab1PUGdI9GXmS6L9A9fD0wA+l8NRdpBPYuKdST1tbS +bAQ4BiEGBTCKuZ0FjRJuSDm79pNPuqWEx5YvvpIl6dCVKtkjirMoC7YZHDu+opFw +RKh3GJRL32H0XMl4djS1hw/AkgQmtspizZtd678QrN+vcl+vCTix3OE9E9ugrLcu +yjlcTPEegai0RKJy1TvAcczcFg36OJZEswDWZQIDAQABAoIBAAfDA/HQyX6i41YZ +8l+kEe2XhZLT+IVTB/jb7C9dTZ9kaJj0kFeZAxKv1cq9JTH2gNcYuyc58muDrLHK +g6jrPoQ/z1k0RB8ci9Q5jgrz7n4NsOWmxXfS5GMaprlHDHeA+HjdgBZBtorfUDvL +vndpVimgiETETUCd115hd39jKHFcRcdV6yCix7ObywK3dMgLVpagCcnlyCWffS/r +nhhMfJ+VstW0nUtfZ7JEYwT6Cg7lLAVtDkqPX8zGjJiRwUKH808bUyqEw1y5Cc8U +U5hbmMgPWfXsKxsEC6FSVHBG9ZX2jymOMQXijLFcBSuWvADHmyU+ZxXcbtd1rv4E +cGFj3wECgYEA5cNrr5WjrpEin6MYYVWxiQ+xEWPU2R17eApagrDRLM41JJpv7a5m +TYuZRfIxb59CBPi718Gi168P3T2KMvo2/BTh9Lq5ZBYHx3aDqW2QvMFn7/tgamj8 +0DBxccd2QWfGIBrT1rAF7lD8TC86wtDDVKrvhucRSEXVKF/jWFFRGfUCgYEAyPt6 +48khr7sfNMVdkDLjQjZVV6H7ZUMoSn0FGybgKWxW+b0XCBPObUQWIpyCNTRr1+4A +1TAUS+F/OVVfwnLNgemeE2wd6CaduxwiK1U4pHbyXCElH1ifonHWV3MoXOefYsiY +q5z2jfJzUi0JZVUKsveu9rQsFLsc//1s/I5T1LECgYEAldY6fNg2VVp63OZsuNU8 +oSiljbSwEyMh6Oe/nOkYkIKtr4AzrCoGt11piG7ohGW0lS9suMijnMqiquI+JP5+ +KyinLoUy761aR17nf+9e62mpkZw6hUqQTGi7Irs0SHUXhMpaCfDi/Ua9MiW+yVuB +ds6+xBgeciZwWxMlXOwy2p0CgYEAm+YWiSK3Mq0fo7uEvBn9Fps2z+ciLoZNdppL +n6gkMX2MaeQ3PVi/wxoRYX+tsL+c973yf2vwEnw0R7Dlutt6dc9VgxNWj4GE0GMe +Tiao7Uom7Tf4p7wC9+r9rI/zOz2f8OxRIK18wtbShWfR5fx1dCWUXmGb3+jUse1O +4Qk2FcECgYAvSvGFoJb8tuHFEYYHBbjficmvTUsrTE+EhxPqWKFhKfF19fFFIupy +XBCrN6nwrh+/YMxZXeIRbbTTf814cOO7PjLeNhnfhJZkaJq1HzbYe3bOurna3qrm +Ra3xiM8Ld2PyGnZPXf8+AWhMhuPkLX1KFVTCAxwCpmTZCHtiGCmXMA== +-----END RSA PRIVATE KEY----- diff --git a/test/test_fallback.data/withdefault.certs/https-and-http.nginx-proxy.test.crt b/test/test_fallback.data/withdefault.certs/https-and-http.nginx-proxy.test.crt new file mode 100644 index 0000000..8b04cb9 --- /dev/null +++ b/test/test_fallback.data/withdefault.certs/https-and-http.nginx-proxy.test.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld + Validity + Not Before: Feb 7 21:53:19 2023 GMT + Not After : Jun 25 21:53:19 2050 GMT + Subject: CN=https-and-http.nginx-proxy.test + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:b7:97:85:d1:7f:6b:50:29:f3:87:b7:4e:f5:25: + 40:6a:d8:fa:a1:63:3c:4a:2e:68:4a:c6:8b:38:df: + 07:81:d0:08:9d:fc:17:f5:37:28:7f:31:e6:f3:81: + 28:4e:22:b6:bd:a2:4e:f2:2f:e5:0f:dd:55:3c:e1: + 04:84:4c:45:1b:1a:ae:b7:f0:2a:da:43:05:71:91: + 92:b8:d1:49:fe:80:0a:53:b9:66:da:54:60:9a:fc: + e1:b2:e8:28:48:7f:96:94:3c:92:a3:b2:37:f6:7a: + c2:de:0b:12:f0:ae:4e:92:fe:2d:c1:b2:95:28:1f: + 88:8d:79:99:81:19:ae:22:a4:95:f5:9f:db:25:8e: + 1d:cf:43:cd:6f:85:93:5f:79:ee:f8:f3:d4:82:e1: + e9:4d:c9:ad:ae:5b:92:43:3a:3c:71:51:70:f7:3e: + bd:1b:24:52:6a:a3:cf:54:72:57:ed:fe:72:ea:96: + 9b:5a:02:02:a7:df:85:b7:68:ae:1e:07:77:9f:59: + a5:a0:8b:28:c2:c8:b7:bb:8a:42:50:df:05:73:bf: + 9c:55:13:b5:82:79:77:40:57:a4:8f:88:a5:71:50: + d7:70:b0:4d:0c:d9:86:b3:9b:db:8a:20:bd:19:68: + 10:52:2d:53:ba:0e:2e:1c:ad:80:54:bb:b6:c9:ab: + 11:39 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:https-and-http.nginx-proxy.test + Signature Algorithm: sha256WithRSAEncryption + 2c:f3:e5:47:3f:8e:5a:28:b1:df:e5:95:50:85:6f:27:2f:a6: + 8d:f1:5e:cf:df:e2:52:66:97:61:36:59:81:26:25:19:99:c9: + 93:e5:85:cb:ca:69:af:4b:21:a3:d2:7a:bf:b5:5e:2d:42:fb: + 99:f8:22:58:e5:bf:79:b8:8a:74:7e:c6:94:14:d9:f2:27:63: + b6:e5:74:21:5b:59:fb:f6:c8:a9:28:fb:60:f7:5e:bd:c2:e6: + 74:24:14:96:61:95:6c:c2:66:b4:52:25:a1:85:5a:97:e5:68: + 5c:62:cf:69:3b:b0:a9:56:d8:e3:5f:74:dc:84:18:d5:3e:4f: + c9:35:39:26:88:dc:9b:80:d9:40:e1:4f:09:27:8d:d2:89:55: + 30:91:02:86:35:04:95:1e:1d:58:14:5b:c6:e0:2e:a7:bf:a8: + f6:2b:76:8a:4e:71:79:bc:c0:04:cd:db:81:73:46:ce:68:ed: + 25:b0:0e:42:8d:96:64:77:3b:f4:9d:1a:c9:f6:78:4c:56:4f: + 92:17:29:3d:80:50:71:77:4b:a8:29:c2:12:fc:ad:0a:37:81: + 38:4c:fb:54:99:4d:12:5f:98:dc:d1:a9:7b:08:45:c4:6f:7e: + fe:00:e0:db:79:fe:d1:28:e3:8e:82:d1:fb:bc:0a:c4:42:93: + c9:5e:eb:ba +-----BEGIN CERTIFICATE----- +MIIDFTCCAf2gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp +bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs +ZDAgFw0yMzAyMDcyMTUzMTlaGA8yMDUwMDYyNTIxNTMxOVowKjEoMCYGA1UEAwwf +aHR0cHMtYW5kLWh0dHAubmdpbngtcHJveHkudGVzdDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALeXhdF/a1Ap84e3TvUlQGrY+qFjPEouaErGizjfB4HQ +CJ38F/U3KH8x5vOBKE4itr2iTvIv5Q/dVTzhBIRMRRsarrfwKtpDBXGRkrjRSf6A +ClO5ZtpUYJr84bLoKEh/lpQ8kqOyN/Z6wt4LEvCuTpL+LcGylSgfiI15mYEZriKk +lfWf2yWOHc9DzW+Fk1957vjz1ILh6U3Jra5bkkM6PHFRcPc+vRskUmqjz1RyV+3+ +cuqWm1oCAqffhbdorh4Hd59ZpaCLKMLIt7uKQlDfBXO/nFUTtYJ5d0BXpI+IpXFQ +13CwTQzZhrOb24ogvRloEFItU7oOLhytgFS7tsmrETkCAwEAAaMuMCwwKgYDVR0R +BCMwIYIfaHR0cHMtYW5kLWh0dHAubmdpbngtcHJveHkudGVzdDANBgkqhkiG9w0B +AQsFAAOCAQEALPPlRz+OWiix3+WVUIVvJy+mjfFez9/iUmaXYTZZgSYlGZnJk+WF +y8ppr0sho9J6v7VeLUL7mfgiWOW/ebiKdH7GlBTZ8idjtuV0IVtZ+/bIqSj7YPde +vcLmdCQUlmGVbMJmtFIloYVal+VoXGLPaTuwqVbY41903IQY1T5PyTU5Jojcm4DZ +QOFPCSeN0olVMJEChjUElR4dWBRbxuAup7+o9it2ik5xebzABM3bgXNGzmjtJbAO +Qo2WZHc79J0ayfZ4TFZPkhcpPYBQcXdLqCnCEvytCjeBOEz7VJlNEl+Y3NGpewhF +xG9+/gDg23n+0SjjjoLR+7wKxEKTyV7rug== +-----END CERTIFICATE----- diff --git a/test/test_fallback.data/withdefault.certs/https-and-http.nginx-proxy.test.key b/test/test_fallback.data/withdefault.certs/https-and-http.nginx-proxy.test.key new file mode 100644 index 0000000..11f5210 --- /dev/null +++ b/test/test_fallback.data/withdefault.certs/https-and-http.nginx-proxy.test.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAt5eF0X9rUCnzh7dO9SVAatj6oWM8Si5oSsaLON8HgdAInfwX +9TcofzHm84EoTiK2vaJO8i/lD91VPOEEhExFGxqut/Aq2kMFcZGSuNFJ/oAKU7lm +2lRgmvzhsugoSH+WlDySo7I39nrC3gsS8K5Okv4twbKVKB+IjXmZgRmuIqSV9Z/b +JY4dz0PNb4WTX3nu+PPUguHpTcmtrluSQzo8cVFw9z69GyRSaqPPVHJX7f5y6pab +WgICp9+Ft2iuHgd3n1mloIsowsi3u4pCUN8Fc7+cVRO1gnl3QFekj4ilcVDXcLBN +DNmGs5vbiiC9GWgQUi1Tug4uHK2AVLu2yasROQIDAQABAoIBACT4KSVHoEdzOyvw +GME6sB8T9Fw9TG2vrKaqFmzsVGmqh6Gwmu5xHgGG/fe44XHigaPsJDOWu2yXaEur +ECrH5P6RP++gODDdYCI/ayk2U80g4XN8mR6L8Swkkhphr4Lx1lOhYvH9uFE05Tqr +RjQbFY16C6K+oFSFDQ1YGDYsAqnM3RD7PH+lHpo8UN1TO/vogdSQEpMYZDwLAYnW +uD5G3c0u2PsGu9YLuz2p8hcs3chh+cqKJWXOeW0JLrNGx1bqeQWkn6nXRDdRYi9V +cJlTgDqGuF54bieSyq9ABDZQP4Ol+moYKDoIz5PwurNjcYSklrT1tw0gqHZoQK1L +fDjw3QECgYEA7QMRU1AFKTvO7/8WLHLN5BT63n31wm0e9PYpz/XVLWEfxBcp9Xmf +xAIhXZ/U9P4dfNqxTjN9mVGzCHh5KfDJnUFqOXFy/zvfMeRzJf6dJo6/4OX9Bijr +Tgd454vyGXYQP2t+F14UAwl6vlGOAjttiP5qY5Ef1gllBEeIPe9Ts9kCgYEAxkzZ +pq4HJ/5/iDquMEHXNXzpNPavSvgxQdl1ILvJ49LJImmQFBCP9PqiOTIfePz1OqUI +C4baFuc0FEDJ3x9CUNmMY1lEi2ZUq2agPSXaQNsMcKtEJH8SoJlJIRpkQA7unX09 +zb4dam6g79OaGmb8scePuezXMLv1Ee6WWtXbzGECgYEA6PYn9Gzl9cacu9dOUzgw +2ewpPcIvawDY+cxwAsHO3MDneVWPX4JBoGa7pwvwRTL1hwBqYMRJwwbD5CKObcQI +V/KxV28Eqo2N77tt1z2x9/E99u/4yTI1P0gm9ejfeVlL1RpyIMPPBcEujZ0Z6WXC +X3I63k0KLtajHRa2erIf4tkCgYAfunAgwTuX5JqXO3xfcEl033WY6deGUUvgU2Dw +Sdu1viY8gVNyQmwmMGwAZsquWxsJtRoibgM7IucsTml+b8v2j7hstP3IqCjn+9Wr +swDG28WTyXNvu31JgP04dLaRoVIAlOdsofym6OiLNvozO0M3VsziXMjZnVlK8zfP +dORkQQKBgQDXAJEJPygxVA+bF104dzCMWGmU7K8ShEWC5eOdKK4KWf9bNDpY6M6c +i6zga/xBbj7e3Bxqprpp8Wy2gIsnYiVo4V9EQethbLdomPxOpBMNMARw81rL1CpO +jbHB7bIDcKs2tQoZEXUW86ZxC8sdaDaWTJTfUO0RpJow6ZO3yvxVIQ== +-----END RSA PRIVATE KEY----- diff --git a/test/test_fallback.data/withdefault.certs/https-only.nginx-proxy.test.crt b/test/test_fallback.data/withdefault.certs/https-only.nginx-proxy.test.crt new file mode 100644 index 0000000..a93e728 --- /dev/null +++ b/test/test_fallback.data/withdefault.certs/https-only.nginx-proxy.test.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld + Validity + Not Before: Feb 7 21:53:49 2023 GMT + Not After : Jun 25 21:53:49 2050 GMT + Subject: CN=https-only.nginx-proxy.test + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:d9:87:48:02:85:f4:5f:0d:90:7e:4c:4f:13:89: + 41:ca:41:15:c2:6f:fd:a8:c7:17:83:c6:dd:8c:fe: + 19:a4:b2:6b:0b:35:4f:b4:3d:7c:40:0a:04:33:2a: + fd:10:72:f7:63:63:99:5b:3d:ec:78:ee:c6:4d:c8: + 0e:4c:be:f2:3f:e3:02:74:57:9a:c1:fe:15:95:63: + 4e:e7:2c:eb:70:f2:6b:c8:ba:01:a2:ca:a1:c7:76: + ff:38:e4:c2:b0:66:fc:85:d2:af:0f:22:81:d4:82: + eb:d5:b0:e6:69:14:37:dd:8d:ad:29:ce:93:68:5a: + ce:f4:77:76:6f:78:13:b6:c8:2f:fe:e0:b6:7e:fb: + 29:16:be:e2:f5:45:3b:39:5b:52:dc:26:b7:ca:0c: + b6:1c:fc:a8:38:0b:dd:c1:f4:04:9b:2d:38:c9:a5: + 2d:3e:f1:42:88:53:a2:3b:17:cf:d5:3c:2b:d6:6a: + 7f:6f:05:8d:c5:b7:5d:64:1e:83:1b:e7:ec:80:3d: + 6d:34:c1:66:b2:e6:5d:d9:a7:6e:46:75:14:bf:10: + 16:c5:fc:47:8e:63:fa:e5:b4:bd:f2:b9:e0:cb:ea: + 75:f9:68:ee:7d:8f:ea:8f:1a:9f:34:27:7a:4a:9f: + 85:fd:3e:17:a7:96:c3:d0:4e:50:a2:a2:e0:45:92: + d0:b5 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:https-only.nginx-proxy.test + Signature Algorithm: sha256WithRSAEncryption + 8a:52:46:42:a9:74:18:6a:52:90:ef:a4:e9:c5:54:d5:97:3a: + ff:8b:c2:76:4f:9e:47:aa:e1:ea:e5:b9:af:9d:33:e3:85:17: + 54:7d:32:bd:ac:90:3f:5c:d2:a1:42:17:52:2b:b1:83:e5:c3: + bf:81:f0:e7:38:e2:88:67:7b:d8:59:fe:f9:94:99:ba:be:f4: + 3c:24:b2:c7:9e:f0:98:21:c6:2d:c2:e8:f3:67:bd:62:00:aa: + ce:34:fa:b4:53:6d:c1:09:5e:55:bd:43:aa:86:c6:f8:c5:83: + 46:3a:49:12:a2:ec:30:36:0c:99:44:74:09:9d:cc:4b:98:1f: + 7e:c9:9b:68:a0:f8:1e:00:14:d0:da:2a:bf:c8:ca:a8:1c:10: + b5:68:a2:f1:41:93:0c:f3:3f:c0:c6:53:3c:8d:a7:dd:a5:7b: + 35:cc:44:e0:5b:6d:c5:cb:33:6f:c1:43:7e:06:df:21:99:11: + b3:91:41:b4:5e:f0:37:1e:8e:e5:73:85:dc:4a:21:d5:41:f9: + 4e:b8:f5:ed:21:93:09:91:c2:8c:6b:04:a4:84:ab:3a:fe:35: + 64:fa:6b:a7:8d:40:a6:64:89:30:84:ac:28:99:5a:01:79:77: + c0:df:88:da:a9:75:5f:c4:51:ae:a8:45:7b:d2:e1:a2:81:29: + 60:cd:7b:cd +-----BEGIN CERTIFICATE----- +MIIDDTCCAfWgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp +bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs +ZDAgFw0yMzAyMDcyMTUzNDlaGA8yMDUwMDYyNTIxNTM0OVowJjEkMCIGA1UEAwwb +aHR0cHMtb25seS5uZ2lueC1wcm94eS50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA2YdIAoX0Xw2QfkxPE4lBykEVwm/9qMcXg8bdjP4ZpLJrCzVP +tD18QAoEMyr9EHL3Y2OZWz3seO7GTcgOTL7yP+MCdFeawf4VlWNO5yzrcPJryLoB +osqhx3b/OOTCsGb8hdKvDyKB1ILr1bDmaRQ33Y2tKc6TaFrO9Hd2b3gTtsgv/uC2 +fvspFr7i9UU7OVtS3Ca3ygy2HPyoOAvdwfQEmy04yaUtPvFCiFOiOxfP1Twr1mp/ +bwWNxbddZB6DG+fsgD1tNMFmsuZd2aduRnUUvxAWxfxHjmP65bS98rngy+p1+Wju +fY/qjxqfNCd6Sp+F/T4Xp5bD0E5QoqLgRZLQtQIDAQABoyowKDAmBgNVHREEHzAd +ghtodHRwcy1vbmx5Lm5naW54LXByb3h5LnRlc3QwDQYJKoZIhvcNAQELBQADggEB +AIpSRkKpdBhqUpDvpOnFVNWXOv+LwnZPnkeq4erlua+dM+OFF1R9Mr2skD9c0qFC +F1IrsYPlw7+B8Oc44ohne9hZ/vmUmbq+9Dwkssee8Jghxi3C6PNnvWIAqs40+rRT +bcEJXlW9Q6qGxvjFg0Y6SRKi7DA2DJlEdAmdzEuYH37Jm2ig+B4AFNDaKr/Iyqgc +ELVoovFBkwzzP8DGUzyNp92lezXMROBbbcXLM2/BQ34G3yGZEbORQbRe8DcejuVz +hdxKIdVB+U649e0hkwmRwoxrBKSEqzr+NWT6a6eNQKZkiTCErCiZWgF5d8DfiNqp +dV/EUa6oRXvS4aKBKWDNe80= +-----END CERTIFICATE----- diff --git a/test/test_fallback.data/withdefault.certs/https-only.nginx-proxy.test.key b/test/test_fallback.data/withdefault.certs/https-only.nginx-proxy.test.key new file mode 100644 index 0000000..17976ce --- /dev/null +++ b/test/test_fallback.data/withdefault.certs/https-only.nginx-proxy.test.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA2YdIAoX0Xw2QfkxPE4lBykEVwm/9qMcXg8bdjP4ZpLJrCzVP +tD18QAoEMyr9EHL3Y2OZWz3seO7GTcgOTL7yP+MCdFeawf4VlWNO5yzrcPJryLoB +osqhx3b/OOTCsGb8hdKvDyKB1ILr1bDmaRQ33Y2tKc6TaFrO9Hd2b3gTtsgv/uC2 +fvspFr7i9UU7OVtS3Ca3ygy2HPyoOAvdwfQEmy04yaUtPvFCiFOiOxfP1Twr1mp/ +bwWNxbddZB6DG+fsgD1tNMFmsuZd2aduRnUUvxAWxfxHjmP65bS98rngy+p1+Wju +fY/qjxqfNCd6Sp+F/T4Xp5bD0E5QoqLgRZLQtQIDAQABAoIBAAWs//YA5MVuJy0E +dLO/yxWp6RVvsqCqwTRRBgrdvnGLrjtWosPDLvDE0iM7peq99TKEsMWusfLd2BLD +e4wJF20PUUsT1hflt050juR9SY9i4+kS4WQMAXig5DvpzCKqLUCYpLSyY8zVta2X +tgtb2bFQNwp2N2ZrqCa8zzxNV8ZXGoW+ZlvBJEDtBwt1DCDhY39/pqHfIhFl4Vwk +YhhbVjID145D1j/fP6vLceM2YA4uRmF1itj1iQ6YNNpXRspUGE4DXdqR6HcbduiX +trZjmdtKXY8mJg6jyLZxYbjFlKV/LvqKRYF3Jb9K0vdd4juBdZoy7DQzoLhcnzui +pEnPLakCgYEA9tN6KdQGKGBXGuF+ZqhXfB/XSkKUf8o/5j62cbu11ZIJ+iEBx+d6 +lQAxTz5hHUL6a3c5qiM+AWBxYuFD6oqptIlTlBfIXI978neDNvEWWffivPvQLbt9 +o9ohOirfK1iGPvtrpAwjv5ylE5SiTmJ/6wDvQWjNGAnJ3aaxkesJUSMCgYEA4Z0K +UHZVtnKLtzzIY7KfLbuKF/fJEDfMNr4Wgl6ny21vqO9kJGmA7SaoNdhx8RDcKmeV +/Vey4ug6YlOG48eapKLTthdRz5mx+jIkUfdOhj81m28xm/OPTqCrviTHCNOHeYDy +NKAIlJMo2z0vTKJn5eP6CsYmDWLpHQNyXY5qcEcCgYAzDBWt5O3JF/Or2Yr8zEAb +qbIq544yx69jfQDakMnQe72Yf48Quuz9N+b6zpnjJWEJLMU+TL+cJUgN/SzAqyDh +96zTaf/ENOCbiuAWUtIelUfNcf7iFm6rnodUsl0pZ8uL5w+iA+i4zjrNy+WtdG2k +OrNAwd345L1dHAaJeSSaJQKBgQCUnF3r7Fa/TCpt87LHwSQK+sqWyRf+/9IbiRDI +pVL/s8FmVPHw7jIHhHwuo7lCImnz4LGy5C6oOnIizIRAy/04Ty0Hd8ri5YmPlbHI +8A8gbMiB7zeNU1zlXP5jzFPyo2tMhLyGH5gnTdwOtfnPD/dCPe45ZJYyISIOg3O0 +3peMBwKBgH20cskAOCNclfoG+Nis52h8FqmDlflJ8waUarvk26JhO1e009kOytw8 +x/qSuttpGtTG+4fdc2wJvFNczr4h9ZlftBdgZXj8PKgRpcIe8q97Xg8PUj+Xfu/t +vD/QV+tVcGoAMsQq4NeFxiTbPfwVyXdYFT1XVCu6JEdLL+gpWh5W +-----END RSA PRIVATE KEY----- diff --git a/test/test_fallback.data/withdefault.yml b/test/test_fallback.data/withdefault.yml new file mode 100644 index 0000000..00f7ee7 --- /dev/null +++ b/test/test_fallback.data/withdefault.yml @@ -0,0 +1,36 @@ +services: + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./withdefault.certs:/etc/nginx/certs:ro + https-and-http: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: https-and-http.nginx-proxy.test + https-only: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: https-only.nginx-proxy.test + HTTPS_METHOD: nohttp + http-only: + image: web + expose: + - "83" + environment: + WEB_PORTS: "83" + VIRTUAL_HOST: http-only.nginx-proxy.test + HTTPS_METHOD: nohttps + missing-cert: + image: web + expose: + - "84" + environment: + WEB_PORTS: "84" + VIRTUAL_HOST: missing-cert.nginx-proxy.test diff --git a/test/test_fallback.py b/test/test_fallback.py new file mode 100644 index 0000000..1e687a3 --- /dev/null +++ b/test/test_fallback.py @@ -0,0 +1,53 @@ +import os.path + +import backoff +import pytest +import requests + + +@pytest.fixture +def data_dir(): + return f"{os.path.splitext(__file__)[0]}.data" + + +@pytest.fixture +def docker_compose_file(data_dir, compose_file): + return os.path.join(data_dir, compose_file) + + +@pytest.fixture +def get(docker_compose, nginxproxy, want_err_re): + + @backoff.on_exception( + backoff.constant, + requests.exceptions.RequestException, + giveup=lambda e: want_err_re and want_err_re.search(str(e)), + interval=.3, + max_tries=30, + jitter=None) + def _get(url): + return nginxproxy.get(url, allow_redirects=False) + + return _get + + +@pytest.mark.parametrize("compose_file,url,want_code,want_err_re", [ + # Has default.crt. + ("withdefault.yml", "http://https-and-http.nginx-proxy.test/", 301, None), + ("withdefault.yml", "https://https-and-http.nginx-proxy.test/", 200, None), + ("withdefault.yml", "http://https-only.nginx-proxy.test/", 503, None), + ("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", "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), +]) +def test_fallback(get, url, want_code, want_err_re): + if want_err_re is None: + r = get(url) + assert r.status_code == want_code + else: + with pytest.raises(requests.exceptions.RequestException, match=want_err_re): + get(url) diff --git a/test/test_ssl/wildcard_cert_and_nohttps/test_wildcard_cert_nohttps.py b/test/test_ssl/wildcard_cert_and_nohttps/test_wildcard_cert_nohttps.py index 68b0329..603d281 100644 --- a/test/test_ssl/wildcard_cert_and_nohttps/test_wildcard_cert_nohttps.py +++ b/test/test_ssl/wildcard_cert_and_nohttps/test_wildcard_cert_nohttps.py @@ -24,10 +24,10 @@ def test_https_get_served(docker_compose, nginxproxy, subdomain): assert f"answer from port 8{subdomain}\n" == r.text @pytest.mark.filterwarnings('ignore::urllib3.exceptions.InsecureRequestWarning') -def test_web3_https_is_500_and_SSL_validation_fails(docker_compose, nginxproxy): +def test_https_request_to_nohttps_vhost_goes_to_fallback_server(docker_compose, nginxproxy): with pytest.raises( (CertificateError, SSLError) ) as excinfo: nginxproxy.get("https://3.web.nginx-proxy.tld/port") assert """hostname '3.web.nginx-proxy.tld' doesn't match 'nginx-proxy.tld'""" in str(excinfo.value) r = nginxproxy.get("https://3.web.nginx-proxy.tld/port", verify=False) - assert r.status_code == 500 + assert r.status_code == 503 From 9297e9438901df2898c2daf2145a28cb761f880d Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Thu, 2 Feb 2023 22:02:06 -0500 Subject: [PATCH 4/5] fix: Emit TLS error if there are no certs available Before, if neither the vhost-specific cert nor `default.crt` existed, nginx-proxy would not create the https vhost. This resulted in nginx either refusing the connection or serving the wrong vhost depending on whether there was another https vhost with a certificate. Now nginx-proxy always creates an https server for a vhost, even if the vhost-specific certificate and the default certificate are both missing. When both certs are missing, nginx is given empty certificate data to make it possible for it to start up without an error. The empty certificate data causes the user to see a TLS error, which is much easier to troubleshoot than a connection refused error or serving the wrong vhost. --- README.md | 32 ++++++- nginx.tmpl | 83 +++++++++++-------- .../http-only.nginx-proxy.test.crt | 71 ++++++++++++++++ .../http-only.nginx-proxy.test.key | 27 ++++++ .../https-and-http.nginx-proxy.test.crt | 71 ++++++++++++++++ .../https-and-http.nginx-proxy.test.key | 27 ++++++ .../https-only.nginx-proxy.test.crt | 71 ++++++++++++++++ .../https-only.nginx-proxy.test.key | 27 ++++++ test/test_fallback.data/nodefault.yml | 36 ++++++++ test/test_fallback.py | 15 ++++ 10 files changed, 423 insertions(+), 37 deletions(-) create mode 100644 test/test_fallback.data/nodefault.certs/http-only.nginx-proxy.test.crt create mode 100644 test/test_fallback.data/nodefault.certs/http-only.nginx-proxy.test.key create mode 100644 test/test_fallback.data/nodefault.certs/https-and-http.nginx-proxy.test.crt create mode 100644 test/test_fallback.data/nodefault.certs/https-and-http.nginx-proxy.test.key create mode 100644 test/test_fallback.data/nodefault.certs/https-only.nginx-proxy.test.crt create mode 100644 test/test_fallback.data/nodefault.certs/https-only.nginx-proxy.test.key create mode 100644 test/test_fallback.data/nodefault.yml diff --git a/README.md b/README.md index 4e0d9d4..2757c33 100644 --- a/README.md +++ b/README.md @@ -347,10 +347,9 @@ Note that the `Mozilla-Old` policy should use a 1024 bits DH key for compatibili 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 is always preferred when available. -* 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 to establish a connection. A self-signed or generic cert named `default.crt` and `default.key` will allow a client browser to make a SSL connection (likely w/ a warning) and subsequently receive a 500. +* If a virtual host has a usable cert, port 80 will redirect to 443 for that virtual host so that HTTPS is always preferred when available. +* If the virtual host does not have a usable cert, but `default.crt` and `default.key` exist, those will be used as the virtual host's certificate and the client browser will receive a 500 error. +* If the virtual host does not have a usable cert, and `default.crt` and `default.key` do not exist, TLS negotiation will fail (see [Missing Certificate](#missing-certificate) below). 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`, or disable the HTTPS site with `HTTPS_METHOD=nohttps`. `HTTPS_METHOD` can be specified on each container for which you want to override the default behavior or on the proxy container to set it globally. If `HTTPS_METHOD=noredirect` is used, Strict Transport Security (HSTS) is disabled to prevent HTTPS users from being redirected by the client. If you cannot get to the HTTP site after changing this setting, your browser has probably cached the HSTS policy and is automatically redirecting you back to HTTPS. You will need to clear your browser's HSTS cache or use an incognito window / different browser. @@ -358,6 +357,31 @@ By default, [HTTP Strict Transport Security (HSTS)](https://developer.mozilla.or *WARNING*: HSTS will force your users to visit the HTTPS version of your site for the `max-age` time - even if they type in `http://` manually. The only way to get to an HTTP site after receiving an HSTS response is to clear your browser's HSTS cache. +#### Missing Certificate + +If HTTPS is enabled for a virtual host but its certificate is missing, nginx-proxy will configure nginx to use the default certificate (`default.crt` with `default.key`) and return a 500 error. + +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: + + * Chrome: + + > This site can't provide a secure connection + > + > example.test sent an invalid response. + > + > Try running Connectivity Diagnostics. + > + > `ERR_SSL_PROTOCOL_ERROR` + + * Firefox: + + > Secure Connection Failed + > + > An error occurred during a connection to example.test. + > Peer reports it experienced an internal error. + > + > Error code: `SSL_ERROR_INTERNAL_ERROR_ALERT` "TLS error". + ### 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 diff --git a/nginx.tmpl b/nginx.tmpl index c8b704d..d2ccd8f 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -350,23 +350,30 @@ server { server_name _; # This is just an invalid value which will never trigger on a real hostname. server_tokens off; listen {{ $globals.external_http_port }}; + listen {{ $globals.external_https_port }} ssl http2; {{- if $globals.enable_ipv6 }} listen [::]:{{ $globals.external_http_port }}; + listen [::]:{{ $globals.external_https_port }} ssl http2; {{- end }} {{ $globals.access_log }} - return 503; - {{- if $globals.default_cert_ok }} - listen {{ $globals.external_https_port }} ssl http2; - {{- if $globals.enable_ipv6 }} - listen [::]:{{ $globals.external_https_port }} ssl http2; - {{- end }} - ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_certificate /etc/nginx/certs/default.crt; ssl_certificate_key /etc/nginx/certs/default.key; +{{- else }} + # No default.crt certificate found for this vhost, so force nginx to emit a + # TLS error if the client connects via https. + {{- /* See the comment in the main `server` directive for rationale. */}} + ssl_ciphers aNULL; + set $empty ""; + ssl_certificate data:$empty; + ssl_certificate_key data:$empty; + if ($https) { + return 444; + } {{- end }} + return 503; } {{- range $host, $containers := groupByMulti $globals.containers "Env.VIRTUAL_HOST" "," }} @@ -491,13 +498,14 @@ server { listen [::]:{{ $globals.external_http_port }} {{ $default_server }}; {{- end }} {{- end }} - {{- if and (ne $https_method "nohttps") $cert_ok }} + {{- if ne $https_method "nohttps" }} listen {{ $globals.external_https_port }} ssl http2 {{ $default_server }}; {{- if $globals.enable_ipv6 }} listen [::]:{{ $globals.external_https_port }} ssl http2 {{ $default_server }}; {{- end }} - {{- template "ssl_policy" (dict "ssl_policy" $ssl_policy) }} + {{- if $cert_ok }} + {{- template "ssl_policy" (dict "ssl_policy" $ssl_policy) }} ssl_session_timeout 5m; ssl_session_cache shared:SSL:50m; @@ -506,22 +514,50 @@ server { 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)) }} + {{- if (exists (printf "/etc/nginx/certs/%s.dhparam.pem" $cert)) }} ssl_dhparam {{ printf "/etc/nginx/certs/%s.dhparam.pem" $cert }}; - {{- end }} + {{- end }} - {{- if (exists (printf "/etc/nginx/certs/%s.chain.pem" $cert)) }} + {{- if (exists (printf "/etc/nginx/certs/%s.chain.pem" $cert)) }} ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate {{ printf "/etc/nginx/certs/%s.chain.pem" $cert }}; - {{- end }} + {{- end }} - {{- if (not (or (eq $https_method "noredirect") (eq $hsts "off"))) }} + {{- if (not (or (eq $https_method "noredirect") (eq $hsts "off"))) }} set $sts_header ""; if ($https) { set $sts_header "{{ trim $hsts }}"; } add_header Strict-Transport-Security $sts_header always; + {{- end }} + {{- else if $globals.default_cert_ok }} + # No certificate found for this vhost, so use the default certificate and + # return an error code if the user connects via https. + ssl_certificate /etc/nginx/certs/default.crt; + ssl_certificate_key /etc/nginx/certs/default.key; + if ($https) { + return 500; + } + {{- else }} + # No certificate found for this vhost, so force nginx to emit a TLS error if + # the client connects via https. + {{- /* + * The alternative is to not provide an https server for this + * vhost, which would either cause the user to see the wrong + * vhost (if there is another vhost with a certificate) or a + * connection refused error (if there is no other vhost with a + * certificate). A TLS error is easier to troubleshoot, and is + * safer than serving the wrong vhost. Also see + * . + */}} + ssl_ciphers aNULL; + set $empty ""; + ssl_certificate data:$empty; + ssl_certificate_key data:$empty; + if ($https) { + return 444; + } {{- end }} {{- end }} @@ -558,23 +594,4 @@ server { } {{- end }} } - - {{- if and (ne $https_method "nohttps") (not $cert_ok) $globals.default_cert_ok }} -server { - server_name {{ $host }}; - {{- if $server_tokens }} - server_tokens {{ $server_tokens }}; - {{- end }} - listen {{ $globals.external_https_port }} ssl http2 {{ $default_server }}; - {{- if $globals.enable_ipv6 }} - listen [::]:{{ $globals.external_https_port }} ssl http2 {{ $default_server }}; - {{- end }} - {{ $globals.access_log }} - return 500; - - ssl_certificate /etc/nginx/certs/default.crt; - ssl_certificate_key /etc/nginx/certs/default.key; -} - {{- end }} - {{- end }} diff --git a/test/test_fallback.data/nodefault.certs/http-only.nginx-proxy.test.crt b/test/test_fallback.data/nodefault.certs/http-only.nginx-proxy.test.crt new file mode 100644 index 0000000..33fa2f7 --- /dev/null +++ b/test/test_fallback.data/nodefault.certs/http-only.nginx-proxy.test.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld + Validity + Not Before: Feb 7 21:54:16 2023 GMT + Not After : Jun 25 21:54:16 2050 GMT + Subject: CN=http-only.nginx-proxy.test + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:b4:62:61:07:54:2e:6d:55:83:2d:24:b7:e2:15: + 34:13:bd:79:21:e9:10:75:3f:4c:f8:ba:60:29:87: + e5:8e:2a:1e:fd:33:51:5a:8a:3a:6f:60:ff:24:f1: + 1b:27:30:8c:ac:43:04:b7:79:cb:7a:ec:c6:08:a4: + a0:15:b0:0f:ee:6b:15:84:24:11:bc:85:2b:48:06: + 04:0a:58:bb:8c:e8:4d:48:f5:06:c5:91:fe:5d:99: + 0a:29:31:8a:f1:9b:0c:e0:39:75:a1:06:9b:d4:f5: + 06:74:8f:46:5e:64:ba:2f:d0:3d:7c:3d:30:03:e9: + 7c:35:17:69:04:f6:2e:29:d4:93:d6:d6:d2:6c:04: + 38:06:21:06:05:30:8a:b9:9d:05:8d:12:6e:48:39: + bb:f6:93:4f:ba:a5:84:c7:96:2f:be:92:25:e9:d0: + 95:2a:d9:23:8a:b3:28:0b:b6:19:1c:3b:be:a2:91: + 70:44:a8:77:18:94:4b:df:61:f4:5c:c9:78:76:34: + b5:87:0f:c0:92:04:26:b6:ca:62:cd:9b:5d:eb:bf: + 10:ac:df:af:72:5f:af:09:38:b1:dc:e1:3d:13:db: + a0:ac:b7:2e:ca:39:5c:4c:f1:1e:81:a8:b4:44:a2: + 72:d5:3b:c0:71:cc:dc:16:0d:fa:38:96:44:b3:00: + d6:65 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:http-only.nginx-proxy.test + Signature Algorithm: sha256WithRSAEncryption + 3b:54:95:48:4d:f6:93:38:42:40:02:ab:b7:17:3b:50:3b:ca: + c7:12:69:b0:da:cb:d7:3e:0e:1f:bf:a2:59:c7:fe:c2:5c:43: + 84:92:b9:3a:be:8f:7e:2e:81:3c:ed:f3:a9:77:21:c2:35:f1: + da:cf:3a:1e:e2:ee:a2:ce:72:55:97:87:0e:ad:59:61:f7:75: + 46:c0:2b:d4:88:b7:36:97:11:fb:5e:28:89:e9:2a:92:f1:15: + f1:43:8e:c1:38:85:8d:3a:26:7d:25:72:93:17:96:8d:5a:ed: + e8:73:3a:d5:8d:80:f2:af:38:84:ff:85:2e:d1:36:7d:2e:e1: + f0:2c:d8:15:5f:fc:c5:70:5d:25:6a:22:f3:2a:cd:0f:25:ad: + d4:93:d3:9a:3e:50:bc:da:a5:6c:86:ea:1d:d9:b9:c5:90:db: + f5:02:c8:c9:77:5c:ef:77:fe:74:60:41:33:d9:3c:a2:e1:73: + aa:14:18:5d:36:58:c8:41:63:4c:59:0e:4b:3d:c5:65:5a:01: + b0:16:50:0f:d0:4f:0d:ca:97:f6:11:47:06:6b:b1:ae:bb:26: + 30:34:8b:7a:91:5d:8a:22:c7:f9:05:0d:bb:a5:b7:60:c0:20: + ce:d0:0e:c0:66:b3:e7:c4:61:ec:c5:40:e6:52:11:41:c3:11: + 18:04:c7:1e +-----BEGIN CERTIFICATE----- +MIIDCzCCAfOgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp +bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs +ZDAgFw0yMzAyMDcyMTU0MTZaGA8yMDUwMDYyNTIxNTQxNlowJTEjMCEGA1UEAwwa +aHR0cC1vbmx5Lm5naW54LXByb3h5LnRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC0YmEHVC5tVYMtJLfiFTQTvXkh6RB1P0z4umAph+WOKh79M1Fa +ijpvYP8k8RsnMIysQwS3ect67MYIpKAVsA/uaxWEJBG8hStIBgQKWLuM6E1I9QbF +kf5dmQopMYrxmwzgOXWhBpvU9QZ0j0ZeZLov0D18PTAD6Xw1F2kE9i4p1JPW1tJs +BDgGIQYFMIq5nQWNEm5IObv2k0+6pYTHli++kiXp0JUq2SOKsygLthkcO76ikXBE +qHcYlEvfYfRcyXh2NLWHD8CSBCa2ymLNm13rvxCs369yX68JOLHc4T0T26Csty7K +OVxM8R6BqLREonLVO8BxzNwWDfo4lkSzANZlAgMBAAGjKTAnMCUGA1UdEQQeMByC +Gmh0dHAtb25seS5uZ2lueC1wcm94eS50ZXN0MA0GCSqGSIb3DQEBCwUAA4IBAQA7 +VJVITfaTOEJAAqu3FztQO8rHEmmw2svXPg4fv6JZx/7CXEOEkrk6vo9+LoE87fOp +dyHCNfHazzoe4u6iznJVl4cOrVlh93VGwCvUiLc2lxH7XiiJ6SqS8RXxQ47BOIWN +OiZ9JXKTF5aNWu3oczrVjYDyrziE/4Uu0TZ9LuHwLNgVX/zFcF0laiLzKs0PJa3U +k9OaPlC82qVshuod2bnFkNv1AsjJd1zvd/50YEEz2Tyi4XOqFBhdNljIQWNMWQ5L +PcVlWgGwFlAP0E8Nypf2EUcGa7GuuyYwNIt6kV2KIsf5BQ27pbdgwCDO0A7AZrPn +xGHsxUDmUhFBwxEYBMce +-----END CERTIFICATE----- diff --git a/test/test_fallback.data/nodefault.certs/http-only.nginx-proxy.test.key b/test/test_fallback.data/nodefault.certs/http-only.nginx-proxy.test.key new file mode 100644 index 0000000..3834584 --- /dev/null +++ b/test/test_fallback.data/nodefault.certs/http-only.nginx-proxy.test.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAtGJhB1QubVWDLSS34hU0E715IekQdT9M+LpgKYfljioe/TNR +Woo6b2D/JPEbJzCMrEMEt3nLeuzGCKSgFbAP7msVhCQRvIUrSAYECli7jOhNSPUG +xZH+XZkKKTGK8ZsM4Dl1oQab1PUGdI9GXmS6L9A9fD0wA+l8NRdpBPYuKdST1tbS +bAQ4BiEGBTCKuZ0FjRJuSDm79pNPuqWEx5YvvpIl6dCVKtkjirMoC7YZHDu+opFw +RKh3GJRL32H0XMl4djS1hw/AkgQmtspizZtd678QrN+vcl+vCTix3OE9E9ugrLcu +yjlcTPEegai0RKJy1TvAcczcFg36OJZEswDWZQIDAQABAoIBAAfDA/HQyX6i41YZ +8l+kEe2XhZLT+IVTB/jb7C9dTZ9kaJj0kFeZAxKv1cq9JTH2gNcYuyc58muDrLHK +g6jrPoQ/z1k0RB8ci9Q5jgrz7n4NsOWmxXfS5GMaprlHDHeA+HjdgBZBtorfUDvL +vndpVimgiETETUCd115hd39jKHFcRcdV6yCix7ObywK3dMgLVpagCcnlyCWffS/r +nhhMfJ+VstW0nUtfZ7JEYwT6Cg7lLAVtDkqPX8zGjJiRwUKH808bUyqEw1y5Cc8U +U5hbmMgPWfXsKxsEC6FSVHBG9ZX2jymOMQXijLFcBSuWvADHmyU+ZxXcbtd1rv4E +cGFj3wECgYEA5cNrr5WjrpEin6MYYVWxiQ+xEWPU2R17eApagrDRLM41JJpv7a5m +TYuZRfIxb59CBPi718Gi168P3T2KMvo2/BTh9Lq5ZBYHx3aDqW2QvMFn7/tgamj8 +0DBxccd2QWfGIBrT1rAF7lD8TC86wtDDVKrvhucRSEXVKF/jWFFRGfUCgYEAyPt6 +48khr7sfNMVdkDLjQjZVV6H7ZUMoSn0FGybgKWxW+b0XCBPObUQWIpyCNTRr1+4A +1TAUS+F/OVVfwnLNgemeE2wd6CaduxwiK1U4pHbyXCElH1ifonHWV3MoXOefYsiY +q5z2jfJzUi0JZVUKsveu9rQsFLsc//1s/I5T1LECgYEAldY6fNg2VVp63OZsuNU8 +oSiljbSwEyMh6Oe/nOkYkIKtr4AzrCoGt11piG7ohGW0lS9suMijnMqiquI+JP5+ +KyinLoUy761aR17nf+9e62mpkZw6hUqQTGi7Irs0SHUXhMpaCfDi/Ua9MiW+yVuB +ds6+xBgeciZwWxMlXOwy2p0CgYEAm+YWiSK3Mq0fo7uEvBn9Fps2z+ciLoZNdppL +n6gkMX2MaeQ3PVi/wxoRYX+tsL+c973yf2vwEnw0R7Dlutt6dc9VgxNWj4GE0GMe +Tiao7Uom7Tf4p7wC9+r9rI/zOz2f8OxRIK18wtbShWfR5fx1dCWUXmGb3+jUse1O +4Qk2FcECgYAvSvGFoJb8tuHFEYYHBbjficmvTUsrTE+EhxPqWKFhKfF19fFFIupy +XBCrN6nwrh+/YMxZXeIRbbTTf814cOO7PjLeNhnfhJZkaJq1HzbYe3bOurna3qrm +Ra3xiM8Ld2PyGnZPXf8+AWhMhuPkLX1KFVTCAxwCpmTZCHtiGCmXMA== +-----END RSA PRIVATE KEY----- diff --git a/test/test_fallback.data/nodefault.certs/https-and-http.nginx-proxy.test.crt b/test/test_fallback.data/nodefault.certs/https-and-http.nginx-proxy.test.crt new file mode 100644 index 0000000..8b04cb9 --- /dev/null +++ b/test/test_fallback.data/nodefault.certs/https-and-http.nginx-proxy.test.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld + Validity + Not Before: Feb 7 21:53:19 2023 GMT + Not After : Jun 25 21:53:19 2050 GMT + Subject: CN=https-and-http.nginx-proxy.test + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:b7:97:85:d1:7f:6b:50:29:f3:87:b7:4e:f5:25: + 40:6a:d8:fa:a1:63:3c:4a:2e:68:4a:c6:8b:38:df: + 07:81:d0:08:9d:fc:17:f5:37:28:7f:31:e6:f3:81: + 28:4e:22:b6:bd:a2:4e:f2:2f:e5:0f:dd:55:3c:e1: + 04:84:4c:45:1b:1a:ae:b7:f0:2a:da:43:05:71:91: + 92:b8:d1:49:fe:80:0a:53:b9:66:da:54:60:9a:fc: + e1:b2:e8:28:48:7f:96:94:3c:92:a3:b2:37:f6:7a: + c2:de:0b:12:f0:ae:4e:92:fe:2d:c1:b2:95:28:1f: + 88:8d:79:99:81:19:ae:22:a4:95:f5:9f:db:25:8e: + 1d:cf:43:cd:6f:85:93:5f:79:ee:f8:f3:d4:82:e1: + e9:4d:c9:ad:ae:5b:92:43:3a:3c:71:51:70:f7:3e: + bd:1b:24:52:6a:a3:cf:54:72:57:ed:fe:72:ea:96: + 9b:5a:02:02:a7:df:85:b7:68:ae:1e:07:77:9f:59: + a5:a0:8b:28:c2:c8:b7:bb:8a:42:50:df:05:73:bf: + 9c:55:13:b5:82:79:77:40:57:a4:8f:88:a5:71:50: + d7:70:b0:4d:0c:d9:86:b3:9b:db:8a:20:bd:19:68: + 10:52:2d:53:ba:0e:2e:1c:ad:80:54:bb:b6:c9:ab: + 11:39 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:https-and-http.nginx-proxy.test + Signature Algorithm: sha256WithRSAEncryption + 2c:f3:e5:47:3f:8e:5a:28:b1:df:e5:95:50:85:6f:27:2f:a6: + 8d:f1:5e:cf:df:e2:52:66:97:61:36:59:81:26:25:19:99:c9: + 93:e5:85:cb:ca:69:af:4b:21:a3:d2:7a:bf:b5:5e:2d:42:fb: + 99:f8:22:58:e5:bf:79:b8:8a:74:7e:c6:94:14:d9:f2:27:63: + b6:e5:74:21:5b:59:fb:f6:c8:a9:28:fb:60:f7:5e:bd:c2:e6: + 74:24:14:96:61:95:6c:c2:66:b4:52:25:a1:85:5a:97:e5:68: + 5c:62:cf:69:3b:b0:a9:56:d8:e3:5f:74:dc:84:18:d5:3e:4f: + c9:35:39:26:88:dc:9b:80:d9:40:e1:4f:09:27:8d:d2:89:55: + 30:91:02:86:35:04:95:1e:1d:58:14:5b:c6:e0:2e:a7:bf:a8: + f6:2b:76:8a:4e:71:79:bc:c0:04:cd:db:81:73:46:ce:68:ed: + 25:b0:0e:42:8d:96:64:77:3b:f4:9d:1a:c9:f6:78:4c:56:4f: + 92:17:29:3d:80:50:71:77:4b:a8:29:c2:12:fc:ad:0a:37:81: + 38:4c:fb:54:99:4d:12:5f:98:dc:d1:a9:7b:08:45:c4:6f:7e: + fe:00:e0:db:79:fe:d1:28:e3:8e:82:d1:fb:bc:0a:c4:42:93: + c9:5e:eb:ba +-----BEGIN CERTIFICATE----- +MIIDFTCCAf2gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp +bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs +ZDAgFw0yMzAyMDcyMTUzMTlaGA8yMDUwMDYyNTIxNTMxOVowKjEoMCYGA1UEAwwf +aHR0cHMtYW5kLWh0dHAubmdpbngtcHJveHkudGVzdDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALeXhdF/a1Ap84e3TvUlQGrY+qFjPEouaErGizjfB4HQ +CJ38F/U3KH8x5vOBKE4itr2iTvIv5Q/dVTzhBIRMRRsarrfwKtpDBXGRkrjRSf6A +ClO5ZtpUYJr84bLoKEh/lpQ8kqOyN/Z6wt4LEvCuTpL+LcGylSgfiI15mYEZriKk +lfWf2yWOHc9DzW+Fk1957vjz1ILh6U3Jra5bkkM6PHFRcPc+vRskUmqjz1RyV+3+ +cuqWm1oCAqffhbdorh4Hd59ZpaCLKMLIt7uKQlDfBXO/nFUTtYJ5d0BXpI+IpXFQ +13CwTQzZhrOb24ogvRloEFItU7oOLhytgFS7tsmrETkCAwEAAaMuMCwwKgYDVR0R +BCMwIYIfaHR0cHMtYW5kLWh0dHAubmdpbngtcHJveHkudGVzdDANBgkqhkiG9w0B +AQsFAAOCAQEALPPlRz+OWiix3+WVUIVvJy+mjfFez9/iUmaXYTZZgSYlGZnJk+WF +y8ppr0sho9J6v7VeLUL7mfgiWOW/ebiKdH7GlBTZ8idjtuV0IVtZ+/bIqSj7YPde +vcLmdCQUlmGVbMJmtFIloYVal+VoXGLPaTuwqVbY41903IQY1T5PyTU5Jojcm4DZ +QOFPCSeN0olVMJEChjUElR4dWBRbxuAup7+o9it2ik5xebzABM3bgXNGzmjtJbAO +Qo2WZHc79J0ayfZ4TFZPkhcpPYBQcXdLqCnCEvytCjeBOEz7VJlNEl+Y3NGpewhF +xG9+/gDg23n+0SjjjoLR+7wKxEKTyV7rug== +-----END CERTIFICATE----- diff --git a/test/test_fallback.data/nodefault.certs/https-and-http.nginx-proxy.test.key b/test/test_fallback.data/nodefault.certs/https-and-http.nginx-proxy.test.key new file mode 100644 index 0000000..11f5210 --- /dev/null +++ b/test/test_fallback.data/nodefault.certs/https-and-http.nginx-proxy.test.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAt5eF0X9rUCnzh7dO9SVAatj6oWM8Si5oSsaLON8HgdAInfwX +9TcofzHm84EoTiK2vaJO8i/lD91VPOEEhExFGxqut/Aq2kMFcZGSuNFJ/oAKU7lm +2lRgmvzhsugoSH+WlDySo7I39nrC3gsS8K5Okv4twbKVKB+IjXmZgRmuIqSV9Z/b +JY4dz0PNb4WTX3nu+PPUguHpTcmtrluSQzo8cVFw9z69GyRSaqPPVHJX7f5y6pab +WgICp9+Ft2iuHgd3n1mloIsowsi3u4pCUN8Fc7+cVRO1gnl3QFekj4ilcVDXcLBN +DNmGs5vbiiC9GWgQUi1Tug4uHK2AVLu2yasROQIDAQABAoIBACT4KSVHoEdzOyvw +GME6sB8T9Fw9TG2vrKaqFmzsVGmqh6Gwmu5xHgGG/fe44XHigaPsJDOWu2yXaEur +ECrH5P6RP++gODDdYCI/ayk2U80g4XN8mR6L8Swkkhphr4Lx1lOhYvH9uFE05Tqr +RjQbFY16C6K+oFSFDQ1YGDYsAqnM3RD7PH+lHpo8UN1TO/vogdSQEpMYZDwLAYnW +uD5G3c0u2PsGu9YLuz2p8hcs3chh+cqKJWXOeW0JLrNGx1bqeQWkn6nXRDdRYi9V +cJlTgDqGuF54bieSyq9ABDZQP4Ol+moYKDoIz5PwurNjcYSklrT1tw0gqHZoQK1L +fDjw3QECgYEA7QMRU1AFKTvO7/8WLHLN5BT63n31wm0e9PYpz/XVLWEfxBcp9Xmf +xAIhXZ/U9P4dfNqxTjN9mVGzCHh5KfDJnUFqOXFy/zvfMeRzJf6dJo6/4OX9Bijr +Tgd454vyGXYQP2t+F14UAwl6vlGOAjttiP5qY5Ef1gllBEeIPe9Ts9kCgYEAxkzZ +pq4HJ/5/iDquMEHXNXzpNPavSvgxQdl1ILvJ49LJImmQFBCP9PqiOTIfePz1OqUI +C4baFuc0FEDJ3x9CUNmMY1lEi2ZUq2agPSXaQNsMcKtEJH8SoJlJIRpkQA7unX09 +zb4dam6g79OaGmb8scePuezXMLv1Ee6WWtXbzGECgYEA6PYn9Gzl9cacu9dOUzgw +2ewpPcIvawDY+cxwAsHO3MDneVWPX4JBoGa7pwvwRTL1hwBqYMRJwwbD5CKObcQI +V/KxV28Eqo2N77tt1z2x9/E99u/4yTI1P0gm9ejfeVlL1RpyIMPPBcEujZ0Z6WXC +X3I63k0KLtajHRa2erIf4tkCgYAfunAgwTuX5JqXO3xfcEl033WY6deGUUvgU2Dw +Sdu1viY8gVNyQmwmMGwAZsquWxsJtRoibgM7IucsTml+b8v2j7hstP3IqCjn+9Wr +swDG28WTyXNvu31JgP04dLaRoVIAlOdsofym6OiLNvozO0M3VsziXMjZnVlK8zfP +dORkQQKBgQDXAJEJPygxVA+bF104dzCMWGmU7K8ShEWC5eOdKK4KWf9bNDpY6M6c +i6zga/xBbj7e3Bxqprpp8Wy2gIsnYiVo4V9EQethbLdomPxOpBMNMARw81rL1CpO +jbHB7bIDcKs2tQoZEXUW86ZxC8sdaDaWTJTfUO0RpJow6ZO3yvxVIQ== +-----END RSA PRIVATE KEY----- diff --git a/test/test_fallback.data/nodefault.certs/https-only.nginx-proxy.test.crt b/test/test_fallback.data/nodefault.certs/https-only.nginx-proxy.test.crt new file mode 100644 index 0000000..a93e728 --- /dev/null +++ b/test/test_fallback.data/nodefault.certs/https-only.nginx-proxy.test.crt @@ -0,0 +1,71 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: O=nginx-proxy test suite, CN=www.nginx-proxy.tld + Validity + Not Before: Feb 7 21:53:49 2023 GMT + Not After : Jun 25 21:53:49 2050 GMT + Subject: CN=https-only.nginx-proxy.test + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:d9:87:48:02:85:f4:5f:0d:90:7e:4c:4f:13:89: + 41:ca:41:15:c2:6f:fd:a8:c7:17:83:c6:dd:8c:fe: + 19:a4:b2:6b:0b:35:4f:b4:3d:7c:40:0a:04:33:2a: + fd:10:72:f7:63:63:99:5b:3d:ec:78:ee:c6:4d:c8: + 0e:4c:be:f2:3f:e3:02:74:57:9a:c1:fe:15:95:63: + 4e:e7:2c:eb:70:f2:6b:c8:ba:01:a2:ca:a1:c7:76: + ff:38:e4:c2:b0:66:fc:85:d2:af:0f:22:81:d4:82: + eb:d5:b0:e6:69:14:37:dd:8d:ad:29:ce:93:68:5a: + ce:f4:77:76:6f:78:13:b6:c8:2f:fe:e0:b6:7e:fb: + 29:16:be:e2:f5:45:3b:39:5b:52:dc:26:b7:ca:0c: + b6:1c:fc:a8:38:0b:dd:c1:f4:04:9b:2d:38:c9:a5: + 2d:3e:f1:42:88:53:a2:3b:17:cf:d5:3c:2b:d6:6a: + 7f:6f:05:8d:c5:b7:5d:64:1e:83:1b:e7:ec:80:3d: + 6d:34:c1:66:b2:e6:5d:d9:a7:6e:46:75:14:bf:10: + 16:c5:fc:47:8e:63:fa:e5:b4:bd:f2:b9:e0:cb:ea: + 75:f9:68:ee:7d:8f:ea:8f:1a:9f:34:27:7a:4a:9f: + 85:fd:3e:17:a7:96:c3:d0:4e:50:a2:a2:e0:45:92: + d0:b5 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:https-only.nginx-proxy.test + Signature Algorithm: sha256WithRSAEncryption + 8a:52:46:42:a9:74:18:6a:52:90:ef:a4:e9:c5:54:d5:97:3a: + ff:8b:c2:76:4f:9e:47:aa:e1:ea:e5:b9:af:9d:33:e3:85:17: + 54:7d:32:bd:ac:90:3f:5c:d2:a1:42:17:52:2b:b1:83:e5:c3: + bf:81:f0:e7:38:e2:88:67:7b:d8:59:fe:f9:94:99:ba:be:f4: + 3c:24:b2:c7:9e:f0:98:21:c6:2d:c2:e8:f3:67:bd:62:00:aa: + ce:34:fa:b4:53:6d:c1:09:5e:55:bd:43:aa:86:c6:f8:c5:83: + 46:3a:49:12:a2:ec:30:36:0c:99:44:74:09:9d:cc:4b:98:1f: + 7e:c9:9b:68:a0:f8:1e:00:14:d0:da:2a:bf:c8:ca:a8:1c:10: + b5:68:a2:f1:41:93:0c:f3:3f:c0:c6:53:3c:8d:a7:dd:a5:7b: + 35:cc:44:e0:5b:6d:c5:cb:33:6f:c1:43:7e:06:df:21:99:11: + b3:91:41:b4:5e:f0:37:1e:8e:e5:73:85:dc:4a:21:d5:41:f9: + 4e:b8:f5:ed:21:93:09:91:c2:8c:6b:04:a4:84:ab:3a:fe:35: + 64:fa:6b:a7:8d:40:a6:64:89:30:84:ac:28:99:5a:01:79:77: + c0:df:88:da:a9:75:5f:c4:51:ae:a8:45:7b:d2:e1:a2:81:29: + 60:cd:7b:cd +-----BEGIN CERTIFICATE----- +MIIDDTCCAfWgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp +bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs +ZDAgFw0yMzAyMDcyMTUzNDlaGA8yMDUwMDYyNTIxNTM0OVowJjEkMCIGA1UEAwwb +aHR0cHMtb25seS5uZ2lueC1wcm94eS50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA2YdIAoX0Xw2QfkxPE4lBykEVwm/9qMcXg8bdjP4ZpLJrCzVP +tD18QAoEMyr9EHL3Y2OZWz3seO7GTcgOTL7yP+MCdFeawf4VlWNO5yzrcPJryLoB +osqhx3b/OOTCsGb8hdKvDyKB1ILr1bDmaRQ33Y2tKc6TaFrO9Hd2b3gTtsgv/uC2 +fvspFr7i9UU7OVtS3Ca3ygy2HPyoOAvdwfQEmy04yaUtPvFCiFOiOxfP1Twr1mp/ +bwWNxbddZB6DG+fsgD1tNMFmsuZd2aduRnUUvxAWxfxHjmP65bS98rngy+p1+Wju +fY/qjxqfNCd6Sp+F/T4Xp5bD0E5QoqLgRZLQtQIDAQABoyowKDAmBgNVHREEHzAd +ghtodHRwcy1vbmx5Lm5naW54LXByb3h5LnRlc3QwDQYJKoZIhvcNAQELBQADggEB +AIpSRkKpdBhqUpDvpOnFVNWXOv+LwnZPnkeq4erlua+dM+OFF1R9Mr2skD9c0qFC +F1IrsYPlw7+B8Oc44ohne9hZ/vmUmbq+9Dwkssee8Jghxi3C6PNnvWIAqs40+rRT +bcEJXlW9Q6qGxvjFg0Y6SRKi7DA2DJlEdAmdzEuYH37Jm2ig+B4AFNDaKr/Iyqgc +ELVoovFBkwzzP8DGUzyNp92lezXMROBbbcXLM2/BQ34G3yGZEbORQbRe8DcejuVz +hdxKIdVB+U649e0hkwmRwoxrBKSEqzr+NWT6a6eNQKZkiTCErCiZWgF5d8DfiNqp +dV/EUa6oRXvS4aKBKWDNe80= +-----END CERTIFICATE----- diff --git a/test/test_fallback.data/nodefault.certs/https-only.nginx-proxy.test.key b/test/test_fallback.data/nodefault.certs/https-only.nginx-proxy.test.key new file mode 100644 index 0000000..17976ce --- /dev/null +++ b/test/test_fallback.data/nodefault.certs/https-only.nginx-proxy.test.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA2YdIAoX0Xw2QfkxPE4lBykEVwm/9qMcXg8bdjP4ZpLJrCzVP +tD18QAoEMyr9EHL3Y2OZWz3seO7GTcgOTL7yP+MCdFeawf4VlWNO5yzrcPJryLoB +osqhx3b/OOTCsGb8hdKvDyKB1ILr1bDmaRQ33Y2tKc6TaFrO9Hd2b3gTtsgv/uC2 +fvspFr7i9UU7OVtS3Ca3ygy2HPyoOAvdwfQEmy04yaUtPvFCiFOiOxfP1Twr1mp/ +bwWNxbddZB6DG+fsgD1tNMFmsuZd2aduRnUUvxAWxfxHjmP65bS98rngy+p1+Wju +fY/qjxqfNCd6Sp+F/T4Xp5bD0E5QoqLgRZLQtQIDAQABAoIBAAWs//YA5MVuJy0E +dLO/yxWp6RVvsqCqwTRRBgrdvnGLrjtWosPDLvDE0iM7peq99TKEsMWusfLd2BLD +e4wJF20PUUsT1hflt050juR9SY9i4+kS4WQMAXig5DvpzCKqLUCYpLSyY8zVta2X +tgtb2bFQNwp2N2ZrqCa8zzxNV8ZXGoW+ZlvBJEDtBwt1DCDhY39/pqHfIhFl4Vwk +YhhbVjID145D1j/fP6vLceM2YA4uRmF1itj1iQ6YNNpXRspUGE4DXdqR6HcbduiX +trZjmdtKXY8mJg6jyLZxYbjFlKV/LvqKRYF3Jb9K0vdd4juBdZoy7DQzoLhcnzui +pEnPLakCgYEA9tN6KdQGKGBXGuF+ZqhXfB/XSkKUf8o/5j62cbu11ZIJ+iEBx+d6 +lQAxTz5hHUL6a3c5qiM+AWBxYuFD6oqptIlTlBfIXI978neDNvEWWffivPvQLbt9 +o9ohOirfK1iGPvtrpAwjv5ylE5SiTmJ/6wDvQWjNGAnJ3aaxkesJUSMCgYEA4Z0K +UHZVtnKLtzzIY7KfLbuKF/fJEDfMNr4Wgl6ny21vqO9kJGmA7SaoNdhx8RDcKmeV +/Vey4ug6YlOG48eapKLTthdRz5mx+jIkUfdOhj81m28xm/OPTqCrviTHCNOHeYDy +NKAIlJMo2z0vTKJn5eP6CsYmDWLpHQNyXY5qcEcCgYAzDBWt5O3JF/Or2Yr8zEAb +qbIq544yx69jfQDakMnQe72Yf48Quuz9N+b6zpnjJWEJLMU+TL+cJUgN/SzAqyDh +96zTaf/ENOCbiuAWUtIelUfNcf7iFm6rnodUsl0pZ8uL5w+iA+i4zjrNy+WtdG2k +OrNAwd345L1dHAaJeSSaJQKBgQCUnF3r7Fa/TCpt87LHwSQK+sqWyRf+/9IbiRDI +pVL/s8FmVPHw7jIHhHwuo7lCImnz4LGy5C6oOnIizIRAy/04Ty0Hd8ri5YmPlbHI +8A8gbMiB7zeNU1zlXP5jzFPyo2tMhLyGH5gnTdwOtfnPD/dCPe45ZJYyISIOg3O0 +3peMBwKBgH20cskAOCNclfoG+Nis52h8FqmDlflJ8waUarvk26JhO1e009kOytw8 +x/qSuttpGtTG+4fdc2wJvFNczr4h9ZlftBdgZXj8PKgRpcIe8q97Xg8PUj+Xfu/t +vD/QV+tVcGoAMsQq4NeFxiTbPfwVyXdYFT1XVCu6JEdLL+gpWh5W +-----END RSA PRIVATE KEY----- diff --git a/test/test_fallback.data/nodefault.yml b/test/test_fallback.data/nodefault.yml new file mode 100644 index 0000000..ecd4359 --- /dev/null +++ b/test/test_fallback.data/nodefault.yml @@ -0,0 +1,36 @@ +services: + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./nodefault.certs:/etc/nginx/certs:ro + https-and-http: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: https-and-http.nginx-proxy.test + https-only: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: https-only.nginx-proxy.test + HTTPS_METHOD: nohttp + http-only: + image: web + expose: + - "83" + environment: + WEB_PORTS: "83" + VIRTUAL_HOST: http-only.nginx-proxy.test + HTTPS_METHOD: nohttps + missing-cert: + image: web + expose: + - "84" + environment: + WEB_PORTS: "84" + VIRTUAL_HOST: missing-cert.nginx-proxy.test diff --git a/test/test_fallback.py b/test/test_fallback.py index 1e687a3..cdaeef3 100644 --- a/test/test_fallback.py +++ b/test/test_fallback.py @@ -1,4 +1,5 @@ import os.path +import re import backoff import pytest @@ -31,6 +32,9 @@ def get(docker_compose, nginxproxy, want_err_re): return _get +INTERNAL_ERR_RE = re.compile("TLSV1_ALERT_INTERNAL_ERROR") + + @pytest.mark.parametrize("compose_file,url,want_code,want_err_re", [ # Has default.crt. ("withdefault.yml", "http://https-and-http.nginx-proxy.test/", 301, None), @@ -43,6 +47,17 @@ def get(docker_compose, nginxproxy, want_err_re): ("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), + # Same as withdefault.yml, except there is no default.crt. + ("nodefault.yml", "http://https-and-http.nginx-proxy.test/", 301, None), + ("nodefault.yml", "https://https-and-http.nginx-proxy.test/", 200, None), + ("nodefault.yml", "http://https-only.nginx-proxy.test/", 503, None), + ("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", "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), ]) def test_fallback(get, url, want_code, want_err_re): if want_err_re is None: From 9b4bb07b348dc5a428b94416517291adb30794c3 Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Sat, 4 Feb 2023 18:59:38 -0500 Subject: [PATCH 5/5] fix: Don't create fallback http(s) server when http(s) disabled Before, a fallback http server was created to handle requests for unknown virtual hosts even when `HTTPS_METHOD=nohttp`. (In this case, all http vhosts would be unknown.) Likewise, a catch-all fallback https server was still created even if `HTTPS_METHOD=nohttps`. Now the fallback servers are created only if needed. This brings the behavior in line with the documentation and user expectation. It will also make it easier to implement a planned feature: different servers on different ports. --- nginx.tmpl | 124 +++++++++++------- test/test_fallback.data/nohttp-on-app.yml | 16 +++ .../nohttp-with-missing-cert.yml | 22 ++++ test/test_fallback.data/nohttp.yml | 15 +++ test/test_fallback.data/nohttps-on-app.yml | 15 +++ test/test_fallback.data/nohttps.yml | 14 ++ test/test_fallback.py | 31 +++++ test/test_ssl/test_nohttp.py | 7 +- 8 files changed, 194 insertions(+), 50 deletions(-) create mode 100644 test/test_fallback.data/nohttp-on-app.yml create mode 100644 test/test_fallback.data/nohttp-with-missing-cert.yml create mode 100644 test/test_fallback.data/nohttp.yml create mode 100644 test/test_fallback.data/nohttps-on-app.yml create mode 100644 test/test_fallback.data/nohttps.yml diff --git a/nginx.tmpl b/nginx.tmpl index d2ccd8f..5733351 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -20,6 +20,7 @@ {{- $_ := set $globals "access_log" (or (and (not $globals.Env.DISABLE_ACCESS_LOGS) "access_log /var/log/nginx/access.log vhost;") "") }} {{- $_ := set $globals "enable_ipv6" (parseBool (coalesce $globals.Env.ENABLE_IPV6 "false")) }} {{- $_ := set $globals "ssl_policy" (or ($globals.Env.SSL_POLICY) "Mozilla-Intermediate") }} +{{- $_ := set $globals "vhosts" (dict) }} {{- $_ := set $globals "networks" (dict) }} # Networks available to the container running docker-gen (which are assumed to # match the networks available to the container running nginx): @@ -346,22 +347,80 @@ proxy_set_header X-Original-URI $request_uri; proxy_set_header Proxy ""; {{- end }} +{{- /* + * 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. + */}} +{{- range $vhost, $containers := groupByMulti $globals.containers "Env.VIRTUAL_HOST" "," }} + {{- $vhost := trim $vhost }} + {{- if not $vhost }} + {{- /* Ignore containers with VIRTUAL_HOST set to the empty string. */}} + {{- continue }} + {{- end }} + {{- $certName := first (groupByKeys $containers "Env.CERT_NAME") }} + {{- $vhostCert := closest (dir "/etc/nginx/certs") (printf "%s.crt" $vhost) }} + {{- $vhostCert = trimSuffix ".crt" $vhostCert }} + {{- $vhostCert = trimSuffix ".key" $vhostCert }} + {{- $cert := or $certName $vhostCert }} + {{- $cert_ok := and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert)) }} + {{- $default := eq $globals.Env.DEFAULT_HOST $vhost }} + {{- $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) $globals.Env.HTTPS_METHOD "redirect" }} + {{- $_ := set $globals.vhosts $vhost (dict "cert" $cert "cert_ok" $cert_ok "containers" $containers "default" $default "https_method" $https_method) }} +{{- end }} + +{{- /* + * If needed, create a catch-all fallback server to send an error code to + * clients that request something from an unknown vhost. + */}} +{{- block "fallback_server" $globals }} + {{- $globals := . }} + {{- $http_exists := false }} + {{- $https_exists := false }} + {{- $default_http_exists := false }} + {{- $default_https_exists := false }} + {{- range $vhost := $globals.vhosts }} + {{- $http := or (ne $vhost.https_method "nohttp") (not $vhost.cert_ok) }} + {{- $https := ne $vhost.https_method "nohttps" }} + {{- $http_exists = or $http_exists $http }} + {{- $https_exists = or $https_exists $https }} + {{- $default_http_exists = or $default_http_exists (and $http $vhost.default) }} + {{- $default_https_exists = or $default_https_exists (and $https $vhost.default) }} + {{- end }} + {{- $fallback_http := and $http_exists (not $default_http_exists) }} + {{- $fallback_https := and $https_exists (not $default_https_exists) }} + {{- /* + * If there are no vhosts at all, create fallbacks for both plain http + * and https so that clients get something more useful than a connection + * refused error. + */}} + {{- if and (not $http_exists) (not $https_exists) }} + {{- $fallback_http = true }} + {{- $fallback_https = true }} + {{- end }} + {{- if or $fallback_http $fallback_https }} server { server_name _; # This is just an invalid value which will never trigger on a real hostname. server_tokens off; - listen {{ $globals.external_http_port }}; - listen {{ $globals.external_https_port }} ssl http2; -{{- if $globals.enable_ipv6 }} - listen [::]:{{ $globals.external_http_port }}; - listen [::]:{{ $globals.external_https_port }} ssl http2; -{{- end }} + {{- if $fallback_http }} + listen {{ $globals.external_http_port }} default_server; + {{- if $globals.enable_ipv6 }} + listen [::]:{{ $globals.external_http_port }} default_server; + {{- end }} + {{- end }} + {{- if $fallback_https }} + listen {{ $globals.external_https_port }} ssl http2 default_server; + {{- if $globals.enable_ipv6 }} + listen [::]:{{ $globals.external_https_port }} ssl http2 default_server; + {{- end }} + {{- end }} {{ $globals.access_log }} -{{- if $globals.default_cert_ok }} + {{- if $globals.default_cert_ok }} ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_certificate /etc/nginx/certs/default.crt; ssl_certificate_key /etc/nginx/certs/default.key; -{{- else }} + {{- else }} # No default.crt certificate found for this vhost, so force nginx to emit a # TLS error if the client connects via https. {{- /* See the comment in the main `server` directive for rationale. */}} @@ -372,17 +431,19 @@ server { if ($https) { return 444; } -{{- end }} + {{- end }} return 503; } - -{{- range $host, $containers := groupByMulti $globals.containers "Env.VIRTUAL_HOST" "," }} - - {{- $host := trim $host }} - {{- if not $host }} - {{- /* Ignore containers with VIRTUAL_HOST set to the empty string. */}} - {{- continue }} {{- end }} +{{- end }} + +{{- range $host, $vhost := $globals.vhosts }} + {{- $cert := $vhost.cert }} + {{- $cert_ok := $vhost.cert_ok }} + {{- $containers := $vhost.containers }} + {{- $default_server := when $vhost.default "default_server" "" }} + {{- $https_method := $vhost.https_method }} + {{- $is_regexp := hasPrefix "~" $host }} {{- $upstream_name := when (or $is_regexp $globals.sha1_upstream_name) (sha1 $host) $host }} @@ -402,22 +463,12 @@ server { {{ template "upstream" (dict "globals" $globals "Upstream" $upstream "Containers" $containers) }} {{- end }} - {{- $default_host := or ($globals.Env.DEFAULT_HOST) "" }} - {{- $default_server := index (dict $host "" $default_host "default_server") $host }} - {{- /* * Get the SERVER_TOKENS defined by containers w/ the same vhost, * falling back to "". */}} {{- $server_tokens := trim (or (first (groupByKeys $containers "Env.SERVER_TOKENS")) "") }} - - {{- /* - * Get the HTTPS_METHOD defined by containers w/ the same vhost, falling - * back to "redirect". - */}} - {{- $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) (or $globals.Env.HTTPS_METHOD "redirect") }} - {{- /* * Get the SSL_POLICY defined by containers w/ the same vhost, falling * back to empty string (use default). @@ -433,27 +484,6 @@ server { {{- /* Get the VIRTUAL_ROOT By containers w/ use fastcgi root */}} {{- $vhost_root := or (first (groupByKeys $containers "Env.VIRTUAL_ROOT")) "/var/www/public" }} - - {{- /* Get the first cert name defined by containers w/ the same vhost */}} - {{- $certName := (first (groupByKeys $containers "Env.CERT_NAME")) }} - - {{- /* Get the best matching cert by name for the vhost. */}} - {{- $vhostCert := (closest (dir "/etc/nginx/certs") (printf "%s.crt" $host))}} - - {{- /* - * vhostCert is actually a filename so remove any suffixes since they - * are added later. - */}} - {{- $vhostCert := trimSuffix ".crt" $vhostCert }} - {{- $vhostCert := trimSuffix ".key" $vhostCert }} - - {{- /* - * Use the cert specified on the container or fallback to the best vhost - * match. - */}} - {{- $cert := (coalesce $certName $vhostCert) }} - {{- $cert_ok := and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert)) }} - {{- if and $cert_ok (eq $https_method "redirect") }} server { server_name {{ $host }}; diff --git a/test/test_fallback.data/nohttp-on-app.yml b/test/test_fallback.data/nohttp-on-app.yml new file mode 100644 index 0000000..d81c9ca --- /dev/null +++ b/test/test_fallback.data/nohttp-on-app.yml @@ -0,0 +1,16 @@ +services: + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./withdefault.certs:/etc/nginx/certs:ro + environment: + HTTPS_METHOD: redirect + https-only: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + HTTPS_METHOD: nohttp + VIRTUAL_HOST: https-only.nginx-proxy.test diff --git a/test/test_fallback.data/nohttp-with-missing-cert.yml b/test/test_fallback.data/nohttp-with-missing-cert.yml new file mode 100644 index 0000000..3593a32 --- /dev/null +++ b/test/test_fallback.data/nohttp-with-missing-cert.yml @@ -0,0 +1,22 @@ +services: + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./withdefault.certs:/etc/nginx/certs:ro + environment: + HTTPS_METHOD: nohttp + https-only: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: https-only.nginx-proxy.test + missing-cert: + image: web + expose: + - "84" + environment: + WEB_PORTS: "84" + VIRTUAL_HOST: missing-cert.nginx-proxy.test diff --git a/test/test_fallback.data/nohttp.yml b/test/test_fallback.data/nohttp.yml new file mode 100644 index 0000000..3ed0c0e --- /dev/null +++ b/test/test_fallback.data/nohttp.yml @@ -0,0 +1,15 @@ +services: + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./withdefault.certs:/etc/nginx/certs:ro + environment: + HTTPS_METHOD: nohttp + https-only: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST: https-only.nginx-proxy.test diff --git a/test/test_fallback.data/nohttps-on-app.yml b/test/test_fallback.data/nohttps-on-app.yml new file mode 100644 index 0000000..690d656 --- /dev/null +++ b/test/test_fallback.data/nohttps-on-app.yml @@ -0,0 +1,15 @@ +services: + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + environment: + HTTPS_METHOD: redirect + http-only: + image: web + expose: + - "83" + environment: + WEB_PORTS: "83" + HTTPS_METHOD: nohttps + VIRTUAL_HOST: http-only.nginx-proxy.test diff --git a/test/test_fallback.data/nohttps.yml b/test/test_fallback.data/nohttps.yml new file mode 100644 index 0000000..f07ddf9 --- /dev/null +++ b/test/test_fallback.data/nohttps.yml @@ -0,0 +1,14 @@ +services: + sut: + image: nginxproxy/nginx-proxy:test + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + environment: + HTTPS_METHOD: nohttps + http-only: + image: web + expose: + - "83" + environment: + WEB_PORTS: "83" + VIRTUAL_HOST: http-only.nginx-proxy.test diff --git a/test/test_fallback.py b/test/test_fallback.py index cdaeef3..ce3d68f 100644 --- a/test/test_fallback.py +++ b/test/test_fallback.py @@ -33,6 +33,7 @@ def get(docker_compose, nginxproxy, want_err_re): INTERNAL_ERR_RE = re.compile("TLSV1_ALERT_INTERNAL_ERROR") +CONNECTION_REFUSED_RE = re.compile("Connection refused") @pytest.mark.parametrize("compose_file,url,want_code,want_err_re", [ @@ -58,6 +59,36 @@ INTERNAL_ERR_RE = re.compile("TLSV1_ALERT_INTERNAL_ERROR") ("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), + # HTTPS_METHOD=nohttp on nginx-proxy, HTTPS_METHOD unset on the app container. + ("nohttp.yml", "http://https-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE), + ("nohttp.yml", "https://https-only.nginx-proxy.test/", 200, None), + ("nohttp.yml", "http://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE), + ("nohttp.yml", "https://unknown.nginx-proxy.test/", 503, None), + # HTTPS_METHOD=redirect on nginx-proxy, HTTPS_METHOD=nohttp on the app container. + ("nohttp-on-app.yml", "http://https-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE), + ("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), + ("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", "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", "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), + ("nohttps.yml", "https://http-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE), + ("nohttps.yml", "http://unknown.nginx-proxy.test/", 503, None), + ("nohttps.yml", "https://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE), + # HTTPS_METHOD=redirect on nginx-proxy, HTTPS_METHOD=nohttps on the app container. + ("nohttps-on-app.yml", "http://http-only.nginx-proxy.test/", 200, None), + ("nohttps-on-app.yml", "https://http-only.nginx-proxy.test/", None, CONNECTION_REFUSED_RE), + ("nohttps-on-app.yml", "http://unknown.nginx-proxy.test/", 503, None), + ("nohttps-on-app.yml", "https://unknown.nginx-proxy.test/", None, CONNECTION_REFUSED_RE), ]) def test_fallback(get, url, want_code, want_err_re): if want_err_re is None: diff --git a/test/test_ssl/test_nohttp.py b/test/test_ssl/test_nohttp.py index d7f0d92..5b650db 100644 --- a/test/test_ssl/test_nohttp.py +++ b/test/test_ssl/test_nohttp.py @@ -1,9 +1,10 @@ import pytest +import requests -def test_web2_http_is_not_forwarded(docker_compose, nginxproxy): - r = nginxproxy.get("http://web2.nginx-proxy.tld/", allow_redirects=False) - assert r.status_code == 503 +def test_web2_http_is_connection_refused(docker_compose, nginxproxy): + with pytest.raises(requests.exceptions.RequestException, match="Connection refused"): + nginxproxy.get("http://web2.nginx-proxy.tld/") def test_web2_https_is_forwarded(docker_compose, nginxproxy):