Apache-2.2

Nginx 連接到上游 Apache:重新協商握手失敗

  • March 24, 2017

我正在配置將用作反向代理的新 Nginx 伺服器。我們有執行 Apache 的舊 Debian 伺服器。在這個 apache 伺服器上是只有 HTTPS 訪問的站點,我想隱藏在代理後面。

從代理到上游 Apache 的連接必須通過 HTTPS(伺服器位於不同的位置,並且 apache 只允許 HTTPS 訪問)。

我的問題是從 Nginx 到 Apache 的連接失敗。通過 HTTPS 從瀏覽器到上游的正常連接可以正常工作。從同一代理到 Nginx 上游的連接有效。當 Nginx 嘗試連接到上游 Apache 連接失敗時,重新協商握手失敗

來自代理 Nginx(調試級別)的日誌僅顯示:

2016/04/07 15:51:08 [error] 5855#0: *1 upstream prematurely closed connection while reading response header from upstream, client: 94.113.97.9, server: procrastination.com, request: "GET / HTTP/1.1", upstream: "https://77.240.191.234:443/", host: "procrastination.com"

來自上游 Apache 的日誌:

[Thu Apr 07 15:36:48 2016] [info] Initial (No.1) HTTPS request received for child 35 (server procrastination.com:443)
[Thu Apr 07 15:36:48 2016] [debug] ssl_engine_kernel.c(421): [client 83.167.254.21] Reconfigured cipher suite will force renegotiation
[Thu Apr 07 15:36:48 2016] [info] [client 83.167.254.21] Requesting connection re-negotiation
[Thu Apr 07 15:36:48 2016] [debug] ssl_engine_kernel.c(764): [client 83.167.254.21] Performing full renegotiation: complete handshake protocol (client does support secure renegotiation)
[Thu Apr 07 15:36:48 2016] [info] [client 83.167.254.21] Awaiting re-negotiation handshake
[Thu Apr 07 15:36:58 2016] [error] [client 83.167.254.21] Re-negotiation handshake failed: Not accepted by client!?

我在代理上的 Nginx 站點配置:

server {
 listen 80;
 listen 443 ssl;

 server_name procrastination.com *.procrastination.com;

 ###
 # SSL
 ###
 ssl  on;
 ssl_certificate         /etc/ssl/localcerts/procrastination.com/fullchain.pem;
 ssl_certificate_key     /etc/ssl/localcerts/procrastination.com/privkey.pem;

 ##
 # Logging Settings
 ##
 access_log /var/log/nginx/procrastination_proxy-access.log;
 error_log /var/log/nginx/procrastination_proxy-error.log debug;


 include /etc/nginx/snippets/common;
 include /etc/nginx/snippets/proxy_params;

 location / {
   proxy_pass https://brigita_https;
   proxy_ssl_name $host;
 }
}

代理上 nginx.conf 的 SSL 相關部分:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

上游的 Apache 站點配置:

<VirtualHost 77.240.191.234:80>
 ServerName procrastination.com
 ServerAlias *.procrastination.com
 DocumentRoot /var/www/procrastination-production/build/current/www
 php_value newrelic.appname /var/www/procrastination-production/build/current/www

 RewriteEngine On
 RewriteCond %{HTTPS} !=on
 RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L]

</VirtualHost>


<VirtualHost 77.240.191.234:443>
 ServerName procrastination.com
 ServerAlias *.procrastination.com
 DocumentRoot /var/www/procrastination-production/build/current/www
 php_value newrelic.appname /var/www/procrastination-production/build/current/www

 SSLEngine On
 SSLCertificateFile /etc/apache2/ssl/ssl_procrastination_com.crt
 SSLCertificateKeyFile /etc/apache2/ssl/ssl_procrastination_com.key

 RewriteCond %{HTTP_HOST} !^www\..*$
 RewriteRule (.*) https://www.%{HTTP_HOST}%{REQUEST_URI} [L]

</VirtualHost>

其他 Apache 配置值是預設值。

知道可能是什麼原因或在哪裡尋找更多診斷數據?

解決了!

問題出在 Apache 上游的 SNI 中。Nginx 沒有傳遞正確的參數,Apache 給他發送了錯誤的證書。

您需要**proxy_ssl_server_name on**在 Nginx 配置中進行設置。

只是改變:

 location / {
   proxy_pass https://brigita_https;
   proxy_ssl_name $host;
 }

到:

 location / {
   proxy_pass https://brigita_https;
   proxy_ssl_name $host;
   proxy_ssl_server_name on;
 }

引用自:https://serverfault.com/questions/768802