Proxy inverso NGINX SSL Verifica SSL a monte
Ho configurato NGINX come proxy inverso per ospitare più siti Web utilizzando un solo indirizzo IP. Ho un certificato Lets Encrypt sul proxy e un altro certificato Lets Encrypt sul server upstream. Fondamentalmente, ho bisogno di NGINX per inoltrare il traffico al server upstream e verificare che il server upstream abbia un certificato TLS valido. Se disattivo proxy_ssl_verify
, funzionerà. Se vado https://app.local.example.com
sulla mia rete interna, l'app funziona bene.
Diagramma di rete:
https://app.example.com --> NGINX Reverse Proxy --> https://app.local.example.com (Local IP Address)
File di configurazione del proxy inverso 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
}
}
Ecco il messaggio di errore che sto ricevendo.
[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/">
Versione OpenSSL:OpenSSL 1.1.1f 31 Mar 2020
nginx-v:nginx version: nginx/1.18.0 (Ubuntu)
cat /etc/problema:Ubuntu 20.04.1 LTS \n \l
Uscita diopenssl 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)
Risposte
Certificate chain
0 s:CN = app.local.example.com
i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
Il tuo server non è configurato correttamente. Invece di inviare il certificato foglia (app.local.example.com) e il certificato intermedio, invia solo il certificato foglia. A causa del certificato intermedio mancante, non è possibile creare alcun percorso di attendibilità verso l'ancora di attendibilità locale, il che significa che la convalida del certificato non riesce con "impossibile ottenere il certificato dell'emittente locale" . I browser spesso risolvono tali problemi ottenendo il certificato intermedio mancante da qualche altra parte, ma altri stack TLS di solito non eseguono tali soluzioni alternative.
Dopo aver configurato correttamente il server, dovresti vedere quanto segue in openssl s_client
. Una volta fatto questo, anche nginx dovrebbe funzionare.
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
Ho cambiato il ssl_certificate
valore da cert.pem
a fullchain.pem
sul server upstream.
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;
Ecco un link ai file di configurazione NGINX che ho usato