SNI: 实现多域名虚拟主机的SSL/TLS认证

直到现在,仍然有人认为只有独立 IP 的虚拟主机或 VPS 才能享有 SSL/TLS 连接服务。他们会一本正经地教导你,在 SSL 握手的过程中,根本不会传递域名这条信息,所以服务器端通常返回的是配置中的第一个可用证书;如果要使用多个证书呢,就只能配置不同的 SSL 端口或增加 IP 地址,或者可以花重金使用一个“多域名 SSL 证书”或一个“通配型证书”来达到相同效果。

嗯,这在过去是对的,但不适用于现在了,因为 SNI(Server Name Indication) 技术出现了(实际上早就有了)。换句话说,一个 IP 地址上可以为不同域名分配使用不同的 SSL 证书;这同时意味着,共享 IP 的虚拟主机也可实现 SSL/TLS 连接

拓展阅读:《HTTPS的七个误解》

介绍

早期的 SSLv2 根据经典的公钥基础设施 PKI(Public Key Infrastructure) 设计,它默认认为:一台服务器(或者说一个IP)只会提供一个服务,所以在 SSL 握手时,服务器端可以确信客户端申请的是哪张证书。

但是让人万万没有想到的是,虚拟主机大力发展起来了,这就造成了一个 IP 会对应多个域名的情况。解决办法有一些,例如申请泛域名证书,对所有 *.yourdomain.com 的域名都可以认证,但如果你还有一个 yourdomain.net 的域名,那就不行了。

在 HTTP 协议中,请求的域名作为主机头(Host)放在 HTTP Header 中,所以服务器端知道应该把请求引向哪个域名,但是早期的 SSL 做不到这一点,因为在 SSL 握手的过程中,根本不会有 Host 的信息,所以服务器端通常返回的是配置中的第一个可用证书。因而一些较老的环境,可能会产生多域名分别配好了证书,但返回的始终是同一个。

既然问题的原因是在 SSL 握手时缺少主机头信息,那么补上就是了。

SNI(Server Name Indication,意为“服务器名称指示”) 定义在 RFC 4366,是一项用于改善 SSL/TLS 的技术,在 SSLv3/TLSv1 中被启用。它允许客户端在发起 SSL 握手请求时(具体说来,是客户端发出 SSL 请求中的 ClientHello 阶段),就提交请求的 Host 信息,使得服务器能够切换到正确的域并返回相应的证书。

要使用 SNI,需要客户端和服务器端同时满足条件,幸好对于现代浏览器来说,大部分都支持 SSLv3/TLSv1,所以都可以享受 SNI 带来的便利。

nginx / apache 服务器端实现

Nginx 和 Apache 服务端支持 SNI 参见:

《nginx 同一个IP上配置多个HTTPS主机》
《apache mod_gnutls实现多HTTPS虚拟主机》

支持SNI的浏览器、服务器、库

  • Internet Explorer 7 及更高版本(Windows Vista 及更高版本操作系统上的),Windows XP 的 Internet Explorer 总不支持,哪怕是 Internet Explorer 8。
  • Mozilla Firefox 2.0 及更高版本
  • Opera 8.0 及更高版本 (必须开启 TLS 1.1 协议)
  • Opera Mobile 至少是 10.1 beta 的 Android 版本
  • Google Chrome (Vista 或更高版本;XP 上的话要求 Chrome 6 及更高版本;OS X 10.5.7 及更高版本要求 Chrome 5.0.342.1 及更高版本)
  • Safari 2.1 及更高版本 (Mac OS X 10.5.6 及更高版本或 Windows Vista 及更高版本)
  • Konqueror/KDE 4.7 及更高版本
  • MobileSafari (在 Apple iOS 4.0 及更高版本的环境下的)
  • Android 默认浏览器 (在 Honeycomb 及更高版本的)
  • Windows Phone 7
  • MicroB (在 Maemo 下的)

支持SNI的服务器

  • Apache 2.2.12 及更高版本 使用 mod_ssl (或用试验性的 mod_gnutls 代替)
  • Cherokee 如果编译了 TLS 支持
  • 打了补丁的 lighttpd 1.4.x 或 1.5.x ,1.4.24+ 没打补丁就行
  • Nginx 在以 SNI 为支持的 OpenSSL 的陪同下
  • LiteSpeed 4.1 及更高版本
  • Pound 2.6 及更高版本
  • Apache Tomcat (Java 7) 及更高版本
  • Microsoft Internet Information Server (IIS) 8

支持SNI的库

  • Mozilla NSS 3.11.1 仅在客户端
  • OpenSSL
  • 0.9.8f (2007年10月11日发布) - 不缺省编译,可用设置选项 ‘–enable-tlsext’ 编译
  • 0.9.8j (2009年1月7日发布) 至 1.0.0 (2010年3月29日发布) – 缺省编译
  • GNU TLS
  • libcurl / cURL 至少 7.18.1 (2008年3月30日) 在 SNI 支持下编译一个 SSL/TLS 工具包
  • Python 3.2 (ssl, urllib 和 httplib 模块)
  • Qt 4.8
  • Oracle Java 7 JSSE

参考文档:http://blog.hesey.net/2012/02/sni-for-multi-domain-ssl-tls.html
http://serverfault.com/questions/109800/multiple-ssl-domains-on-the-same-ip-address-and-same-port

在共享 IP 主机上添加 SSL 支持

按照一般步骤安装 SSL 证书【生成证书请求文件(顺便生成私钥)→到 SSL 服务商生成证书→合并证书扔进去】,然后修改下网站资源链接即可。只要主机面板(如 cPanel)有相关选项,就应该没有内部技术问题(少数时候服务器不支持,此时应该联系主机商)

cPanel 下“SSL/TLS 管理器”中的“管理 SSL 主机”会提示道:

注意:您没有一个独立 IP。因此,当用户访问您任何一个 SSL 网站时,不支持 SNI 的浏览器很可能会向用户发出安全警告。Windows XP 上的 Microsoft Internet Explorer 是最广泛使用而不支持 SNI 的浏览器。

经实际测试,虚拟主机共享 IP 上首个安装 SSL 证书的人看起来有特权——整个 IP 都“安装上”那个证书了。可以推得也可以观察到,不支持 SNI 的浏览器在需要 SSL 证书时也将请求到这首个安装的证书。这对有“特权”的那个站(即第一个安装 SSL 的站点)是好的,因为这非常好地兼容了不支持 SNI 的浏览器,使其总是不会发出警告,但主机上邻居们的 https 访问就悲催了。如果邻站安装了 SSL 证书,一个使用不支持 SNI 技术的浏览器去访问 https 站的访客将收到证书上域名不匹配的警告,即便忽略警告后访问的是目标站,但因证书不是预期的目标站的证书,此访客也存有中招中间人攻击的风险;更令人不安的是,若邻站没有安装 SSL 证书,使用不论支持 SNI 与否的浏览器去访问 https 站的访客将收到相同警告,忽略后会访问到有“特权”的那个站而非目标站(至少在 cPanel 主机如此),而此时“特权站长”除了能够发起中间人攻击外,更是可以十分方便省事地制作一个特别的网站,可以是各种跳转页,可以是恶作剧网站,更可以是……钓鱼网站之类的非法网站

什么?你在问闪星空间是否已经支持 SSL 访问?当然!本博客是一个成功案例,嗯,也体现在上述“特权”上……

版权声明

此文一半多来自运维生存时间,一部分来自闪星空间,转载本文时请保留这两个链接,谢谢。

2014-7-29 P.S.更新“在共享 IP 主机上添加 SSL 支持”一节。

若无特别说明,本文系原创,遵循 署名-非商业性使用 3.0 (CC BY-NC 3.0) 协议,转载文章请注明来自【闪星空间】,或链接上原文地址:http://shansing.com/read/355/

24 条评论

  1. 貌似也算旧新闻了

    1. 是旧闻,但是很多人(包括之前的我)还停留在更旧的时期。

  2. 是哪儿买的 SSL 证书啊?

    1. Namecheap 送了一个,剩下的在某宝买的。

  3. 很早就知道惹。

    1. 所以像我这种近似渣渣的才蒙在鼓中那么久呢。

      1. Wis Wis

        嗯,我也是渣渣……

        1. Test for comment.

          1. 你确定不是“comment for test"?

            1. 顺手就打出来了原谅我这个英语渣叭

  4. 貌似很厉害的样子~现在都wantypecho了,wordpress看样子要没落了~555555

    1. Typecho 小巧呀!但是话说 WordPress 怎么会没落呢?不要担心嘛。

  5. 那这个 SNI 也不大好啊。

  6. Young Young

    WoSign DVSSL 免费SSL证书可支持多个域名
    像我这种草根站长挖掘了各类免费资源hhhhhh

    1. 沃通证书的兼容性不是很好,不过有免费的多域名SSL证书真是吓了我一跳呢!

  7. 如果是购买的虚拟主机,不知道可不可以?

  8. 证书也能在X宝买?
    有安全隐患吗?

    1. 特别的渠道。没有安全隐患。

  9. [...]这篇文章应该是闪闪的星朋友在帮助我处理“单IP绑定多域名配置SSL”和“使用独立域名作为图片地址”时的心得和总结,我认识闪闪的星起因是自己在配置https的时候无从下手,百度搜了一些关键词后,看到了闪闪的星的一篇文章《SNI: 实现多域名虚拟主机的SSL/TLS认证》,这品文章写的头头是道有理有据,虽然我没能按照文中的步骤配置好自己的https,但是却让我认定了,这是一位牛逼人物,找他请教应该所向[...]

  10. [...]SNI: 实现多域名虚拟主机的SSL/TLS认证[...]

  11. [...]SNI: 实现多域名虚拟主机的SSL/TLS认证[...]

  12. ...这篇文章应该是闪闪的星朋友在帮助我处理“单IP绑定多域名配置SSL”和“使用独立域名作为图片地址”时的心得和总结,我认识闪闪的星起因是自己在配置https的时候无从下手,百度搜了一些关键词后,看到了闪闪的星的一篇文章《SNI: 实现多域名虚拟主机的SSL/TLS认证》,这品文章写的头头是道有理有据,虽然我没能按照文中的步骤配置好自己的https,但是却让我认定了,这是一位牛逼人物,找他请[...]

  13. [...]SNI: 实现多域名虚拟主机的SSL/TLS认证[...]

发表评论»

NO SPAMS! 不要发垃圾评论哦!

表情