NGINX SSL Reverse Proxy Verifiziert Upstream-SSL

Aug 18 2020

Ich habe NGINX als Reverse-Proxy eingerichtet, um mehrere Websites mit nur einer IP-Adresse zu hosten. Ich habe ein Lets Encrypt-Zertifikat auf dem Proxy und ein anderes Lets Encrypt-Zertifikat auf dem Upstream-Server. Grundsätzlich brauche ich NGINX, um den Datenverkehr an den Upstream-Server weiterzuleiten und zu überprüfen, ob der Upstream-Server über ein gültiges TLS-Zertifikat verfügt. Wenn ich deaktiviere proxy_ssl_verify, funktioniert es. Wenn ich in https://app.local.example.commein internes Netzwerk gehe, funktioniert die App einwandfrei.

Netzwerkdiagramm:

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

NGINX-Reverse-Proxy-Konfigurationsdatei:

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
        }
}

Hier ist die Fehlermeldung, die ich bekomme.

[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/">

OpenSSL-Version:OpenSSL 1.1.1f 31 Mar 2020

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

Katze /etc/Problem:Ubuntu 20.04.1 LTS \n \l

Ausgabe vonopenssl 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)

Antworten

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

Ihr Server ist nicht richtig konfiguriert. Anstelle des Blattzertifikats (app.local.example.com) und des Zwischenzertifikats wird nur das Blattzertifikat gesendet. Aufgrund des fehlenden Zwischenzertifikats kann kein Vertrauenspfad zum lokalen Vertrauensanker erstellt werden, was bedeutet, dass die Zertifikatsvalidierung mit "Unable to Get Local Issuer Certificate" fehlschlägt . Browser umgehen solche Probleme oft, indem sie das fehlende Zwischenzertifikat von woanders beziehen, aber andere TLS-Stacks führen solche Problemumgehungen normalerweise nicht durch.

Sobald Sie den Server richtig konfiguriert haben, sollten Sie Folgendes in sehen openssl s_client. Sobald dies erledigt ist, sollte nginx auch funktionieren.

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

Ich habe den ssl_certificateWert cert.pemauf fullchain.pemdem Upstream-Server von auf geändert.

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;

Hier ist ein Link zu den von mir verwendeten NGINX-Konfigurationsdateien