由于SSL证书是在http请求之前,所以web组件无法判断域名,也就很难根据域名来返回正确的证书
但解决方法总是有的,SSL的一个扩展:Server Name Indication,可以让客户端在SSL协商时发送域名给服务器,从而解决问题。
坏处是并不是所有浏览器都支持,不过本人实测,电脑的IE8、Chrome、安卓的UC和chrome都可以正常使用。我等穷逼的福音,再组合只能管单个域名的证书,就可以华丽丽的上SSL了!
大致实现方式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$SERVER["socket"] == ":443" { ssl.engine = "enable" ssl.pemfile = "/srv/www/随意1个站的.pem" ssl.ca-file = "/srv/www/统一.ca" #如果不是统一的,分别增加在每个host内 $HTTP["host"] == "站1" { ssl.pemfile = "/srv/www/站1.pem" } $HTTP["host"] == "站2" { ssl.pemfile = "/srv/www/站2.pem" } $HTTP["host"] == "站3" { ssl.pemfile = "/srv/www/站3.pem" } } |
注意,这里不再需要加其他内容~ 不要重复添加server.document-root什么的,不需要的。
此外,本人因为基础不扎实,研究一个问题浪费了大半个下午: ca-file的作用,在于针对那些不是直接用顶级ca签署的证书,所以大部分情况下是要完整填写ca链路的,否则就有可能出现电脑上证书正常,安卓设备上证书不正常的情况。 很容易误会为兼容性问题,实际上就是中间的ca没有声明好。 如果你的证书是在同一个中间ca申请的,那么可以像上述那样搞,如果不是,那么在每个$HTTP[“host”]内还需要加上自己的ca,是否可以我还没有测试过,我只测试了同一个中间ca的不同证书。
得知SNI是在搜索的时候从nginx的相关介绍里找到的,差点有想换nginx的冲动(nginx的配置文件看起来比Lighttpd简洁一些),后来发现原来Lighttpd也早就支持了,只是没有人发详细的介绍出来,官方的docs里是有的,看来Lighttpd还是非常不错。