Skip to content

Commit 2c83810

Browse files
authored
Merge pull request #2592 from SchoNie/mtls-client-certificate
feat: SSL client certificate validation
2 parents 219d3b1 + df85d14 commit 2c83810

18 files changed

+636
-0
lines changed

docs/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [Docker Networking](#docker-networking)
66
- [Upstream (Backend) features](#upstream-backend-features)
77
- [Basic Authentication Support](#basic-authentication-support)
8+
- [mTLS client side certificate authentication](#mtls-client-side-certificate-authentication)
89
- [Logging](#logging)
910
- [SSL Support](#ssl-support)
1011
- [IPv6 Support](#ipv6-nat)
@@ -374,6 +375,39 @@ You'll need apache2-utils on the machine where you plan to create the htpasswd f
374375

375376
⬆️ [back to table of contents](#table-of-contents)
376377

378+
## mTLS client side certificate authentication
379+
In mTLS, both the client and server have a certificate, and both sides authenticate using their public/private key pair.
380+
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.
381+
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).
382+
383+
### Certificate Authority (CA)
384+
#### Per-VIRTUAL_HOST CA
385+
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
386+
`/etc/nginx/certs/`. Example: `/etc/nginx/certs/app.example.com.ca.crt`.
387+
Or if your `VIRTUAL_HOST` is a regex: `/etc/nginx/certs/9ae5d1b655182b052fed458ec701f9ae1524e1c2.ca.crt`.
388+
389+
#### Global CA
390+
If you want to secure everything globally you can copy your CA certificate file (ca.crt) named as `ca.crt` in directory
391+
`/etc/nginx/certs/`. Example: `/etc/nginx/certs/ca.crt`.
392+
393+
### Certificate Revocation List (CRL)
394+
#### Per-VIRTUAL_HOST CRL
395+
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
396+
`/etc/nginx/certs/`. Example: `/etc/nginx/certs/app.example.com.crl.pem`.
397+
Or if your `VIRTUAL_HOST` is a regex: `/etc/nginx/certs/9ae5d1b655182b052fed458ec701f9ae1524e1c2.crl.pem`.
398+
399+
#### Global CRL
400+
If you want to use a global CRL file you have to copy your CRL file named as `ca.crl.pem` in directory
401+
`/etc/nginx/certs/`. Example: `/etc/nginx/certs/ca.crl.pem`.
402+
403+
> [!NOTE]
404+
> 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)
405+
406+
### optional ssl_verify_client
407+
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.
408+
409+
⬆️ [back to table of contents](#table-of-contents)
410+
377411
## Logging
378412

379413
The default nginx access log format is
@@ -1327,6 +1361,7 @@ Configuration available on each proxied container, either by environment variabl
13271361
| n/a | [`com.github.nginx-proxy.nginx-proxy.non-get-redirect`](#how-ssl-support-works) | global (proxy) value |
13281362
| [`SERVER_TOKENS`](#per-virtual_host-server_tokens-configuration) | n/a | no default value |
13291363
| [`SSL_POLICY`](#how-ssl-support-works) | n/a | global (proxy) value |
1364+
| n/a | [`com.github.nginx-proxy.nginx-proxy.ssl_verify_client`](#optional-ssl_verify_client) | `on` |
13301365
| n/a | [`com.github.nginx-proxy.nginx-proxy.trust-default-cert`](#default-and-missing-certificate) | global (proxy) value |
13311366
| [`VIRTUAL_DEST`](#virtual_dest) | n/a | `empty string` |
13321367
| [`VIRTUAL_HOST`](#virtual-hosts-and-ports) | n/a | no default value |

nginx.tmpl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,9 @@ proxy_set_header Proxy "";
759759
{{- /* Get the SSL_POLICY defined by containers w/ the same vhost, falling back to empty string (use default). */}}
760760
{{- $ssl_policy := groupByKeys $vhost_containers "Env.SSL_POLICY" | first | default "" }}
761761

762+
{{- /* Get ssl_verify_client defined by containers w/ the same vhost, falling back to "on" */}}
763+
{{- $ssl_verify_client := groupByLabel $vhost_containers "com.github.nginx-proxy.nginx-proxy.ssl_verify_client" | keys | first | default "on" }}
764+
762765
{{- /* Get the HSTS defined by containers w/ the same vhost, falling back to "max-age=31536000". */}}
763766
{{- $hsts := groupByKeys $vhost_containers "Env.HSTS" | first | default $globals.config.hsts }}
764767

@@ -780,6 +783,7 @@ proxy_set_header Proxy "";
780783
"acme_http_challenge_enabled" $acme_http_challenge_enabled
781784
"server_tokens" $server_tokens
782785
"ssl_policy" $ssl_policy
786+
"ssl_verify_client" $ssl_verify_client
783787
"trust_default_cert" $trust_default_cert
784788
"upstream_name" $upstream_name
785789
"vhost_root" $vhost_root
@@ -1038,6 +1042,25 @@ server {
10381042
include /etc/nginx/vhost.d/default;
10391043
{{- end }}
10401044

1045+
{{/* SSL Client Certificate Validation */}}
1046+
{{/* If vhost(hash).ca.crt exists, include CA */}}
1047+
{{- if (exists (printf "/etc/nginx/certs/%s.ca.crt" $vhostFileName)) }}
1048+
ssl_client_certificate {{ printf "/etc/nginx/certs/%s.ca.crt" $vhostFileName }};
1049+
ssl_verify_client {{ $vhost.ssl_verify_client }};
1050+
{{/* If vhost(hash).crl.pem exists, include CRL */}}
1051+
{{- if (exists (printf "/etc/nginx/certs/%s.crl.pem" $vhostFileName)) }}
1052+
ssl_crl {{ printf "/etc/nginx/certs/%s.crl.pem" $vhostFileName }};
1053+
{{ end }}
1054+
{{/* Else if no vhost CA file exists, but a global ca.crt exists include it */}}
1055+
{{ else if (exists "/etc/nginx/certs/ca.crt") }}
1056+
ssl_client_certificate /etc/nginx/certs/ca.crt;
1057+
ssl_verify_client {{ $vhost.ssl_verify_client }};
1058+
{{/* If no vhost CA file exists, but a global ca.crl.pem exists include it */}}
1059+
{{ if (exists "/etc/nginx/certs/ca.crl.pem")}}
1060+
ssl_crl /etc/nginx/certs/ca.crl.pem;
1061+
{{ end }}
1062+
{{ end }}
1063+
10411064
{{- if $vhost.enable_debug_endpoint }}
10421065
{{ template "debug_location" (dict "GlobalConfig" $globals.config "Hostname" $hostname "VHost" $vhost) }}
10431066
{{- end }}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDbDCCAlSgAwIBAgIUNvSKwCRCnOATsXaluKSE3RI6fy0wDQYJKoZIhvcNAQEL
3+
BQAwITEfMB0GA1UEAwwWbmdpbngtcHJveHktdGVzdC1zdWl0ZTAeFw0yNTAxMDMx
4+
MjE0NTdaFw0zNTAxMDExMjE0NTdaMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRl
5+
c3Qtc3VpdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCb78gTRxTy
6+
6NrnApjBZ9Gjuj+0FcqE6ARpYBcQU+F/yokyNhE0SR4AyQaGtymDkqPcrfdDVd4b
7+
ylz3wsbJ5jCjHyPFOQ+6trVZ6eKfQ+VoMTlTCj+ystKAba85bWdXriLdMNoqZdkY
8+
jT6ryHUQ/mmeVdhUKBtCrqayiYNbjGTkhCwH2h2jYBdK5ngZ5mc1Z+4NGCUi14aY
9+
AHU+nwSae/y6OU2gcYhr4NuFtwxLfxXXj2vgdTMcqoeu08u6kEjY0g7A7dzMEJ0r
10+
VGB6+aMVK22KklPLn2IgZ/w4TC/kq/DhyWivL4HYjsKbmA6O9tM6xQqpxUwIyo+y
11+
CdTbtv5uSX3jAgMBAAGjgZswgZgwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQU9X5P
12+
1mF9ZBIYOSikqH40bUmpgRYwXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmp
13+
gRahJaQjMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAk
14+
QpzgE7F2pbikhN0SOn8tMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
15+
kE32r6zEm6ntNRVdu3wYR6oSkk7wQr1m2YmVQjb4LIdSL3nP8VJ9PhBxUpLV03tX
16+
evUqrAiMRL6luwFaTSb3mDxm4RGfWUzd0OVjS5NMki7Tr2RXwCCxvKApYcoJ8pwP
17+
dNsqAmhxEwhQXIx3lG8EAxiSXe26S9JU6ILVDgdnYgfr/S9k99OjtUQOS88XiKuL
18+
fwV7n/xSAQDiczGjwWpJLdZiKgic5VFtKOVHHMo5BIX30SJSd//BjZ5Z3N++FhLg
19+
RzwEjbnVxxOkyz30N8VD5M7I5XwTa+VVTj5Cqoj+ImBy+/IsqjqIX8KIjl2AoJER
20+
+2EdFJ1a5odHU3olzbuRcA==
21+
-----END CERTIFICATE-----
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-----BEGIN X509 CRL-----
2+
MIICADCB6QIBATANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDDBZuZ2lueC1wcm94
3+
eS10ZXN0LXN1aXRlFw0yNTAxMDMxMjMwNTBaFw0yNTA3MDIxMjMwNTBaMDIwMAIR
4+
AK8a1AmezG56vTp5WqtpnScXDTI1MDEwMzEyMzAwN1owDDAKBgNVHRUEAwoBBaBg
5+
MF4wXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmpgRahJaQjMCExHzAdBgNV
6+
BAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAkQpzgE7F2pbikhN0SOn8t
7+
MA0GCSqGSIb3DQEBCwUAA4IBAQCGaKW8kJy1Mznc3T2OHkCx8GudvOo0ZBsZ+pTm
8+
sAnlxDQTIqm8e4gU19WF/SISlfr7qEERqif8+SlUgS9CWtJa70gk+9oobuWfBNIT
9+
VXD4ujO/47nqt2MdRUSSGX+K+9Ox2gyU6kHO1ZrT8VmsL22Bhfa2Pw/3OBL/QHMU
10+
b1hAZyed0CoPCnMqjG0X5zMo3ByGW3TkxG2GhzKCWLGXVbzdHFpS98hpkpaxvIlE
11+
juSYuPItwEftHdB8JHAHL18uDJapZ5mOCuUn/HoZBWOudFjtFQUUzq4eTsB56My4
12+
qDGb1/ReAoGyheuV0fEtg9MJkGEuGrb38JN6hcdfpW5u0Hwb
13+
-----END X509 CRL-----

test/test_ssl/certs_mtls/ca.crl.pem

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-----BEGIN X509 CRL-----
2+
MIICADCB6QIBATANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDDBZuZ2lueC1wcm94
3+
eS10ZXN0LXN1aXRlFw0yNTAxMDMxMjMwNTBaFw0yNTA3MDIxMjMwNTBaMDIwMAIR
4+
AK8a1AmezG56vTp5WqtpnScXDTI1MDEwMzEyMzAwN1owDDAKBgNVHRUEAwoBBaBg
5+
MF4wXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmpgRahJaQjMCExHzAdBgNV
6+
BAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAkQpzgE7F2pbikhN0SOn8t
7+
MA0GCSqGSIb3DQEBCwUAA4IBAQCGaKW8kJy1Mznc3T2OHkCx8GudvOo0ZBsZ+pTm
8+
sAnlxDQTIqm8e4gU19WF/SISlfr7qEERqif8+SlUgS9CWtJa70gk+9oobuWfBNIT
9+
VXD4ujO/47nqt2MdRUSSGX+K+9Ox2gyU6kHO1ZrT8VmsL22Bhfa2Pw/3OBL/QHMU
10+
b1hAZyed0CoPCnMqjG0X5zMo3ByGW3TkxG2GhzKCWLGXVbzdHFpS98hpkpaxvIlE
11+
juSYuPItwEftHdB8JHAHL18uDJapZ5mOCuUn/HoZBWOudFjtFQUUzq4eTsB56My4
12+
qDGb1/ReAoGyheuV0fEtg9MJkGEuGrb38JN6hcdfpW5u0Hwb
13+
-----END X509 CRL-----

test/test_ssl/certs_mtls/ca.crt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDbDCCAlSgAwIBAgIUNvSKwCRCnOATsXaluKSE3RI6fy0wDQYJKoZIhvcNAQEL
3+
BQAwITEfMB0GA1UEAwwWbmdpbngtcHJveHktdGVzdC1zdWl0ZTAeFw0yNTAxMDMx
4+
MjE0NTdaFw0zNTAxMDExMjE0NTdaMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRl
5+
c3Qtc3VpdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCb78gTRxTy
6+
6NrnApjBZ9Gjuj+0FcqE6ARpYBcQU+F/yokyNhE0SR4AyQaGtymDkqPcrfdDVd4b
7+
ylz3wsbJ5jCjHyPFOQ+6trVZ6eKfQ+VoMTlTCj+ystKAba85bWdXriLdMNoqZdkY
8+
jT6ryHUQ/mmeVdhUKBtCrqayiYNbjGTkhCwH2h2jYBdK5ngZ5mc1Z+4NGCUi14aY
9+
AHU+nwSae/y6OU2gcYhr4NuFtwxLfxXXj2vgdTMcqoeu08u6kEjY0g7A7dzMEJ0r
10+
VGB6+aMVK22KklPLn2IgZ/w4TC/kq/DhyWivL4HYjsKbmA6O9tM6xQqpxUwIyo+y
11+
CdTbtv5uSX3jAgMBAAGjgZswgZgwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQU9X5P
12+
1mF9ZBIYOSikqH40bUmpgRYwXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmp
13+
gRahJaQjMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAk
14+
QpzgE7F2pbikhN0SOn8tMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
15+
kE32r6zEm6ntNRVdu3wYR6oSkk7wQr1m2YmVQjb4LIdSL3nP8VJ9PhBxUpLV03tX
16+
evUqrAiMRL6luwFaTSb3mDxm4RGfWUzd0OVjS5NMki7Tr2RXwCCxvKApYcoJ8pwP
17+
dNsqAmhxEwhQXIx3lG8EAxiSXe26S9JU6ILVDgdnYgfr/S9k99OjtUQOS88XiKuL
18+
fwV7n/xSAQDiczGjwWpJLdZiKgic5VFtKOVHHMo5BIX30SJSd//BjZ5Z3N++FhLg
19+
RzwEjbnVxxOkyz30N8VD5M7I5XwTa+VVTj5Cqoj+ImBy+/IsqjqIX8KIjl2AoJER
20+
+2EdFJ1a5odHU3olzbuRcA==
21+
-----END CERTIFICATE-----
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDbDCCAlSgAwIBAgIUNvSKwCRCnOATsXaluKSE3RI6fy0wDQYJKoZIhvcNAQEL
3+
BQAwITEfMB0GA1UEAwwWbmdpbngtcHJveHktdGVzdC1zdWl0ZTAeFw0yNTAxMDMx
4+
MjE0NTdaFw0zNTAxMDExMjE0NTdaMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRl
5+
c3Qtc3VpdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCb78gTRxTy
6+
6NrnApjBZ9Gjuj+0FcqE6ARpYBcQU+F/yokyNhE0SR4AyQaGtymDkqPcrfdDVd4b
7+
ylz3wsbJ5jCjHyPFOQ+6trVZ6eKfQ+VoMTlTCj+ystKAba85bWdXriLdMNoqZdkY
8+
jT6ryHUQ/mmeVdhUKBtCrqayiYNbjGTkhCwH2h2jYBdK5ngZ5mc1Z+4NGCUi14aY
9+
AHU+nwSae/y6OU2gcYhr4NuFtwxLfxXXj2vgdTMcqoeu08u6kEjY0g7A7dzMEJ0r
10+
VGB6+aMVK22KklPLn2IgZ/w4TC/kq/DhyWivL4HYjsKbmA6O9tM6xQqpxUwIyo+y
11+
CdTbtv5uSX3jAgMBAAGjgZswgZgwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQU9X5P
12+
1mF9ZBIYOSikqH40bUmpgRYwXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmp
13+
gRahJaQjMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAk
14+
QpzgE7F2pbikhN0SOn8tMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
15+
kE32r6zEm6ntNRVdu3wYR6oSkk7wQr1m2YmVQjb4LIdSL3nP8VJ9PhBxUpLV03tX
16+
evUqrAiMRL6luwFaTSb3mDxm4RGfWUzd0OVjS5NMki7Tr2RXwCCxvKApYcoJ8pwP
17+
dNsqAmhxEwhQXIx3lG8EAxiSXe26S9JU6ILVDgdnYgfr/S9k99OjtUQOS88XiKuL
18+
fwV7n/xSAQDiczGjwWpJLdZiKgic5VFtKOVHHMo5BIX30SJSd//BjZ5Z3N++FhLg
19+
RzwEjbnVxxOkyz30N8VD5M7I5XwTa+VVTj5Cqoj+ImBy+/IsqjqIX8KIjl2AoJER
20+
+2EdFJ1a5odHU3olzbuRcA==
21+
-----END CERTIFICATE-----
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-----BEGIN X509 CRL-----
2+
MIICADCB6QIBATANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDDBZuZ2lueC1wcm94
3+
eS10ZXN0LXN1aXRlFw0yNTAxMDMxMjMwNTBaFw0yNTA3MDIxMjMwNTBaMDIwMAIR
4+
AK8a1AmezG56vTp5WqtpnScXDTI1MDEwMzEyMzAwN1owDDAKBgNVHRUEAwoBBaBg
5+
MF4wXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmpgRahJaQjMCExHzAdBgNV
6+
BAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAkQpzgE7F2pbikhN0SOn8t
7+
MA0GCSqGSIb3DQEBCwUAA4IBAQCGaKW8kJy1Mznc3T2OHkCx8GudvOo0ZBsZ+pTm
8+
sAnlxDQTIqm8e4gU19WF/SISlfr7qEERqif8+SlUgS9CWtJa70gk+9oobuWfBNIT
9+
VXD4ujO/47nqt2MdRUSSGX+K+9Ox2gyU6kHO1ZrT8VmsL22Bhfa2Pw/3OBL/QHMU
10+
b1hAZyed0CoPCnMqjG0X5zMo3ByGW3TkxG2GhzKCWLGXVbzdHFpS98hpkpaxvIlE
11+
juSYuPItwEftHdB8JHAHL18uDJapZ5mOCuUn/HoZBWOudFjtFQUUzq4eTsB56My4
12+
qDGb1/ReAoGyheuV0fEtg9MJkGEuGrb38JN6hcdfpW5u0Hwb
13+
-----END X509 CRL-----
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
if ($ssl_client_verify = SUCCESS) {
2+
add_header Content-Type text/plain;
3+
return 418 'ssl_client_verify is SUCCESS';
4+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDbDCCAlSgAwIBAgIUNvSKwCRCnOATsXaluKSE3RI6fy0wDQYJKoZIhvcNAQEL
3+
BQAwITEfMB0GA1UEAwwWbmdpbngtcHJveHktdGVzdC1zdWl0ZTAeFw0yNTAxMDMx
4+
MjE0NTdaFw0zNTAxMDExMjE0NTdaMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRl
5+
c3Qtc3VpdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCb78gTRxTy
6+
6NrnApjBZ9Gjuj+0FcqE6ARpYBcQU+F/yokyNhE0SR4AyQaGtymDkqPcrfdDVd4b
7+
ylz3wsbJ5jCjHyPFOQ+6trVZ6eKfQ+VoMTlTCj+ystKAba85bWdXriLdMNoqZdkY
8+
jT6ryHUQ/mmeVdhUKBtCrqayiYNbjGTkhCwH2h2jYBdK5ngZ5mc1Z+4NGCUi14aY
9+
AHU+nwSae/y6OU2gcYhr4NuFtwxLfxXXj2vgdTMcqoeu08u6kEjY0g7A7dzMEJ0r
10+
VGB6+aMVK22KklPLn2IgZ/w4TC/kq/DhyWivL4HYjsKbmA6O9tM6xQqpxUwIyo+y
11+
CdTbtv5uSX3jAgMBAAGjgZswgZgwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQU9X5P
12+
1mF9ZBIYOSikqH40bUmpgRYwXAYDVR0jBFUwU4AU9X5P1mF9ZBIYOSikqH40bUmp
13+
gRahJaQjMCExHzAdBgNVBAMMFm5naW54LXByb3h5LXRlc3Qtc3VpdGWCFDb0isAk
14+
QpzgE7F2pbikhN0SOn8tMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
15+
kE32r6zEm6ntNRVdu3wYR6oSkk7wQr1m2YmVQjb4LIdSL3nP8VJ9PhBxUpLV03tX
16+
evUqrAiMRL6luwFaTSb3mDxm4RGfWUzd0OVjS5NMki7Tr2RXwCCxvKApYcoJ8pwP
17+
dNsqAmhxEwhQXIx3lG8EAxiSXe26S9JU6ILVDgdnYgfr/S9k99OjtUQOS88XiKuL
18+
fwV7n/xSAQDiczGjwWpJLdZiKgic5VFtKOVHHMo5BIX30SJSd//BjZ5Z3N++FhLg
19+
RzwEjbnVxxOkyz30N8VD5M7I5XwTa+VVTj5Cqoj+ImBy+/IsqjqIX8KIjl2AoJER
20+
+2EdFJ1a5odHU3olzbuRcA==
21+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy