记一个开启 ssl_session_tickets 导致的 SSL 证书冲突的问题
很久不写东西了,自己都感觉自己太懒了,有深深的罪恶感了。 今天刚刚好遇到一个 Nginx 的问题,就硬逼着自己一定要写点什么记录一下。
今天在突然发现自己的博客打不开了,提示很奇怪,提示内容是 此网站无法提供安全连接
.
回想了一下这两样的的操作,就是昨晚给服务器加了一个 https 的站点。
假设1:SSL 证书过期了
刚刚开始以为是 SSL 证书问题,看了一下证书的到期,也还有几天就到期了。脆重新去签发一个证书试试,但是重新签发后,发现问题依旧。
再开 B 站点,都是正常的。唯独博客这个站点 A 有问题。
假设2:SSL 证书冲突
那么应该就是配置文件的问题了,首先想到的是是 SSL 证书冲突。
一般来说一个 IP 只能支持一个 SSL 证书,但是在 Nginx 我们可以通过开启 TLS SNI support
来让 Nginx 支持多SSL证书。
xxxx@xxxxxxx> /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.12.2
built with OpenSSL 1.0.1f 6 Jan 2014
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-ipv6 --with-http_sub_module --with-stream --with-http_dav_module --add-module=/root/nginx-dav-ext-module-0.0.3
经过查看, Nginx 是已经开启了 TLS SNI support
了的。那么排除了 Nginx 不支持多个 SSL 证书的问题。
主观和事实需要经过辩证的
两个假设的问题都不对,只能来看余下的配置:
server
{
listen 443;
server_name cong5.net www.cong5.net;
index index.html index.htm index.php default.html default.htm default.php;
root /xxxx/xxxxx/public;
ssl on;
ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/privkey.pem;
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets on;
ssl_stapling on;
ssl_stapling_verify on;
fastcgi_hide_header X-Powered-By;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header Public-Key-Pins 'pin-sha256="FankyFNJUnHYf737yBalLqkC8bWTxZGTCeoMezFgNX0="; pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; max-age=2592000; includeSubDomains';
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
#......
}
从配置信息里面,我设置了 ssl_session_...
这部分是用来 Nginx 共享 session,优化 https 使用的,详细的解释可以看这个: ngx_http_ssl_module
经过一项项排除,发现这里面存在着 ssl_session_tickets
这一项是, ssl_session_tickets
是用来开启浏览器的 Session Ticket
缓存,联想到多个 https 站点,然后感觉有问题部分最大可能性就是它了。
到这一步呢开始进行配置文件对比, 发现博客开启了 Session Ticket: ssl_session_tickets on;
,然后 B 站点没有配置 ssl_session_tickets
。
把两个站点的 ssl_session_tickets 都进行关闭:
ssl_session_tickets off ;
然后重启 Nginx :
/etc/init.d/nginx restart
发现问题解决。
找 Google 大叔去
当我们在 Nginx 里面配置多个 https 的站点的时候,如果有一个站点开启了 ssl_session_tickets ,那么浏览器的就会缓存Session Ticket,然后在下一个请求使用当前的Session Ticket,提升性能;
而然后再新增站点的时候,无论是否设置了 ssl_session_tickets 了。那么都会导致浏览器复用前一个的Session Ticket。
于是就产生了 “此网站无法提供安全连接” 的问题。
信息来源:errors-from-browsers-with-ssl-session-tickets-off-nginx
问题的方法有2种:
第一种:如果 Nginx 的站点配置文件都包含在一个 http{ ... }
里面的,那么可以关闭 ssl_session_tickets: ssl_session_tickets off;
第二种:创建多个 http{ ... }
,然后在每个独立的 http{ ... }
里面就可以分别开启 ssl_session_tickets
了。
最后不得不再次感叹,懒的时候需要逼一逼才能有所产出的。