NGINX SSL Reverse Proxy Weryfikacja upstream SSL

Aug 18 2020

Mam konfigurację NGINX jako odwrotnego proxy do hostowania wielu witryn internetowych przy użyciu tylko jednego adresu IP. Mam certyfikat Lets Encrypt na serwerze proxy i inny certyfikat Lets Encrypt na serwerze nadrzędnym. Zasadniczo potrzebuję NGINX do przekazywania ruchu do serwera nadrzędnego i sprawdzania, czy serwer nadrzędny ma ważny certyfikat TLS. Jeśli wyłączę proxy_ssl_verify, będzie działać. Jeśli przejdę do https://app.local.example.commojej sieci wewnętrznej, aplikacja działa dobrze.

Schemat sieci:

https://app.example.com --> NGINX Reverse Proxy --> https://app.local.example.com (Local IP Address)

Plik konfiguracyjny odwrotnego proxy NGINX:

server {
    listen 80;
    rewrite ^ https://$host$request_uri? permanent;
}

server {
        server_name app.example.com;

        listen                                  443 ssl;

        ssl_certificate                         /etc/letsencrypt/live/app.example.com/cert.pem;
        ssl_certificate_key                     /etc/letsencrypt/live/app.example.com/privkey.pem;
        ssl_trusted_certificate                 /etc/letsencrypt/live/app.example.com/chain.pem;

        location / {

                proxy_redirect off;
                proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Ssl on; proxy_set_header X-Forwarded-Protocol $scheme;
                proxy_set_header X-Forwarded-HTTPS on;

                proxy_ssl_session_reuse        off;
                proxy_ssl_name                 app.local.example.com

                proxy_ssl_verify               on;
                proxy_ssl_verify_depth         2; # I've tried 1,2,3,4
                proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt; 
                            
                proxy_pass                     https://app.local.example.com
        }
}

Oto komunikat o błędzie, który otrzymuję.

[error] 1087#1087: *2 upstream SSL certificate verify error: (20:unable to get local issuer certificate) while SSL handshaking to upstream, client: [Client IP], server: app.example.com, request: "GET / HTTP/1.1", upstream: "https://192.168.1.5:443/", host: "app.local.example.com", referrer: "https://app.example.com/">

Wersja OpenSSL: OpenSSL 1.1.1f 31 Mar 2020

nginx -v: nginx version: nginx/1.18.0 (Ubuntu)

cat / etc / issue: Ubuntu 20.04.1 LTS \n \l

Wyjście openssl s_client -connect app.local.example.com:443

CONNECTED(00000003)
depth=0 CN = app.local.example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = app.local.example.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:CN = app.local.example.com
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFeDCCBGCgAwIBAgISA8NkbZ6wz2EnKcedXujKT9AmMA0GCSqGSIb3DQEBCwUA
...
-----END CERTIFICATE-----
...
SSL-Session:
    Protocol  : TLSv1.3
    ...
    Verify return code: 21 (unable to verify the first certificate)

Odpowiedzi

2 SteffenUllrich Aug 18 2020 at 02:42
Certificate chain
 0 s:CN = app.local.example.com
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3

Twój serwer nie jest poprawnie skonfigurowany. Zamiast wysyłać certyfikat liścia (app.local.example.com) i certyfikat pośredni, wysyła tylko certyfikat liścia. Z powodu braku certyfikatu pośredniego nie można utworzyć ścieżki zaufania do lokalnej kotwicy zaufania, co oznacza, że ​​walidacja certyfikatu kończy się niepowodzeniem z komunikatem „nie można uzyskać certyfikatu lokalnego wystawcy” . Przeglądarki często omijają takie problemy, pobierając brakujący certyfikat pośredni z innego miejsca, ale inne stosy TLS zwykle nie zapewniają takich obejść.

Po prawidłowym skonfigurowaniu serwera powinieneś zobaczyć następujące informacje w openssl s_client. Gdy to zrobisz, nginx też powinien działać.

Certificate chain
 0 s:CN = app.local.example.com
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
MarcWoodyard Aug 18 2020 at 13:17

Zmieniłem ssl_certificatewartość z cert.pemna fullchain.pemna serwerze nadrzędnym.

ssl_certificate         /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key     /etc/letsencrypt/live/app.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/app.example.com/chain.pem;

Oto link do plików konfiguracyjnych NGINX, których użyłem