Nginx 反向代理到 Heroku 的 SSL 握手失败
Nginx reverse proxy to Heroku fails SSL handshake
不幸的是,我不是一个系统管理员,遇到了一个让我头撞墙的问题。
简而言之,我 运行 在 EC2 (Ubuntu 14.04.4 LTS) 上使用 Nginx 来 (a) 托管我公司的营销网站 (https://example.com,顺便说一句是 Wordpress)和 (b) 作为我们在 Heroku (https:// app.example.com) 上的 Rails 应用程序 运行ning 的反向代理,用于某些路径。我们对 example.com 和 app.example.com 使用相同的 SSL 证书。所有这一切在 8-10 个月内都运行良好,但我最近从 Heroku 的付费 SSL 插件切换到新的免费 SSL 产品,现在我们的反向代理坏了。
在检查 Nginx 错误日志时,我看到以下内容:
SSL_do_handshake() failed (SSL: error:14094438:SSL
routines:SSL3_READ_BYTES:tlsv1 alert internal error:SSL alert number
80) while SSL handshaking to upstream, client: ipaddress1, server:
example.com, request: "GET /proxiedpath/proxiedpage HTTP/1.1",
upstream: "https:// ipaddress2:443/proxiedpath/proxiedpage", host:
"example.com"
我试图四处寻找一些额外的指导 - 我已经升级了 Nginx (1.10.1) 和 OpenSSL (1.0.2h),但没有成功。我怀疑这个问题可能是由于 Heroku 在新的免费 SSL 功能中使用了 SNI (https://devcenter.heroku.com/articles/ssl-beta),但无法确定这可能是个问题的原因。
我对这一点的探索还有几点补充:
当我切换到新的免费 Heroku SSL 时,我按照文档的指示将 app.example.com DNS 记录更改为指向 app.example.com.herokudns.com。该应用程序可以通过 app.example.com 正常访问,当我 运行 在 app.example.com 和 app.example.com.herokudns.com 上进行 nslookup 时,我得到了相同的 IP 地址。然而...
我无法通过 nslookup 返回的 IP 地址或 app.example.com.herokudns.com 访问该应用程序。我怀疑这是正常的并且是预料之中的,但不知道到底为什么会这样。还有...
从 nslookup 返回的 IP 地址与上面日志错误消息中引用的 IP 地址不同 ("ipaddress2")。事实上,"ipaddress2" 在整个日志中并不一致 - 它似乎定期更改。又一次,我不知道我不知道什么……Heroku 端的负载平衡?
最后,我的Nginx反向代理配置如下nginx.conf:
http {
client_max_body_size 500M;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_names_hash_bucket_size 64;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
server {
listen 443 default_server;
server_name example.com;
root /usr/share/nginx/html;
index index.php index.html index.htm;
ssl on;
ssl_certificate mycompanycert.crt;
ssl_certificate_key mycompanykey.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ^~ /proxiedpath/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_pass https://app.example.com/proxiedpath/;
}
}
}
非常感谢任何帮助 - 非常感谢!
我今天能够解决这个问题,并且想 post 解决方案以防其他人 运行 遇到同样的问题。
原来是SNI问题。我在 nginx.org:
上找到了这张票
https://trac.nginx.org/nginx/ticket/229
这让我想到了 proxy_ssl_server_name 指令:
http://nginx.org/r/proxy_ssl_server_name
通过在您的配置中设置为 "on",您将能够使用 SNI 代理到上游主机。
感谢所有提出建议的评论!
请注意,Heroku 强加的相关条件是 HOST 字段必须与自定义域名匹配。
所以除了 proxy_ssl_server_name
你可能还想设置这样一行:
proxy_set_header Host mycustomdomain.com;
当然,这仅适用于传入服务器的主机字段与您的服务器所在的域不同的情况。
您得到的具体错误是:
SSL certificate error
There is conflicting information between the SSL connection, its certificate and/or the included HTTP requests.
请尝试添加proxy_ssl_server_name on
location ^~ /proxiedpath/ {
proxy_ssl_server_name on;
}
不幸的是,我不是一个系统管理员,遇到了一个让我头撞墙的问题。
简而言之,我 运行 在 EC2 (Ubuntu 14.04.4 LTS) 上使用 Nginx 来 (a) 托管我公司的营销网站 (https://example.com,顺便说一句是 Wordpress)和 (b) 作为我们在 Heroku (https:// app.example.com) 上的 Rails 应用程序 运行ning 的反向代理,用于某些路径。我们对 example.com 和 app.example.com 使用相同的 SSL 证书。所有这一切在 8-10 个月内都运行良好,但我最近从 Heroku 的付费 SSL 插件切换到新的免费 SSL 产品,现在我们的反向代理坏了。
在检查 Nginx 错误日志时,我看到以下内容:
SSL_do_handshake() failed (SSL: error:14094438:SSL routines:SSL3_READ_BYTES:tlsv1 alert internal error:SSL alert number 80) while SSL handshaking to upstream, client: ipaddress1, server: example.com, request: "GET /proxiedpath/proxiedpage HTTP/1.1", upstream: "https:// ipaddress2:443/proxiedpath/proxiedpage", host: "example.com"
我试图四处寻找一些额外的指导 - 我已经升级了 Nginx (1.10.1) 和 OpenSSL (1.0.2h),但没有成功。我怀疑这个问题可能是由于 Heroku 在新的免费 SSL 功能中使用了 SNI (https://devcenter.heroku.com/articles/ssl-beta),但无法确定这可能是个问题的原因。
我对这一点的探索还有几点补充:
当我切换到新的免费 Heroku SSL 时,我按照文档的指示将 app.example.com DNS 记录更改为指向 app.example.com.herokudns.com。该应用程序可以通过 app.example.com 正常访问,当我 运行 在 app.example.com 和 app.example.com.herokudns.com 上进行 nslookup 时,我得到了相同的 IP 地址。然而...
我无法通过 nslookup 返回的 IP 地址或 app.example.com.herokudns.com 访问该应用程序。我怀疑这是正常的并且是预料之中的,但不知道到底为什么会这样。还有...
从 nslookup 返回的 IP 地址与上面日志错误消息中引用的 IP 地址不同 ("ipaddress2")。事实上,"ipaddress2" 在整个日志中并不一致 - 它似乎定期更改。又一次,我不知道我不知道什么……Heroku 端的负载平衡?
最后,我的Nginx反向代理配置如下nginx.conf:
http {
client_max_body_size 500M;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_names_hash_bucket_size 64;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
server {
listen 443 default_server;
server_name example.com;
root /usr/share/nginx/html;
index index.php index.html index.htm;
ssl on;
ssl_certificate mycompanycert.crt;
ssl_certificate_key mycompanykey.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ^~ /proxiedpath/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_pass https://app.example.com/proxiedpath/;
}
}
}
非常感谢任何帮助 - 非常感谢!
我今天能够解决这个问题,并且想 post 解决方案以防其他人 运行 遇到同样的问题。
原来是SNI问题。我在 nginx.org:
上找到了这张票https://trac.nginx.org/nginx/ticket/229
这让我想到了 proxy_ssl_server_name 指令:
http://nginx.org/r/proxy_ssl_server_name
通过在您的配置中设置为 "on",您将能够使用 SNI 代理到上游主机。
感谢所有提出建议的评论!
请注意,Heroku 强加的相关条件是 HOST 字段必须与自定义域名匹配。
所以除了 proxy_ssl_server_name
你可能还想设置这样一行:
proxy_set_header Host mycustomdomain.com;
当然,这仅适用于传入服务器的主机字段与您的服务器所在的域不同的情况。
您得到的具体错误是:
SSL certificate error
There is conflicting information between the SSL connection, its certificate and/or the included HTTP requests.
请尝试添加proxy_ssl_server_name on
location ^~ /proxiedpath/ {
proxy_ssl_server_name on;
}