2021-10-10 17:25 (Ultima actualización: 2023-05-13 19:58)
Proxy Inverso Nginx: SSL alert number 40
Este proxy inverso, por lo general utiliza un servidor aguas arriba que es el que realmente contiene el contenido que se sirve. En ocasiones pueden presentarse problemas de conectividad contra éste último. En este caso recibiremos errores que se verán en el registro del sistema con la cadena.
2021/10/10 10:22:14 [error] 2214955#2214955: *231 SSL_do_handshake() failed (SSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:SSL alert number 40) while SSL handshaking to upstream, client: 127.0.0.1, server: www.example.com, request: "GET /uripath HTTP/2.0", upstream: "https://192.168.1.100/", host: "www.example.com"
2021/08/30 10:22:14 [debug] 2214955#2214955: *231 http upstream ssl handshake: "/uripath?"
2021/08/30 10:22:14 [debug] 2214955#2214955: *231 http next upstream, 2
2021/08/30 10:22:14 [debug] 2214955#2214955: *231 free rr peer 6 4
2021/08/30 10:22:14 [warn] 2214955#2214955: *231 upstream server temporarily disabled while SSL handshaking to upstream, client: 127.0.0.1, server: www.example.com, request: "GET /uripath TP/2.0", upstream: "https://192.168.1.100/", host: "www.example.com"
Si examinamos este evento desde la máquina que ejecuta el proxy inverso, contra el servidor del contenido, podemos ver lo siguiente:
openssl s_client -connect 192.168.1.200:443
CONNECTED(00000003)
140542033261888:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1543:SSL alert number 40
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 283 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
Pero si incluimos el nombre de dominio:
openssl s_client -connect 192.168.1.100:443 -servername external.example.com
CONNECTED(00000003)
depth=2 C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
verify return:1
depth=1 C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "Cloudflare, Inc.", CN = sni.cloudflaressl.com
verify return:1
---
Certificate chain
0 s:C = US, ST = California, L = San Francisco, O = "Cloudflare, Inc.", CN = sni.cloudflaressl.com
i:C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
1 s:C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3
i:C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root
---
Server certificate
-----BEGIN CERTIFICATE-----
...
Lo que viene a significar que nuestra instancia de nginx no está encontrando un certificado instalado en el servidor web con el contenido. Por lo que es necesario usar SNI y especificar el nombre del servidor. Por lo tanto, la directiva location ha de quedar similar a la siguiente:
location = / {
proxy_ssl_server_name on;
proxy_pass https://external.example.com/;
}
En la que la clave se encuentra en la línea proxy_ssl_server_name on;