I try to configure an Nginx server as a reverse proxy so the https requests it receives from clients are forwarded to the upstream server via https as well.
Here's the configuration that I use:
http {
# enable reverse proxy
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwared-For $proxy_add_x_forwarded_for;
upstream streaming_example_com
{
server WEBSERVER_IP:443;
}
server
{
listen 443 default ssl;
server_name streaming.example.com;
access_log /tmp/nginx_reverse_access.log;
error_log /tmp/nginx_reverse_error.log;
root /usr/local/nginx/html;
index index.html;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_verify_client off;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location /
{
proxy_pass https://streaming_example_com;
}
}
}
Anyway, when I try to access a file using reverse proxy this is the error I get in reverse proxy logs:
2014/03/20 12:09:07 [error] 4113079#0: *1 SSL_do_handshake() failed (SSL: error:1408E0F4:SSL routines:SSL3_GET_MESSAGE:unexpected message) while SSL handshaking to upstream, client: 192.168.1.2, server: streaming.example.com, request: "GET /publishers/0/645/_teaser.jpg HTTP/1.1", upstream: "https://MYSERVER.COM:443/publishers/0/645/_teaser.jpg", host: "streaming.example.com"
Any idea what I am doing wrong?
I found what was the error, I needed to add
proxy_ssl_session_reuse off;
In my case, I was trying to reverse proxy a website behind Cloudflare. I got the same error in
/var/log/nginx/error.log
. I tried many solutions and this one worked for me:See nginx documentation:
If a server terminates the TLS connection first with a server-global TLS certificate, it can look at the HTTP Host header to figure out which user/application should receive the HTTP request. But if the server serves domains with different TLS certificates (what all CDNs like Cloudflare do), the server needs to know which TLS private-key to use for TLS termination. Therefore it needs to look at the unencrypted TLS SNI header, as the HTTP Host header is still encrypted.
This fully solved the issue for me:
I also had to add
proxy_ssl_name
in order to make sure that nginx knew what name to pass to the upstream https server.