Tengo NGINX configurado como proxy inverso para alojar varios sitios web usando una sola dirección IP. Tengo un certificado Lets Encrypt en el proxy y un certificado Lets Encrypt diferente 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 accedo https://app.local.example.com
a 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 recibo.
[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)
Respuesta1
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 un certificado hoja (app.local.example.com) y un certificado intermedio, solo envía el certificado hoja. Debido a que falta el certificado intermedio, no se puede crear una ruta de confianza al 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 obteniendo el certificado intermedio faltante de otro lugar, pero otras pilas TLS generalmente no solucionan este tipo de soluciones.
Una vez que haya configurado correctamente el servidor, debería ver lo siguiente en openssl s_client
. Una vez hecho esto, nginx debería funcionar también.
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
Respuesta2
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 utilicé