From 409b0e6fbb682a28ed49165ec5b085d45f0f81cd Mon Sep 17 00:00:00 2001 From: Niek <100143256+SchoNie@users.noreply.github.com> Date: Thu, 27 Feb 2025 13:20:45 +0100 Subject: [PATCH 1/5] feat: SSL client certificate validation --- nginx.tmpl | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/nginx.tmpl b/nginx.tmpl index fa23bd4..6dbea62 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -759,6 +759,9 @@ proxy_set_header Proxy ""; {{- /* Get the SSL_POLICY defined by containers w/ the same vhost, falling back to empty string (use default). */}} {{- $ssl_policy := groupByKeys $vhost_containers "Env.SSL_POLICY" | first | default "" }} + {{- /* Get ssl_verify_client defined by containers w/ the same vhost, falling back to "on" */}} + {{- $ssl_verify_client := groupByLabel $vhost_containers "com.github.nginx-proxy.nginx-proxy.ssl_verify_client" | keys | first | default "on" }} + {{- /* Get the HSTS defined by containers w/ the same vhost, falling back to "max-age=31536000". */}} {{- $hsts := groupByKeys $vhost_containers "Env.HSTS" | first | default $globals.config.hsts }} @@ -780,6 +783,7 @@ proxy_set_header Proxy ""; "acme_http_challenge_enabled" $acme_http_challenge_enabled "server_tokens" $server_tokens "ssl_policy" $ssl_policy + "ssl_verify_client" $ssl_verify_client "trust_default_cert" $trust_default_cert "upstream_name" $upstream_name "vhost_root" $vhost_root @@ -1038,6 +1042,25 @@ server { include /etc/nginx/vhost.d/default; {{- end }} + {{/* SSL Client Certificate Validation */}} + {{/* If vhost(hash).ca.crt exists, include CA */}} + {{- if (exists (printf "/etc/nginx/certs/%s.ca.crt" $vhostFileName)) }} + ssl_client_certificate {{ printf "/etc/nginx/certs/%s.ca.crt" $vhostFileName }}; + ssl_verify_client {{ $vhost.ssl_verify_client }}; + {{/* If vhost(hash).crl.pem exists, include CRL */}} + {{- if (exists (printf "/etc/nginx/certs/%s.crl.pem" $vhostFileName)) }} + ssl_crl {{ printf "/etc/nginx/certs/%s.crl.pem" $vhostFileName }}; + {{ end }} + {{/* If no vhost CA file exists, but a global ca.crt exists include it */}} + {{ else if (exists "/etc/nginx/certs/ca.crt") }} + ssl_client_certificate /etc/nginx/certs/ca.crt; + ssl_verify_client {{ $vhost.ssl_verify_client }}; + {{/* If no vhost CA file exists, but a global ca.crl.pem exists include it */}} + {{ if (exists "/etc/nginx/certs/ca.crl.pem")}} + ssl_crl /etc/nginx/certs/ca.crl.pem; + {{ end }} + {{ end }} + {{- if $vhost.enable_debug_endpoint }} {{ template "debug_location" (dict "GlobalConfig" $globals.config "Hostname" $hostname "VHost" $vhost) }} {{- end }} From 5e77e2910b93b248eedb842690008300210ffd99 Mon Sep 17 00:00:00 2001 From: Niek <100143256+SchoNie@users.noreply.github.com> Date: Thu, 27 Feb 2025 13:22:03 +0100 Subject: [PATCH 2/5] tests: SSL client certificate validation mTLS --- ...1b655182b052fed458ec701f9ae1524e1c2.ca.crt | 21 +++++ ...b655182b052fed458ec701f9ae1524e1c2.crl.pem | 13 +++ test/test_ssl/certs_mtls/ca.crl.pem | 13 +++ test/test_ssl/certs_mtls/ca.crt | 21 +++++ .../mtls-enabled.nginx-proxy.tld.ca.crt | 21 +++++ .../mtls-enabled.nginx-proxy.tld.crl.pem | 13 +++ .../certs_mtls/mtls-optional-foo-bar_location | 4 + .../mtls-optional.nginx-proxy.tld.ca.crt | 21 +++++ test/test_ssl/certs_mtls/nginx-proxy.tld.crt | 70 +++++++++++++++ test/test_ssl/certs_mtls/nginx-proxy.tld.key | 27 ++++++ test/test_ssl/clientcerts/Revoked.crt | 85 +++++++++++++++++++ test/test_ssl/clientcerts/Revoked.key | 28 ++++++ test/test_ssl/clientcerts/Valid.crt | 85 +++++++++++++++++++ test/test_ssl/clientcerts/Valid.key | 28 ++++++ test/test_ssl/test_mtls-client-certificate.py | 59 +++++++++++++ .../test_ssl/test_mtls-client-certificate.yml | 69 +++++++++++++++ 16 files changed, 578 insertions(+) create mode 100644 test/test_ssl/certs_mtls/9ae5d1b655182b052fed458ec701f9ae1524e1c2.ca.crt create mode 100644 test/test_ssl/certs_mtls/9ae5d1b655182b052fed458ec701f9ae1524e1c2.crl.pem create mode 100644 test/test_ssl/certs_mtls/ca.crl.pem create mode 100644 test/test_ssl/certs_mtls/ca.crt create mode 100644 test/test_ssl/certs_mtls/mtls-enabled.nginx-proxy.tld.ca.crt create mode 100644 test/test_ssl/certs_mtls/mtls-enabled.nginx-proxy.tld.crl.pem create mode 100644 test/test_ssl/certs_mtls/mtls-optional-foo-bar_location create mode 100644 test/test_ssl/certs_mtls/mtls-optional.nginx-proxy.tld.ca.crt create mode 100644 test/test_ssl/certs_mtls/nginx-proxy.tld.crt create mode 100644 test/test_ssl/certs_mtls/nginx-proxy.tld.key create mode 100644 test/test_ssl/clientcerts/Revoked.crt create mode 100644 test/test_ssl/clientcerts/Revoked.key create mode 100644 test/test_ssl/clientcerts/Valid.crt create mode 100644 test/test_ssl/clientcerts/Valid.key create mode 100644 test/test_ssl/test_mtls-client-certificate.py create mode 100644 test/test_ssl/test_mtls-client-certificate.yml diff --git a/test/test_ssl/certs_mtls/9ae5d1b655182b052fed458ec701f9ae1524e1c2.ca.crt b/test/test_ssl/certs_mtls/9ae5d1b655182b052fed458ec701f9ae1524e1c2.ca.crt new file mode 100644 index 0000000..e3d27c5 --- /dev/null +++ b/test/test_ssl/certs_mtls/9ae5d1b655182b052fed458ec701f9ae1524e1c2.ca.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIUNvSKwCRCnOATsXaluKSE3RI6fy0wDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWbmdpbngtcHJveHktdGVzdC1zdWl0ZTAeFw0yNTAxMDMx +MjE0NTdaFw0zNTAxMDExMjE0NTdaMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRl +c3Qtc3VpdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCb78gTRxTy +6NrnApjBZ9Gjuj+0FcqE6ARpYBcQU+F/yokyNhE0SR4AyQaGtymDkqPcrfdDVd4b +ylz3wsbJ5jCjHyPFOQ+6trVZ6eKfQ+VoMTlTCj+ystKAba85bWdXriLdMNoqZdkY +jT6ryHUQ/mmeVdhUKBtCrqayiYNbjGTkhCwH2h2jYBdK5ngZ5mc1Z+4NGCUi14aY +AHU+nwSae/y6OU2gcYhr4NuFtwxLfxXXj2vgdTMcqoeu08u6kEjY0g7A7dzMEJ0r +VGB6+aMVK22KklPLn2IgZ/w4TC/kq/DhyWivL4HYjsKbmA6O9tM6xQqpxUwIyo+y +CdTbtv5uSX3jAgMBAAGjgZswgZgwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQU9X5P +1mF9ZBIYOSikqH40bUmpgRYwXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmp +gRahJaQjMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAk +QpzgE7F2pbikhN0SOn8tMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA +kE32r6zEm6ntNRVdu3wYR6oSkk7wQr1m2YmVQjb4LIdSL3nP8VJ9PhBxUpLV03tX +evUqrAiMRL6luwFaTSb3mDxm4RGfWUzd0OVjS5NMki7Tr2RXwCCxvKApYcoJ8pwP +dNsqAmhxEwhQXIx3lG8EAxiSXe26S9JU6ILVDgdnYgfr/S9k99OjtUQOS88XiKuL +fwV7n/xSAQDiczGjwWpJLdZiKgic5VFtKOVHHMo5BIX30SJSd//BjZ5Z3N++FhLg +RzwEjbnVxxOkyz30N8VD5M7I5XwTa+VVTj5Cqoj+ImBy+/IsqjqIX8KIjl2AoJER ++2EdFJ1a5odHU3olzbuRcA== +-----END CERTIFICATE----- diff --git a/test/test_ssl/certs_mtls/9ae5d1b655182b052fed458ec701f9ae1524e1c2.crl.pem b/test/test_ssl/certs_mtls/9ae5d1b655182b052fed458ec701f9ae1524e1c2.crl.pem new file mode 100644 index 0000000..a4bbd95 --- /dev/null +++ b/test/test_ssl/certs_mtls/9ae5d1b655182b052fed458ec701f9ae1524e1c2.crl.pem @@ -0,0 +1,13 @@ +-----BEGIN X509 CRL----- +MIICADCB6QIBATANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDDBZuZ2lueC1wcm94 +eS10ZXN0LXN1aXRlFw0yNTAxMDMxMjMwNTBaFw0yNTA3MDIxMjMwNTBaMDIwMAIR +AK8a1AmezG56vTp5WqtpnScXDTI1MDEwMzEyMzAwN1owDDAKBgNVHRUEAwoBBaBg +MF4wXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmpgRahJaQjMCExHzAdBgNV +BAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAkQpzgE7F2pbikhN0SOn8t +MA0GCSqGSIb3DQEBCwUAA4IBAQCGaKW8kJy1Mznc3T2OHkCx8GudvOo0ZBsZ+pTm +sAnlxDQTIqm8e4gU19WF/SISlfr7qEERqif8+SlUgS9CWtJa70gk+9oobuWfBNIT +VXD4ujO/47nqt2MdRUSSGX+K+9Ox2gyU6kHO1ZrT8VmsL22Bhfa2Pw/3OBL/QHMU +b1hAZyed0CoPCnMqjG0X5zMo3ByGW3TkxG2GhzKCWLGXVbzdHFpS98hpkpaxvIlE +juSYuPItwEftHdB8JHAHL18uDJapZ5mOCuUn/HoZBWOudFjtFQUUzq4eTsB56My4 +qDGb1/ReAoGyheuV0fEtg9MJkGEuGrb38JN6hcdfpW5u0Hwb +-----END X509 CRL----- diff --git a/test/test_ssl/certs_mtls/ca.crl.pem b/test/test_ssl/certs_mtls/ca.crl.pem new file mode 100644 index 0000000..a4bbd95 --- /dev/null +++ b/test/test_ssl/certs_mtls/ca.crl.pem @@ -0,0 +1,13 @@ +-----BEGIN X509 CRL----- +MIICADCB6QIBATANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDDBZuZ2lueC1wcm94 +eS10ZXN0LXN1aXRlFw0yNTAxMDMxMjMwNTBaFw0yNTA3MDIxMjMwNTBaMDIwMAIR +AK8a1AmezG56vTp5WqtpnScXDTI1MDEwMzEyMzAwN1owDDAKBgNVHRUEAwoBBaBg +MF4wXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmpgRahJaQjMCExHzAdBgNV +BAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAkQpzgE7F2pbikhN0SOn8t +MA0GCSqGSIb3DQEBCwUAA4IBAQCGaKW8kJy1Mznc3T2OHkCx8GudvOo0ZBsZ+pTm +sAnlxDQTIqm8e4gU19WF/SISlfr7qEERqif8+SlUgS9CWtJa70gk+9oobuWfBNIT +VXD4ujO/47nqt2MdRUSSGX+K+9Ox2gyU6kHO1ZrT8VmsL22Bhfa2Pw/3OBL/QHMU +b1hAZyed0CoPCnMqjG0X5zMo3ByGW3TkxG2GhzKCWLGXVbzdHFpS98hpkpaxvIlE +juSYuPItwEftHdB8JHAHL18uDJapZ5mOCuUn/HoZBWOudFjtFQUUzq4eTsB56My4 +qDGb1/ReAoGyheuV0fEtg9MJkGEuGrb38JN6hcdfpW5u0Hwb +-----END X509 CRL----- diff --git a/test/test_ssl/certs_mtls/ca.crt b/test/test_ssl/certs_mtls/ca.crt new file mode 100644 index 0000000..e3d27c5 --- /dev/null +++ b/test/test_ssl/certs_mtls/ca.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIUNvSKwCRCnOATsXaluKSE3RI6fy0wDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWbmdpbngtcHJveHktdGVzdC1zdWl0ZTAeFw0yNTAxMDMx +MjE0NTdaFw0zNTAxMDExMjE0NTdaMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRl +c3Qtc3VpdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCb78gTRxTy +6NrnApjBZ9Gjuj+0FcqE6ARpYBcQU+F/yokyNhE0SR4AyQaGtymDkqPcrfdDVd4b +ylz3wsbJ5jCjHyPFOQ+6trVZ6eKfQ+VoMTlTCj+ystKAba85bWdXriLdMNoqZdkY +jT6ryHUQ/mmeVdhUKBtCrqayiYNbjGTkhCwH2h2jYBdK5ngZ5mc1Z+4NGCUi14aY +AHU+nwSae/y6OU2gcYhr4NuFtwxLfxXXj2vgdTMcqoeu08u6kEjY0g7A7dzMEJ0r +VGB6+aMVK22KklPLn2IgZ/w4TC/kq/DhyWivL4HYjsKbmA6O9tM6xQqpxUwIyo+y +CdTbtv5uSX3jAgMBAAGjgZswgZgwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQU9X5P +1mF9ZBIYOSikqH40bUmpgRYwXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmp +gRahJaQjMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAk +QpzgE7F2pbikhN0SOn8tMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA +kE32r6zEm6ntNRVdu3wYR6oSkk7wQr1m2YmVQjb4LIdSL3nP8VJ9PhBxUpLV03tX +evUqrAiMRL6luwFaTSb3mDxm4RGfWUzd0OVjS5NMki7Tr2RXwCCxvKApYcoJ8pwP +dNsqAmhxEwhQXIx3lG8EAxiSXe26S9JU6ILVDgdnYgfr/S9k99OjtUQOS88XiKuL +fwV7n/xSAQDiczGjwWpJLdZiKgic5VFtKOVHHMo5BIX30SJSd//BjZ5Z3N++FhLg +RzwEjbnVxxOkyz30N8VD5M7I5XwTa+VVTj5Cqoj+ImBy+/IsqjqIX8KIjl2AoJER ++2EdFJ1a5odHU3olzbuRcA== +-----END CERTIFICATE----- diff --git a/test/test_ssl/certs_mtls/mtls-enabled.nginx-proxy.tld.ca.crt b/test/test_ssl/certs_mtls/mtls-enabled.nginx-proxy.tld.ca.crt new file mode 100644 index 0000000..e3d27c5 --- /dev/null +++ b/test/test_ssl/certs_mtls/mtls-enabled.nginx-proxy.tld.ca.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIUNvSKwCRCnOATsXaluKSE3RI6fy0wDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWbmdpbngtcHJveHktdGVzdC1zdWl0ZTAeFw0yNTAxMDMx +MjE0NTdaFw0zNTAxMDExMjE0NTdaMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRl +c3Qtc3VpdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCb78gTRxTy +6NrnApjBZ9Gjuj+0FcqE6ARpYBcQU+F/yokyNhE0SR4AyQaGtymDkqPcrfdDVd4b +ylz3wsbJ5jCjHyPFOQ+6trVZ6eKfQ+VoMTlTCj+ystKAba85bWdXriLdMNoqZdkY +jT6ryHUQ/mmeVdhUKBtCrqayiYNbjGTkhCwH2h2jYBdK5ngZ5mc1Z+4NGCUi14aY +AHU+nwSae/y6OU2gcYhr4NuFtwxLfxXXj2vgdTMcqoeu08u6kEjY0g7A7dzMEJ0r +VGB6+aMVK22KklPLn2IgZ/w4TC/kq/DhyWivL4HYjsKbmA6O9tM6xQqpxUwIyo+y +CdTbtv5uSX3jAgMBAAGjgZswgZgwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQU9X5P +1mF9ZBIYOSikqH40bUmpgRYwXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmp +gRahJaQjMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAk +QpzgE7F2pbikhN0SOn8tMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA +kE32r6zEm6ntNRVdu3wYR6oSkk7wQr1m2YmVQjb4LIdSL3nP8VJ9PhBxUpLV03tX +evUqrAiMRL6luwFaTSb3mDxm4RGfWUzd0OVjS5NMki7Tr2RXwCCxvKApYcoJ8pwP +dNsqAmhxEwhQXIx3lG8EAxiSXe26S9JU6ILVDgdnYgfr/S9k99OjtUQOS88XiKuL +fwV7n/xSAQDiczGjwWpJLdZiKgic5VFtKOVHHMo5BIX30SJSd//BjZ5Z3N++FhLg +RzwEjbnVxxOkyz30N8VD5M7I5XwTa+VVTj5Cqoj+ImBy+/IsqjqIX8KIjl2AoJER ++2EdFJ1a5odHU3olzbuRcA== +-----END CERTIFICATE----- diff --git a/test/test_ssl/certs_mtls/mtls-enabled.nginx-proxy.tld.crl.pem b/test/test_ssl/certs_mtls/mtls-enabled.nginx-proxy.tld.crl.pem new file mode 100644 index 0000000..a4bbd95 --- /dev/null +++ b/test/test_ssl/certs_mtls/mtls-enabled.nginx-proxy.tld.crl.pem @@ -0,0 +1,13 @@ +-----BEGIN X509 CRL----- +MIICADCB6QIBATANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDDBZuZ2lueC1wcm94 +eS10ZXN0LXN1aXRlFw0yNTAxMDMxMjMwNTBaFw0yNTA3MDIxMjMwNTBaMDIwMAIR +AK8a1AmezG56vTp5WqtpnScXDTI1MDEwMzEyMzAwN1owDDAKBgNVHRUEAwoBBaBg +MF4wXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmpgRahJaQjMCExHzAdBgNV +BAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAkQpzgE7F2pbikhN0SOn8t +MA0GCSqGSIb3DQEBCwUAA4IBAQCGaKW8kJy1Mznc3T2OHkCx8GudvOo0ZBsZ+pTm +sAnlxDQTIqm8e4gU19WF/SISlfr7qEERqif8+SlUgS9CWtJa70gk+9oobuWfBNIT +VXD4ujO/47nqt2MdRUSSGX+K+9Ox2gyU6kHO1ZrT8VmsL22Bhfa2Pw/3OBL/QHMU +b1hAZyed0CoPCnMqjG0X5zMo3ByGW3TkxG2GhzKCWLGXVbzdHFpS98hpkpaxvIlE +juSYuPItwEftHdB8JHAHL18uDJapZ5mOCuUn/HoZBWOudFjtFQUUzq4eTsB56My4 +qDGb1/ReAoGyheuV0fEtg9MJkGEuGrb38JN6hcdfpW5u0Hwb +-----END X509 CRL----- diff --git a/test/test_ssl/certs_mtls/mtls-optional-foo-bar_location b/test/test_ssl/certs_mtls/mtls-optional-foo-bar_location new file mode 100644 index 0000000..285a3bd --- /dev/null +++ b/test/test_ssl/certs_mtls/mtls-optional-foo-bar_location @@ -0,0 +1,4 @@ +if ($ssl_client_verify = SUCCESS) { + add_header Content-Type text/plain; + return 418 'ssl_client_verify is SUCCESS'; +} diff --git a/test/test_ssl/certs_mtls/mtls-optional.nginx-proxy.tld.ca.crt b/test/test_ssl/certs_mtls/mtls-optional.nginx-proxy.tld.ca.crt new file mode 100644 index 0000000..e3d27c5 --- /dev/null +++ b/test/test_ssl/certs_mtls/mtls-optional.nginx-proxy.tld.ca.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIUNvSKwCRCnOATsXaluKSE3RI6fy0wDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWbmdpbngtcHJveHktdGVzdC1zdWl0ZTAeFw0yNTAxMDMx +MjE0NTdaFw0zNTAxMDExMjE0NTdaMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRl +c3Qtc3VpdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCb78gTRxTy +6NrnApjBZ9Gjuj+0FcqE6ARpYBcQU+F/yokyNhE0SR4AyQaGtymDkqPcrfdDVd4b +ylz3wsbJ5jCjHyPFOQ+6trVZ6eKfQ+VoMTlTCj+ystKAba85bWdXriLdMNoqZdkY +jT6ryHUQ/mmeVdhUKBtCrqayiYNbjGTkhCwH2h2jYBdK5ngZ5mc1Z+4NGCUi14aY +AHU+nwSae/y6OU2gcYhr4NuFtwxLfxXXj2vgdTMcqoeu08u6kEjY0g7A7dzMEJ0r +VGB6+aMVK22KklPLn2IgZ/w4TC/kq/DhyWivL4HYjsKbmA6O9tM6xQqpxUwIyo+y +CdTbtv5uSX3jAgMBAAGjgZswgZgwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQU9X5P +1mF9ZBIYOSikqH40bUmpgRYwXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmp +gRahJaQjMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAk +QpzgE7F2pbikhN0SOn8tMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA +kE32r6zEm6ntNRVdu3wYR6oSkk7wQr1m2YmVQjb4LIdSL3nP8VJ9PhBxUpLV03tX +evUqrAiMRL6luwFaTSb3mDxm4RGfWUzd0OVjS5NMki7Tr2RXwCCxvKApYcoJ8pwP +dNsqAmhxEwhQXIx3lG8EAxiSXe26S9JU6ILVDgdnYgfr/S9k99OjtUQOS88XiKuL +fwV7n/xSAQDiczGjwWpJLdZiKgic5VFtKOVHHMo5BIX30SJSd//BjZ5Z3N++FhLg +RzwEjbnVxxOkyz30N8VD5M7I5XwTa+VVTj5Cqoj+ImBy+/IsqjqIX8KIjl2AoJER ++2EdFJ1a5odHU3olzbuRcA== +-----END CERTIFICATE----- diff --git a/test/test_ssl/certs_mtls/nginx-proxy.tld.crt b/test/test_ssl/certs_mtls/nginx-proxy.tld.crt new file mode 100644 index 0000000..cd7284b --- /dev/null +++ b/test/test_ssl/certs_mtls/nginx-proxy.tld.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: Jan 10 00:08:52 2017 GMT + Not After : May 28 00:08:52 2044 GMT + Subject: CN=*.nginx-proxy.tld + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:cb:45:f4:14:9b:fe:64:85:79:4a:36:8d:3d:d1: + 27:d0:7c:36:28:30:e6:73:80:6f:7c:49:23:d0:6c: + 17:e4:44:c0:77:4d:9a:c2:bc:24:84:e3:a5:4d:ba: + d2:da:51:7b:a1:2a:12:d4:c0:19:55:69:2c:22:27: + 2d:1a:f6:fc:4b:7f:e9:cb:a8:3c:e8:69:b8:d2:4f: + de:4e:50:e2:d0:74:30:7c:42:5a:ae:aa:85:a5:b1: + 71:4d:c9:7e:86:8b:62:8c:3e:0d:e3:3b:c3:f5:81: + 0b:8c:68:79:fe:bf:10:fb:ae:ec:11:49:6d:64:5e: + 1a:7d:b3:92:93:4e:96:19:3a:98:04:a7:66:b2:74: + 61:2d:41:13:0c:a4:54:0d:2c:78:fd:b4:a3:e8:37: + 78:9a:de:fa:bc:2e:a8:0f:67:14:58:ce:c3:87:d5: + 14:0e:8b:29:7d:48:19:b2:a9:f5:b4:e8:af:32:21: + 67:15:7e:43:52:8b:20:cf:9f:38:43:bf:fd:c8:24: + 7f:52:a3:88:f2:f1:4a:14:91:2a:6e:91:6f:fb:7d: + 6a:78:c6:6d:2e:dd:1e:4c:2b:63:bb:3a:43:9c:91: + f9:df:d3:08:13:63:86:7d:ce:e8:46:cf:f1:6c:1f: + ca:f7:4c:de:d8:4b:e0:da:bc:06:d9:87:0f:ff:96: + 45:85 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:*.nginx-proxy.tld + Signature Algorithm: sha256WithRSAEncryption + 6e:a5:0e:e4:d3:cc:d5:b7:fc:34:75:89:4e:98:8c:e7:08:06: + a8:5b:ec:13:7d:83:99:a2:61:b8:d5:12:6e:c5:b4:53:4e:9a: + 22:cd:ad:14:30:6a:7d:58:d7:23:d9:a4:2a:96:a0:40:9e:50: + 9f:ce:f2:fe:8c:dd:9a:ac:99:39:5b:89:2d:ca:e5:3e:c3:bc: + 03:04:1c:12:d9:6e:b8:9f:f0:3a:be:12:44:7e:a4:21:86:73: + af:d5:00:51:3f:2c:56:70:34:8f:26:b0:7f:b0:cf:cf:7f:f9: + 40:6f:00:29:c4:cf:c3:b7:c2:49:3d:3f:b0:26:78:87:b9:c7: + 6c:1b:aa:6a:1a:dd:c5:eb:f2:69:ba:6d:46:0b:92:49:b5:11: + 3c:eb:48:c7:2f:fb:33:a6:6a:82:a2:ab:f8:1e:5f:7d:e3:b7: + f2:fd:f5:88:a5:09:4d:a0:bc:f4:3b:cd:d2:8b:d7:57:1f:86: + 3b:d2:3e:a4:92:21:b0:02:0b:e9:e0:c4:1c:f1:78:e2:58:a7: + 26:5f:4c:29:c8:23:f0:6e:12:3f:bd:ad:44:7b:0b:bd:db:ba: + 63:8d:07:c6:9d:dc:46:cc:63:40:ba:5e:45:82:dd:9a:e5:50: + e8:e7:d7:27:88:fc:6f:1d:8a:e7:5c:49:28:aa:10:29:75:28: + c7:52:de:f9 +-----BEGIN CERTIFICATE----- +MIIC9zCCAd+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzEfMB0GA1UECgwWbmdp +bngtcHJveHkgdGVzdCBzdWl0ZTEcMBoGA1UEAwwTd3d3Lm5naW54LXByb3h5LnRs +ZDAeFw0xNzAxMTAwMDA4NTJaFw00NDA1MjgwMDA4NTJaMBwxGjAYBgNVBAMMESou +bmdpbngtcHJveHkudGxkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +y0X0FJv+ZIV5SjaNPdEn0Hw2KDDmc4BvfEkj0GwX5ETAd02awrwkhOOlTbrS2lF7 +oSoS1MAZVWksIictGvb8S3/py6g86Gm40k/eTlDi0HQwfEJarqqFpbFxTcl+hoti +jD4N4zvD9YELjGh5/r8Q+67sEUltZF4afbOSk06WGTqYBKdmsnRhLUETDKRUDSx4 +/bSj6Dd4mt76vC6oD2cUWM7Dh9UUDospfUgZsqn1tOivMiFnFX5DUosgz584Q7/9 +yCR/UqOI8vFKFJEqbpFv+31qeMZtLt0eTCtjuzpDnJH539MIE2OGfc7oRs/xbB/K +90ze2Evg2rwG2YcP/5ZFhQIDAQABoyAwHjAcBgNVHREEFTATghEqLm5naW54LXBy +b3h5LnRsZDANBgkqhkiG9w0BAQsFAAOCAQEAbqUO5NPM1bf8NHWJTpiM5wgGqFvs +E32DmaJhuNUSbsW0U06aIs2tFDBqfVjXI9mkKpagQJ5Qn87y/ozdmqyZOVuJLcrl +PsO8AwQcEtluuJ/wOr4SRH6kIYZzr9UAUT8sVnA0jyawf7DPz3/5QG8AKcTPw7fC +ST0/sCZ4h7nHbBuqahrdxevyabptRguSSbURPOtIxy/7M6ZqgqKr+B5ffeO38v31 +iKUJTaC89DvN0ovXVx+GO9I+pJIhsAIL6eDEHPF44linJl9MKcgj8G4SP72tRHsL +vdu6Y40Hxp3cRsxjQLpeRYLdmuVQ6OfXJ4j8bx2K51xJKKoQKXUox1Le+Q== +-----END CERTIFICATE----- diff --git a/test/test_ssl/certs_mtls/nginx-proxy.tld.key b/test/test_ssl/certs_mtls/nginx-proxy.tld.key new file mode 100644 index 0000000..91adb14 --- /dev/null +++ b/test/test_ssl/certs_mtls/nginx-proxy.tld.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAy0X0FJv+ZIV5SjaNPdEn0Hw2KDDmc4BvfEkj0GwX5ETAd02a +wrwkhOOlTbrS2lF7oSoS1MAZVWksIictGvb8S3/py6g86Gm40k/eTlDi0HQwfEJa +rqqFpbFxTcl+hotijD4N4zvD9YELjGh5/r8Q+67sEUltZF4afbOSk06WGTqYBKdm +snRhLUETDKRUDSx4/bSj6Dd4mt76vC6oD2cUWM7Dh9UUDospfUgZsqn1tOivMiFn +FX5DUosgz584Q7/9yCR/UqOI8vFKFJEqbpFv+31qeMZtLt0eTCtjuzpDnJH539MI +E2OGfc7oRs/xbB/K90ze2Evg2rwG2YcP/5ZFhQIDAQABAoIBAQCjAro2PNLJMfCO +fyjNRgmzu6iCmpR0U68T8GN0JPsT576g7e8J828l0pkhuIyW33lRSThIvLSUNf9a +dChL032H3lBTLduKVh4NKleQXnVFzaeEPoISSFVdButiAhAhPW4OIUVp0OfY3V+x +fac3j2nDLAfL5SKAtqZv363Py9m66EBYm5BmGTQqT/frQWeCEBvlErQef5RIaU8p +e2zMWgSNNojVai8U3nKNRvYHWeWXM6Ck7lCvkHhMF+RpbmCZuqhbEARVnehU/Jdn +QHJ3nxeA2OWpoWKXvAHtSnno49yxq1UIstiQvY+ng5C5i56UlB60UiU2NJ6doZkB +uQ7/1MaBAoGBAORdcFtgdgRALjXngFWhpCp0CseyUehn1KhxDCG+D1pJ142/ymcf +oJOzKJPMRNDdDUBMnR1GBfy7rmwvYevI/SMNy2Qs7ofcXPbdtwwvTCToZ1V9/54k +VfuPBFT+3QzWRvG1tjTV3E4L2VV3nrl2qNPhE5DlfIaU3nQq5Fl0HprJAoGBAOPf +MWOTGev61CdODO5KN3pLAoamiPs5lEUlz3kM3L1Q52YLITxNDjRj9hWBUATJZOS2 +pLOoYRwmhD7vrnimMc41+NuuFX+4T7hWPc8uSuOxX0VijYtULyNRK57mncG1Fq9M +RMLbOJ7FD+8jdXNsSMqpQ+pxLJRX/A10O2fOQnbdAoGAL5hV4YWSM0KZHvz332EI +ER0MXiCJN7HkPZMKH0I4eu3m8hEmAyYxVndBnsQ1F37q0xrkqAQ/HTSUntGlS/og +4Bxw5pkCwegoq/77tpto+ExDtSrEitYx4XMmSPyxX4qNULU5m3tzJgUML+b1etwD +Rd2kMU/TC02dq4KBAy/TbRkCgYAl1xN5iJz+XenLGR/2liZ+TWR+/bqzlU006mF4 +pZUmbv/uJxz+yYD5XDwqOA4UrWjuvhG9r9FoflDprp2XdWnB556KxG7XhcDfSJr9 +A5/2DadXe1Ur9O/a+oi2228JEsxQkea9QPA3FVxfBtFjOHEiDlez39VaUP4PMeUH +iO3qlQKBgFQhdTb7HeYnApYIDHLmd1PvjRvp8XKR1CpEN0nkw8HpHcT1q1MUjQCr +iT6FQupULEvGmO3frQsgVeRIQDbEdZK3C5xCtn6qOw70sYATVf361BbTtidmU9yV +THFxwDSVLiVZgFryoY/NtAc27sVdJnGsPRjjaeVgALAsLbmZ1K/H +-----END RSA PRIVATE KEY----- diff --git a/test/test_ssl/clientcerts/Revoked.crt b/test/test_ssl/clientcerts/Revoked.crt new file mode 100644 index 0000000..2fcd03e --- /dev/null +++ b/test/test_ssl/clientcerts/Revoked.crt @@ -0,0 +1,85 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + af:1a:d4:09:9e:cc:6e:7a:bd:3a:79:5a:ab:69:9d:27 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=nginx-proxy-test-suite + Validity + Not Before: Jan 3 12:28:03 2025 GMT + Not After : Jan 1 12:28:03 2035 GMT + Subject: CN=Revoked + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c0:ba:0d:13:f3:c9:8e:1a:e8:53:03:0e:fd:1e: + c1:a9:08:b5:7a:0a:64:47:9f:a2:1c:d1:da:4a:cb: + 9b:b5:ab:32:6e:34:03:ee:0d:54:cf:0d:1b:5b:0a: + b3:0c:f0:16:38:81:b2:d9:f9:7d:49:d4:b8:b6:d0: + bc:ce:25:ad:e2:8b:24:58:d6:77:3f:50:4e:32:0e: + 77:84:65:39:6d:41:4c:98:f6:dc:f4:01:e4:f1:b4: + 0d:43:da:54:ed:46:a7:eb:b7:fb:8e:51:dd:f8:77: + 60:be:76:be:43:14:7d:e7:2c:e3:46:0c:40:cc:b1: + 39:cc:7d:ee:67:18:c6:02:79:5e:4e:f3:25:4a:19: + c8:81:9f:d2:11:f0:84:14:ab:f6:e7:4a:b6:c6:e1: + a0:d1:4d:62:03:50:49:41:87:c2:79:32:b0:66:be: + a2:fa:08:31:f4:79:4c:cc:4a:4d:ad:81:3c:a6:6f: + e5:a1:41:d9:8c:f0:ba:68:50:f6:11:23:f7:27:8e: + 0d:2f:27:06:43:d0:b8:78:cd:ef:7d:6b:36:28:7e: + 7c:96:17:3b:6e:34:b7:4f:14:3c:b2:a6:79:98:9b: + 97:08:9b:19:ab:06:21:a9:fa:7d:55:c2:7b:7f:f4: + c1:e4:c7:5a:b8:0e:70:ef:1a:59:cd:05:bd:29:4f: + 43:67 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 13:7E:71:8D:FC:AD:51:DE:05:9F:5F:48:A0:BB:BB:C6:D9:26:1B:61 + X509v3 Authority Key Identifier: + keyid:F5:7E:4F:D6:61:7D:64:12:18:39:28:A4:A8:7E:34:6D:49:A9:81:16 + DirName:/CN=nginx-proxy-test-suite + serial:36:F4:8A:C0:24:42:9C:E0:13:B1:76:A5:B8:A4:84:DD:12:3A:7F:2D + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 50:ae:d0:c6:32:da:28:c4:5b:d9:35:9b:46:f1:f1:22:eb:40: + 88:e9:4b:3e:a6:f8:06:60:8e:e0:03:15:07:26:9d:51:04:db: + a8:5b:72:3e:55:cf:87:89:a9:c1:4d:94:07:cc:4a:ab:bf:a6: + e2:54:19:ee:ee:f8:cb:22:60:cb:fc:e6:25:1d:a0:b2:7f:61: + ed:de:2a:62:24:f2:14:eb:b3:e8:04:51:85:b9:c7:26:2e:42: + ef:94:bf:dd:67:b3:8d:44:78:14:4e:83:93:4e:c3:f3:75:82: + 00:9c:bc:aa:45:c2:45:80:30:43:28:ea:57:c8:a3:1b:fc:d7: + f7:9f:29:46:c1:05:8e:09:ff:e3:70:0b:fb:35:e7:94:15:dd: + 72:b9:e6:18:f7:68:65:57:cb:c7:31:c2:22:cc:94:a4:ee:3b: + b1:8b:90:80:56:da:6e:f7:01:84:74:e8:8b:65:ac:a2:1c:c4: + bd:e5:b6:d8:03:c2:97:6b:f0:da:24:fa:df:a0:1c:8b:f4:4f: + 47:f4:58:34:4f:de:40:99:7d:37:94:20:9f:0e:51:b1:49:c8: + 53:ef:39:b6:ea:25:ab:f4:4c:23:c2:a1:ae:40:8f:b0:bc:1e: + 6e:fa:4f:d9:2b:b3:4c:d0:55:cf:19:c5:7a:ed:52:4f:da:4a: + 24:03:7c:1f +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIRAK8a1AmezG56vTp5WqtpnScwDQYJKoZIhvcNAQELBQAw +ITEfMB0GA1UEAwwWbmdpbngtcHJveHktdGVzdC1zdWl0ZTAeFw0yNTAxMDMxMjI4 +MDNaFw0zNTAxMDExMjI4MDNaMBIxEDAOBgNVBAMMB1Jldm9rZWQwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAug0T88mOGuhTAw79HsGpCLV6CmRHn6Ic +0dpKy5u1qzJuNAPuDVTPDRtbCrMM8BY4gbLZ+X1J1Li20LzOJa3iiyRY1nc/UE4y +DneEZTltQUyY9tz0AeTxtA1D2lTtRqfrt/uOUd34d2C+dr5DFH3nLONGDEDMsTnM +fe5nGMYCeV5O8yVKGciBn9IR8IQUq/bnSrbG4aDRTWIDUElBh8J5MrBmvqL6CDH0 +eUzMSk2tgTymb+WhQdmM8LpoUPYRI/cnjg0vJwZD0Lh4ze99azYofnyWFztuNLdP +FDyypnmYm5cImxmrBiGp+n1Vwnt/9MHkx1q4DnDvGlnNBb0pT0NnAgMBAAGjga0w +gaowCQYDVR0TBAIwADAdBgNVHQ4EFgQUE35xjfytUd4Fn19IoLu7xtkmG2EwXAYD +VR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmpgRahJaQjMCExHzAdBgNVBAMMFm5n +aW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAkQpzgE7F2pbikhN0SOn8tMBMGA1Ud +JQQMMAoGCCsGAQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEA +UK7QxjLaKMRb2TWbRvHxIutAiOlLPqb4BmCO4AMVByadUQTbqFtyPlXPh4mpwU2U +B8xKq7+m4lQZ7u74yyJgy/zmJR2gsn9h7d4qYiTyFOuz6ARRhbnHJi5C75S/3Wez +jUR4FE6Dk07D83WCAJy8qkXCRYAwQyjqV8ijG/zX958pRsEFjgn/43AL+zXnlBXd +crnmGPdoZVfLxzHCIsyUpO47sYuQgFbabvcBhHToi2WsohzEveW22APCl2vw2iT6 +36Aci/RPR/RYNE/eQJl9N5Qgnw5RsUnIU+85tuolq/RMI8KhrkCPsLwebvpP2Suz +TNBVzxnFeu1ST9pKJAN8Hw== +-----END CERTIFICATE----- diff --git a/test/test_ssl/clientcerts/Revoked.key b/test/test_ssl/clientcerts/Revoked.key new file mode 100644 index 0000000..42f0dc8 --- /dev/null +++ b/test/test_ssl/clientcerts/Revoked.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDAug0T88mOGuhT +Aw79HsGpCLV6CmRHn6Ic0dpKy5u1qzJuNAPuDVTPDRtbCrMM8BY4gbLZ+X1J1Li2 +0LzOJa3iiyRY1nc/UE4yDneEZTltQUyY9tz0AeTxtA1D2lTtRqfrt/uOUd34d2C+ +dr5DFH3nLONGDEDMsTnMfe5nGMYCeV5O8yVKGciBn9IR8IQUq/bnSrbG4aDRTWID +UElBh8J5MrBmvqL6CDH0eUzMSk2tgTymb+WhQdmM8LpoUPYRI/cnjg0vJwZD0Lh4 +ze99azYofnyWFztuNLdPFDyypnmYm5cImxmrBiGp+n1Vwnt/9MHkx1q4DnDvGlnN +Bb0pT0NnAgMBAAECggEALzFf4nLf+Bw+p5UoJnNRmMK5LZk91QwR9lysx4P0LRgu +0S2LiM9a5RigijqkfZaM2mloElg1hc7BLIMQuKohWkgYLmjV6nsPqtJAEft3hHlo ++Ev67wVHuqgMV4EvKqsSk3YJ81+4qw8QcZNCI8rwyZsETDLT60u6i4iKyFQYqKIC +ivkWxI1WUTe1VYfsL3peTlCfT3oYUR7vk6+gJ6vLgCA+V8jjoAh++MxkPCTEU2vL +BRx0jJYy5C7hyNTzHz0Xq+vu9m+DzLmP0/maUMlsKACF5RsGfO5Jdp499LL//sC0 +/5Z5rC55sJs8/bHGt8nA5N8qNLpTNDSTwuAT5fMqgQKBgQDv4tY2NWND+p9+RIdS +Uc4XsXbvj3Se3Rsx4FB8ApX89KdKUO74dBJ8/0lGttNApYoWL44TfmJDFemmC5eT ++ya7BwQLPmOKnhzc9U8DKziFEQhWrF2FndUm3prAlWolqe/5ddoTel51fEgXooEP +2M4kwBv6Y7DWA+4X72Fvk8tL0wKBgQDNrD8bh4C+vmsqf5u0EV/ST14nLtpg+jS6 +r+a6PfzzhmYos249ZVoHog4f+0mcmO/F+K1X/XAPBnDoFWgHJ9ooVIykO1D5ias8 +CBEzHEiw0E3ayMkYNR1bRbo9ykTuUjNXH7ctdCl+QEAXM2cf83VXvc8fsXQxyRpD +iJZpkExRnQKBgA3zD+fZFOuoEExEaeYUkbp4/GST4AE49FLjK2r6r4QlKfE9YZgb +D9Qq+DTffstclPoTS9zAVbB2/r5EIE1fpnHrx4Vr3Ff8N8t1jGGvyrqaMfTwUwPp +GLMI8NDQH3sPNcA45TSKwiFs17hgH8cvIVWrwjS+RVM8qUTFC9J0Mrc3AoGACeq8 +QD+QXaIg2LO+djhAPovFJm6D6RknYbkJjwFeKP/Z/SxprFwusx+FPtWG/x4AsbMD +6LI3rQHKf+ZIVc/+HOO2xFR32xBgSUy6R5SdjKj+mAYGbDxjZfs+t6wBFtyvzQui +cXagaY3/iR7ZYhkDF2/3hLexupTPx2HWntBuXaECgYBLXINRHusQaJLN1Jjxe22h +9Tx6mPNdnM0KzNeg16F+ix1O5hArNUXaHEwPj6XX6mOq1HbM6crKeGXEzaTw7vTa +o82m4nYjxa+Yh4nDiH0/4bxjZxLRl83+Y13PSxv87lqWXNdzsGdpzkWRasrrs+0J +85NwFxyxcH1wiylc86g0BQ== +-----END PRIVATE KEY----- diff --git a/test/test_ssl/clientcerts/Valid.crt b/test/test_ssl/clientcerts/Valid.crt new file mode 100644 index 0000000..03558ff --- /dev/null +++ b/test/test_ssl/clientcerts/Valid.crt @@ -0,0 +1,85 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + e8:b3:fd:e8:a7:be:5e:a0:ea:3f:23:33:bc:2d:72:da + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=nginx-proxy-test-suite + Validity + Not Before: Jan 3 12:21:59 2025 GMT + Not After : Jan 1 12:21:59 2035 GMT + Subject: CN=Valid + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:d8:40:8d:5d:2e:a1:19:de:c5:20:01:fe:dc:9a: + ee:15:fe:9e:e1:30:a0:c7:a2:5a:22:dd:99:6e:dd: + 34:4d:6e:ad:ec:32:17:a6:e4:37:99:11:ea:67:b1: + db:1f:52:7c:17:c8:02:46:04:7f:86:b3:54:6e:55: + 18:26:af:e8:ce:84:c4:52:7c:42:fd:37:ca:ce:bf: + 88:65:09:30:4d:91:55:6f:33:0d:66:bd:e9:49:08: + 4f:65:a3:bd:41:17:67:78:57:41:94:55:6f:da:91: + cb:48:da:a1:df:fb:7d:35:16:c8:1c:ef:9a:d7:fe: + c9:19:4b:c5:89:e1:29:da:5d:01:8f:99:d4:45:da: + 9b:a8:a2:d6:f1:c2:83:36:f5:8f:bd:4b:6a:54:03: + 37:6b:d8:62:e9:15:31:97:34:43:15:a5:6a:df:2f: + b6:df:19:90:4e:53:c5:42:2a:95:b0:94:43:03:02: + 73:a4:f0:20:10:77:71:5d:55:9c:f8:d4:08:11:07: + 94:c6:bb:45:62:93:c5:bd:61:95:75:49:27:ea:b5: + e4:0b:be:27:52:61:9d:cd:11:c8:12:b3:29:d9:3a: + e9:80:6c:65:44:b0:84:cd:7f:8d:e6:ce:07:86:1c: + c1:a2:75:2f:bf:e4:66:b1:b2:b2:2f:5a:fc:44:82: + e4:f1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + ED:86:4A:75:0A:B2:ED:D1:B8:D9:88:3C:BE:42:DF:8B:18:C3:99:E8 + X509v3 Authority Key Identifier: + keyid:F5:7E:4F:D6:61:7D:64:12:18:39:28:A4:A8:7E:34:6D:49:A9:81:16 + DirName:/CN=nginx-proxy-test-suite + serial:36:F4:8A:C0:24:42:9C:E0:13:B1:76:A5:B8:A4:84:DD:12:3A:7F:2D + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Key Usage: + Digital Signature + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 25:aa:b5:6e:07:0a:3e:d2:ed:61:33:6b:48:ef:81:41:3b:7f: + 02:1c:58:74:13:25:7f:29:d2:5e:14:31:10:7a:12:81:9b:9f: + 6f:3b:b2:3e:07:32:d8:f8:3b:15:5a:18:ec:00:41:15:b1:49: + ea:c1:38:d1:7f:c9:55:bd:dd:99:a0:b9:a8:80:76:f1:6c:db: + 75:bd:23:23:2b:e4:71:9b:d7:fd:74:42:51:31:29:cd:28:32: + a9:d9:09:c5:1f:48:93:e4:6d:e6:45:97:4e:a8:4e:bd:48:d1: + e7:45:e5:34:88:74:aa:98:a3:8d:03:af:c1:10:5b:1d:ec:cb: + 55:90:7c:b4:4c:d0:33:92:63:81:eb:39:50:2b:6e:39:e3:1b: + 74:9d:67:1b:55:76:95:af:8e:83:24:47:c2:fc:aa:c5:7d:f1: + 10:e2:d1:8b:7a:b4:da:5e:40:c4:ce:32:e1:93:d9:17:76:fa: + a2:5d:a8:48:73:ff:0a:b4:b3:ac:97:e4:8b:6e:18:56:09:e0: + 05:be:42:3e:c6:8e:30:cf:29:da:0f:a1:05:c0:7d:3d:8f:8f: + 52:27:e0:dd:06:f2:06:5b:8a:40:e5:0f:5c:a5:3b:16:10:32: + 49:9f:9c:ca:d8:02:9f:f2:5c:b1:20:96:b9:b0:ff:87:7a:20: + 15:1c:4b:88 +-----BEGIN CERTIFICATE----- +MIIDajCCAlKgAwIBAgIRAOiz/einvl6g6j8jM7wtctowDQYJKoZIhvcNAQELBQAw +ITEfMB0GA1UEAwwWbmdpbngtcHJveHktdGVzdC1zdWl0ZTAeFw0yNTAxMDMxMjIx +NTlaFw0zNTAxMDExMjIxNTlaMBAxDjAMBgNVBAMMBVZhbGlkMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2ECNXS6hGd7FIAH+3JruFf6e4TCgx6JaIt2Z +bt00TW6t7DIXpuQ3mRHqZ7HbH1J8F8gCRgR/hrNUblUYJq/ozoTEUnxC/TfKzr+I +ZQkwTZFVbzMNZr3pSQhPZaO9QRdneFdBlFVv2pHLSNqh3/t9NRbIHO+a1/7JGUvF +ieEp2l0Bj5nURdqbqKLW8cKDNvWPvUtqVAM3a9hi6RUxlzRDFaVq3y+23xmQTlPF +QiqVsJRDAwJzpPAgEHdxXVWc+NQIEQeUxrtFYpPFvWGVdUkn6rXkC74nUmGdzRHI +ErMp2TrpgGxlRLCEzX+N5s4HhhzBonUvv+RmsbKyL1r8RILk8QIDAQABo4GtMIGq +MAkGA1UdEwQCMAAwHQYDVR0OBBYEFO2GSnUKsu3RuNmIPL5C34sYw5noMFwGA1Ud +IwRVMFOAFPV+T9ZhfWQSGDkopKh+NG1JqYEWoSWkIzAhMR8wHQYDVQQDDBZuZ2lu +eC1wcm94eS10ZXN0LXN1aXRlghQ29IrAJEKc4BOxdqW4pITdEjp/LTATBgNVHSUE +DDAKBggrBgEFBQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBACWq +tW4HCj7S7WEza0jvgUE7fwIcWHQTJX8p0l4UMRB6EoGbn287sj4HMtj4OxVaGOwA +QRWxSerBONF/yVW93ZmguaiAdvFs23W9IyMr5HGb1/10QlExKc0oMqnZCcUfSJPk +beZFl06oTr1I0edF5TSIdKqYo40Dr8EQWx3sy1WQfLRM0DOSY4HrOVArbjnjG3Sd +ZxtVdpWvjoMkR8L8qsV98RDi0Yt6tNpeQMTOMuGT2Rd2+qJdqEhz/wq0s6yX5Itu +GFYJ4AW+Qj7GjjDPKdoPoQXAfT2Pj1In4N0G8gZbikDlD1ylOxYQMkmfnMrYAp/y +XLEglrmw/4d6IBUcS4g= +-----END CERTIFICATE----- diff --git a/test/test_ssl/clientcerts/Valid.key b/test/test_ssl/clientcerts/Valid.key new file mode 100644 index 0000000..ff63056 --- /dev/null +++ b/test/test_ssl/clientcerts/Valid.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDYQI1dLqEZ3sUg +Af7cmu4V/p7hMKDHoloi3Zlu3TRNbq3sMhem5DeZEepnsdsfUnwXyAJGBH+Gs1Ru +VRgmr+jOhMRSfEL9N8rOv4hlCTBNkVVvMw1mvelJCE9lo71BF2d4V0GUVW/akctI +2qHf+301Fsgc75rX/skZS8WJ4SnaXQGPmdRF2puootbxwoM29Y+9S2pUAzdr2GLp +FTGXNEMVpWrfL7bfGZBOU8VCKpWwlEMDAnOk8CAQd3FdVZz41AgRB5TGu0Vik8W9 +YZV1SSfqteQLvidSYZ3NEcgSsynZOumAbGVEsITNf43mzgeGHMGidS+/5GaxsrIv +WvxEguTxAgMBAAECggEAA9DrzbOncyHrv5tZaIIxZmD2Y8nsZGl4hrn7Xan4pM8p +sYvWwAKx+nkG9mp8j+pwNyk35Q1qRLHAcSv+P5yGErLkFgKMWhSUdx6JJSNK32uL +ouk3ONNsHPZRFF2V1uK3WDfN9/SkAyrkd/YnuiChfoDW6i/OPzaHTPN52muHRguq +z5Iaw9BTTJXFhzdLqd+U6JfdXpn6brmoySXVANYwi/Ug470pR8wyulTIXIhyu8gc +9O9U/QTfpV3uRIxCdci72w9UICVHljPG1ARW1JAZsmTAgxpioGjXcwn5soSNlQ4g +dO6MJ9M7Y/amkvLfAh0Cabj4vRrEJ83TGKaYhlAquQKBgQDwKtQdftvxrQtQiU0Y +7zglGtjBRKtVjb3rcgRs2cvU1GITjIEAuMyMHnyJmGDGRVPdI2us7EZwtpsOmlk1 +nZppLOe478GBA7twaS6vONxBbegZTBtSClyktY8RG5g/siIE6y3m+JcJnZO7XELA +p1r1JUeVLWXJkO2dmgpDjVJIPQKBgQDmgh71G4iLdIxSR/VGmrHX8kwnBRV3rn2+ +O0XcY0XQZPk4XL4zx3Qw5QUC7QMxikaLDQOXKZXylyjyGGyFAjJI8HrLr7Sm7xb4 +g91EjlfQWmTjrvI/6RBndwsExiEzgkASDxm6iOMXFx658tDK6dIsZWhh/59thUVE +u+ZSBp1mxQKBgQDfQVDxIk5fONc9xISw2x+8DlrUPntvClY0GkdW0JeUfuG0/nWl +MCSlVGm8lrPPW/77oMOlefZ5LKazSnQHTTyO7LlzxxyAS/HgK0bEh/znrb2GVqNG +/m7khgo6gwZin7rUC7Md9JSi0aLVFozO/kOlg0QpvovSdjEMwncsGKEWmQKBgQDS +TiuSc1Fr8qTHuVFF3oOdwznJa/D/JZshwZBml8gtbsKWsr7yHOqcZYbh+X4tZ7we +x3vcIZvmHhXEc5Ym8C8Srx1J0wAeQgsSJ7TsBHaH6MEdnhL1Tl2iGFFcRKwsA40T +LOXLc3LFMVneS3RFfXk8+jR3HLLHSI0/PbPQaKqZBQKBgHggyUNuWtSwWTByicnU +MmGv+fb+0NEFN/c+lf2HGb5GFifhFTppAi2L+FT/D5cW+vFpC0f/O7m+ymIoa5YC +fjLvUE6L83D17H/TN34pwxpUxZg/cWl3HkVHRVLnpm4L5HKnt2Qj7q1n4q2FTjhR +vuihVh5K2G3n+Sysf1rViP5I +-----END PRIVATE KEY----- diff --git a/test/test_ssl/test_mtls-client-certificate.py b/test/test_ssl/test_mtls-client-certificate.py new file mode 100644 index 0000000..c7c03ae --- /dev/null +++ b/test/test_ssl/test_mtls-client-certificate.py @@ -0,0 +1,59 @@ +import pathlib + +import pytest +from requests.exceptions import SSLError + + +@pytest.fixture(scope="session") +def clientcerts(): + """ + Pytest fixture to provide paths to client certificates and keys. + """ + current_file_path = pathlib.Path(__file__) + clientcerts_path = current_file_path.parent.joinpath("clientcerts") + + return { + "valid_client_cert": clientcerts_path.joinpath("Valid.crt"), + "valid_client_key": clientcerts_path.joinpath("Valid.key"), + "revoked_client_cert": clientcerts_path.joinpath("Revoked.crt"), + "revoked_client_key": clientcerts_path.joinpath("Revoked.key"), + } + +@pytest.mark.parametrize("description, url, cert, expected_code, expected_text", [ + #Enforced: Test connection to a website with mTLS enabled without providing a client certificate. + ("Enforced: No client certificate, virtual_host", "https://mtls-enabled.nginx-proxy.tld/port", None, 400, "400 No required SSL certificate was sent"), + ("Enforced: No client certificate, virtual_path", "https://mtls-enabled.nginx-proxy.tld/bar/port", None, 400, "400 No required SSL certificate was sent"), + ("Enforced: No client certificate, regex", "https://regex.nginx-proxy.tld/port", None, 400, "400 No required SSL certificate was sent"), + ("Enforced: No client certificate, global CA", "https://global-mtls-enabled.nginx-proxy.tld/port", None, 400, "400 No required SSL certificate was sent"), + #Authenticated: Test connection to a website with mTLS enabled providing a valid client certificate. + ("Authenticated: Valid client certificate, virtual_host", "https://mtls-enabled.nginx-proxy.tld/port", "valid", 200, "answer from port 81\n"), + ("Authenticated: Valid client certificate, virtual_path", "https://mtls-enabled.nginx-proxy.tld/bar/port", "valid", 200, "answer from port 83\n"), + ("Authenticated: Valid client certificate, regex", "https://regex.nginx-proxy.tld/port", "valid", 200, "answer from port 85\n"), + ("Authenticated: Valid client certificate, global CA", "https://global-mtls-enabled.nginx-proxy.tld/port", "valid", 200, "answer from port 81\n"), + #Revoked: Test connection to a website with mTLS enabled providing a revoked client certificate on the CRL. + ("Revoked: Invalid client certificate, virtual_host", "https://mtls-enabled.nginx-proxy.tld/port", "revoked", 400, "400 The SSL certificate error"), + ("Revoked: Invalid client certificate, virtual_path", "https://mtls-enabled.nginx-proxy.tld/bar/port", "revoked", 400, "400 The SSL certificate error"), + ("Revoked: Invalid client certificate, regex", "https://regex.nginx-proxy.tld/port", "revoked", 400, "400 The SSL certificate error"), + ("Revoked: Invalid client certificate, global CA", "https://global-mtls-enabled.nginx-proxy.tld/port", "revoked", 400, "400 The SSL certificate error"), + #Optional: Test connection to a website with optional mTLS. Access is not blocked but can be controlled with "$ssl_client_verify" directive. We assert on /foo if $ssl_client_verify = SUCCESS response with status code 418. + ("Optional, Not enforced: No client certificate", "https://mtls-optional.nginx-proxy.tld/port", None, 200, "answer from port 82\n"), + ("Optional: Enforced, Valid client certificate", "https://mtls-optional.nginx-proxy.tld/foo/port", "valid", 418, "ssl_client_verify is SUCCESS"), + ("Optional, Not enforced: No client certificate", "https://mtls-optional.nginx-proxy.tld/bar/port", None, 200, "answer from port 84\n"), + ("Optional: Enforced, Valid client certificate", "https://mtls-optional.nginx-proxy.tld/foo/bar/port", "valid", 418, "ssl_client_verify is SUCCESS"), + ("Optional, Not enforced: No client certificate, global CA", "https://global-mtls-optional.nginx-proxy.tld/port", None, 200, "answer from port 82\n"), + ("Optional: Enforced, Valid client certificate, global CA", "https://global-mtls-optional.nginx-proxy.tld/foo/port", "valid", 418, "ssl_client_verify is SUCCESS"), +]) +def test_mtls_client_certificates(docker_compose, nginxproxy, clientcerts, description, url, cert, expected_code, expected_text): + """ + Parameterized test for mTLS client certificate scenarios. + """ + if cert == "valid": + client_cert = (clientcerts["valid_client_cert"], clientcerts["valid_client_key"]) + elif cert == "revoked": + client_cert = (clientcerts["revoked_client_cert"], clientcerts["revoked_client_key"]) + else: + client_cert = None + + r = nginxproxy.get(url, cert=client_cert if client_cert else None) + assert r.status_code == expected_code + assert expected_text in r.text diff --git a/test/test_ssl/test_mtls-client-certificate.yml b/test/test_ssl/test_mtls-client-certificate.yml new file mode 100644 index 0000000..99edc83 --- /dev/null +++ b/test/test_ssl/test_mtls-client-certificate.yml @@ -0,0 +1,69 @@ +services: + mtls-vhost-enabled: + image: web + expose: + - "81" + environment: + WEB_PORTS: "81" + VIRTUAL_HOST: "mtls-enabled.nginx-proxy.tld,global-mtls-enabled.nginx-proxy.tld" + + mtls-vhost-optional: + image: web + expose: + - "82" + environment: + WEB_PORTS: "82" + VIRTUAL_HOST_MULTIPORTS: |- + mtls-optional.nginx-proxy.tld: + "/": + dest: "/" + "/foo": + dest: "/" + global-mtls-optional.nginx-proxy.tld: + "/": + dest: "/" + "/foo": + dest: "/" + labels: + com.github.nginx-proxy.nginx-proxy.ssl_verify_client: "optional" + + mtls-vpath-enabled: + image: web + expose: + - "83" + environment: + WEB_PORTS: "83" + VIRTUAL_HOST: "mtls-enabled.nginx-proxy.tld" + VIRTUAL_PATH: /bar/ + VIRTUAL_DEST: / + + mtls-vpath-optional: + image: web + expose: + - "84" + environment: + WEB_PORTS: "84" + VIRTUAL_HOST_MULTIPORTS: |- + mtls-optional.nginx-proxy.tld: + "/bar": + dest: "/" + "/foo/bar": + dest: "/" + labels: + com.github.nginx-proxy.nginx-proxy.ssl_verify_client: "optional" + + mtls-regex-enabled: + image: web + expose: + - "85" + environment: + WEB_PORTS: "85" + VIRTUAL_HOST: ~^regex.*\.nginx-proxy\.tld$ + CERT_NAME: nginx-proxy.tld + + nginx-proxy: + volumes: + - ${PYTEST_MODULE_PATH}/certs_mtls:/etc/nginx/certs:ro + - ${PYTEST_MODULE_PATH}/certs_mtls/mtls-optional-foo-bar_location:/etc/nginx/vhost.d/mtls-optional.nginx-proxy.tld_6dbd548cc03e44b8b44b6e68e56255ce4273ae49_location:ro #/foo + - ${PYTEST_MODULE_PATH}/certs_mtls/mtls-optional-foo-bar_location:/etc/nginx/vhost.d/mtls-optional.nginx-proxy.tld_a82cce35fd860de6f63f97e6c482dc6a14d002e8_location:ro #/bar + - ${PYTEST_MODULE_PATH}/certs_mtls/mtls-optional-foo-bar_location:/etc/nginx/vhost.d/global-mtls-optional.nginx-proxy.tld_6dbd548cc03e44b8b44b6e68e56255ce4273ae49_location:ro #/foo From 7edf50a9e5deb3f8935264a92e4b58b0383c03a5 Mon Sep 17 00:00:00 2001 From: Niek <100143256+SchoNie@users.noreply.github.com> Date: Wed, 4 Jun 2025 15:42:25 +0200 Subject: [PATCH 3/5] docs: SSL client certificate validation mTLS --- docs/README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/docs/README.md b/docs/README.md index f14bc2b..d5f714b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,6 +5,7 @@ - [Docker Networking](#docker-networking) - [Upstream (Backend) features](#upstream-backend-features) - [Basic Authentication Support](#basic-authentication-support) +- [mTLS client side certificate authentication](#mtls-client-side-certificate-authentication) - [Logging](#logging) - [SSL Support](#ssl-support) - [IPv6 Support](#ipv6-nat) @@ -374,6 +375,36 @@ You'll need apache2-utils on the machine where you plan to create the htpasswd f ⬆️ [back to table of contents](#table-of-contents) +## mTLS client side certificate authentication +In mTLS, both the client and server have a certificate, and both sides authenticate using their public/private key pair. +A "root" TLS certificate is necessary for mTLS; this enables an organization to be their own certificate authority. The certificates used by authorized clients and servers have to correspond to this root certificate. The root certificate is self-signed, meaning that the organization creates it themselves. +Make sure you have a root certificate (CA) and client public/private key pair. There is a [howto in the wiki](https://github.com/nginx-proxy/nginx-proxy/wiki/mTLS-client-side-certificate-authentication). + +### Certificate Authority (CA) +#### Per-VIRTUAL_HOST CA +In order to secure a virtual host, you have to copy your CA certificate file (ca.crt) named as its equivalent `VIRTUAL_HOST` variable or if `VIRTUAL_HOST` is a regex, after the sha1 hash of the regex with the suffix `.ca.crt` in directory +`/etc/nginx/certs/`. Example: `/etc/nginx/certs/app.example.com.ca.crt`. +Or if your `VIRTUAL_HOST` is a regex: `/etc/nginx/certs/9ae5d1b655182b052fed458ec701f9ae1524e1c2.ca.crt`. + +#### Global CA +If you want to secure everything globally you can copy your CA certificate file (ca.crt) named as `ca.crt` in directory +`/etc/nginx/certs/`. Example: `/etc/nginx/certs/ca.crt`. + +### Certificate Revocation List (CRL) +#### Per-VIRTUAL_HOST CRL +In order to use a certificate revocation list, you have to copy your CRL file named as its equivalent `VIRTUAL_HOST` variable or if `VIRTUAL_HOST` is a regex, after the sha1 hash of the regex with the suffix `.crl.pem` in directory +`/etc/nginx/certs/`. Example: `/etc/nginx/certs/app.example.com.crl.pem`. +Or if your `VIRTUAL_HOST` is a regex: `/etc/nginx/certs/9ae5d1b655182b052fed458ec701f9ae1524e1c2.crl.pem`. + +#### Global CRL +If you want to use a global CRL file you have to copy your CRL file named as `ca.crl.pem` in directory +`/etc/nginx/certs/`. Example: `/etc/nginx/certs/ca.crl.pem`. + +### optional ssl_verify_client +Optional [`ssl_verify_client`](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_client) can be activated by using the `com.github.nginx-proxy.nginx-proxy.ssl_verify_client: "optional"` label on a proxied container. If this label is set on a proxied container access is not blocked but the result of the mTLS verify is stored in the [$ssl_client_verify](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_client_verify) variable which you can use this in the [Per-VIRTUAL_HOST location](https://github.com/nginx-proxy/nginx-proxy/tree/main/docs#per-virtual_host-location-configuration) and [Per-VIRTUAL_PATH location](https://github.com/nginx-proxy/nginx-proxy/tree/main/docs#per-virtual_path-location-configuration) configurations. + +⬆️ [back to table of contents](#table-of-contents) + ## Logging The default nginx access log format is @@ -1327,6 +1358,7 @@ Configuration available on each proxied container, either by environment variabl | n/a | [`com.github.nginx-proxy.nginx-proxy.non-get-redirect`](#how-ssl-support-works) | global (proxy) value | | [`SERVER_TOKENS`](#per-virtual_host-server_tokens-configuration) | n/a | no default value | | [`SSL_POLICY`](#how-ssl-support-works) | n/a | global (proxy) value | +| n/a | [`com.github.nginx-proxy.nginx-proxy.ssl_verify_client`](#optional-ssl_verify_client) | `on` | | n/a | [`com.github.nginx-proxy.nginx-proxy.trust-default-cert`](#default-and-missing-certificate) | global (proxy) value | | [`VIRTUAL_DEST`](#virtual_dest) | n/a | `empty string` | | [`VIRTUAL_HOST`](#virtual-hosts-and-ports) | n/a | no default value | From 03403dedd679b28863eddae37fb33593753efb4f Mon Sep 17 00:00:00 2001 From: Niek <100143256+SchoNie@users.noreply.github.com> Date: Tue, 10 Jun 2025 10:40:00 +0200 Subject: [PATCH 4/5] chore: styling --- nginx.tmpl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/nginx.tmpl b/nginx.tmpl index 6dbea62..939aa2e 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -1047,18 +1047,18 @@ server { {{- if (exists (printf "/etc/nginx/certs/%s.ca.crt" $vhostFileName)) }} ssl_client_certificate {{ printf "/etc/nginx/certs/%s.ca.crt" $vhostFileName }}; ssl_verify_client {{ $vhost.ssl_verify_client }}; - {{/* If vhost(hash).crl.pem exists, include CRL */}} - {{- if (exists (printf "/etc/nginx/certs/%s.crl.pem" $vhostFileName)) }} + {{/* If vhost(hash).crl.pem exists, include CRL */}} + {{- if (exists (printf "/etc/nginx/certs/%s.crl.pem" $vhostFileName)) }} ssl_crl {{ printf "/etc/nginx/certs/%s.crl.pem" $vhostFileName }}; - {{ end }} - {{/* If no vhost CA file exists, but a global ca.crt exists include it */}} + {{ end }} + {{/* Else if no vhost CA file exists, but a global ca.crt exists include it */}} {{ else if (exists "/etc/nginx/certs/ca.crt") }} ssl_client_certificate /etc/nginx/certs/ca.crt; ssl_verify_client {{ $vhost.ssl_verify_client }}; - {{/* If no vhost CA file exists, but a global ca.crl.pem exists include it */}} - {{ if (exists "/etc/nginx/certs/ca.crl.pem")}} + {{/* If no vhost CA file exists, but a global ca.crl.pem exists include it */}} + {{ if (exists "/etc/nginx/certs/ca.crl.pem")}} ssl_crl /etc/nginx/certs/ca.crl.pem; - {{ end }} + {{ end }} {{ end }} {{- if $vhost.enable_debug_endpoint }} From df85d14f6c388c65457eb4c9f2df593f0eeeb8ac Mon Sep 17 00:00:00 2001 From: Niek <100143256+SchoNie@users.noreply.github.com> Date: Tue, 10 Jun 2025 10:40:54 +0200 Subject: [PATCH 5/5] docs: note about global and per-vhost CRL --- docs/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/README.md b/docs/README.md index d5f714b..feeb5f1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -400,6 +400,9 @@ Or if your `VIRTUAL_HOST` is a regex: `/etc/nginx/certs/9ae5d1b655182b052fed458e If you want to use a global CRL file you have to copy your CRL file named as `ca.crl.pem` in directory `/etc/nginx/certs/`. Example: `/etc/nginx/certs/ca.crl.pem`. +> [!NOTE] +> Use Per-VIRTUAL_HOST CRL if you configured the [Per-VIRTUAL_HOST CA](#per-virtual_host-ca) or Global CRL if you configured the [Global CA](#global-ca) + ### optional ssl_verify_client Optional [`ssl_verify_client`](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_client) can be activated by using the `com.github.nginx-proxy.nginx-proxy.ssl_verify_client: "optional"` label on a proxied container. If this label is set on a proxied container access is not blocked but the result of the mTLS verify is stored in the [$ssl_client_verify](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_client_verify) variable which you can use this in the [Per-VIRTUAL_HOST location](https://github.com/nginx-proxy/nginx-proxy/tree/main/docs#per-virtual_host-location-configuration) and [Per-VIRTUAL_PATH location](https://github.com/nginx-proxy/nginx-proxy/tree/main/docs#per-virtual_path-location-configuration) configurations.