NGINX SSL Proxy inverso Verificar Upstream SSL
Tengo configurado NGINX como un proxy inverso para alojar varios sitios web usando solo una dirección IP. Tengo un certificado de Lets Encrypt en el proxy y otro certificado de Lets Encrypt en el servidor ascendente. Básicamente, necesito que NGINX reenvíe el tráfico al servidor ascendente y verifique que el servidor ascendente tenga un certificado TLS válido. Si lo desactivo proxy_ssl_verify
, funcionará. Si voy a https://app.local.example.com
mi red interna, la aplicación funciona bien.
Diagrama de Red:
https://app.example.com --> NGINX Reverse Proxy --> https://app.local.example.com (Local IP Address)
Archivo de configuración de 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
}
}
Aquí está el mensaje de error que estoy recibiendo.
[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/">
Versión OpenSSL:OpenSSL 1.1.1f 31 Mar 2020
nginx-v:nginx version: nginx/1.18.0 (Ubuntu)
gato /etc/problema:Ubuntu 20.04.1 LTS \n \l
salida deopenssl 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)
Respuestas
Certificate chain
0 s:CN = app.local.example.com
i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
Su servidor no está configurado correctamente. En lugar de enviar el certificado de hoja (app.local.example.com) y el certificado intermedio, solo envía el certificado de hoja. Debido a que falta el certificado intermedio, no se puede crear una ruta de confianza para el ancla de confianza local, lo que significa que la validación del certificado falla con "no se puede obtener el certificado del emisor local" . Los navegadores a menudo solucionan estos problemas al obtener el certificado intermedio faltante de otro lugar, pero otras pilas TLS generalmente no hacen tales soluciones.
Una vez que haya configurado correctamente el servidor, debería ver lo siguiente en openssl s_client
. Una vez hecho esto, nginx también debería funcionar.
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
Cambié el ssl_certificate
valor de cert.pem
a fullchain.pem
en el servidor ascendente.
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;
Aquí hay un enlace a los archivos de configuración de NGINX que usé