前几天帮肾上TR@SOE(CSDN唯一一个用户名里有特殊字符的用户)部署一个HTTPS,虽然去年写过用Let’s Encrypt证书部署HTTPS的文章,但是这次略有不同,所以作个记录吧,顺便也把常见的做法都说一说。
常见的部署环境和条件有以下几种情况组合:
免费证书和商业证书本质上是一样的,都是可以被系统承认的证书,只是申请方式不同而已。
配置一个HTTPS服务所需要的证书包括几个部分:
创建证书的基本流程是这样:
其中前两个步骤都是一样的,在这里统一说明一下。
生成服务器私钥:
openssl genrsa -out server.key 4096
输出的server.key文件就是服务器私钥,4096是密钥长度,要求不高的话用2048也可。
生成CSR:
openssl req -new -sha256 -key server.key -out yoursite.csr
因为sha1已经不安全,所以这里用了sha256,可能太旧的客户端(比如win98?)会不支持。
yoursite.csr就是生成的CSR,yoursite建议用你的网站名标识会比较方便识别。
然后按提示输入:
生成CRT:
openssl x509 -req -days 3650 -in yoursite.csr -signkey server.key -out yoursite.crt
其中签名用的KEY就是自己的服务端私钥,所以这是一个自签名证书。
有效期为3650天(即十年)。
参见旧文《Let’s HTTPS》。
首先找一个商业证书机构(CA)或其代理商下一个证书订单。
其次是选择证书类型。
商业证书有很多类型,也有很多的CA可以选择,不同的CA,不同的类型价格也不一样。
常见的CA有:
以上以价格从高到低排序。除此之外当然还有很多,具体可以打开你的系统证书列表看看。
需要特别说一句的就是:臭名昭著的CNNIC和沃通(WoSign,包括免费的StartSSL),已经被证明不安全,建议将它们从系统中删除,并且不要去申请使用它们的证书。
常见的证书类型有三种:
验证级别从低到高排序,价格也是如此。
DV证书只验证域名,在最终访问者那边查看证书时将不会包含CSR中的组织信息,只有域名信息,也就是说你就算是在CSR里输入你是GOOGLE,到了客户端那里也是看不到的。
OV证书除了验证域名还需要验证组织,即你需要提供证据证明你在CSR里输入的公司或组织的确是你, 这样才能在客户端证书里查看到你的组织信息。
EV证书就要求更高了,通常是金融机构之类的用。
除此之外,证书还有一种区别:
一样是价格从高到低排序。
单域名证书就是只能用于一个域名的证书,某些商业证书可以提供两个域名:带WWW的和不带WWW的。
多域名证书就是一个证书可以用于多个域名,默认支持三个域名,当然增加域名需要加钱,但比单独买单域名证书要便宜。适用于一个公司有多个域名,而且多个域名部署在一个服务器上,使用一个证书会比较省事,也比较便宜。
泛域名证书就是一个证书可以用于一个域名下的任意多个子域名。
一般申请流程(仅指DV类型)如下:
其中各验证方式大致如下:
通过验证后即可获得证书。
证书内容一般包括:域名的CRT,证书机构的CRT链(可能有多个),根证书CRT(CA的证书),如果用服务商的工具生成CSR,还应该会有CSR和KEY。
分别以最常用的Apache和Nginx为例,其它WebServer请参考相关文档。
这里只介绍Apache2(以2.4为例)。
HTTPS的基本配置可以直接套用默认配置,只是要改一下证书文件的部分:
SSLEngine on
SSLCertificateFile /path_to_ssl/yoursite.crt
SSLCertificateKeyFile /path_to_ssl/yoursite.key
SSLCertificateChainFile /path_to_ssl/server-ca.crt
其中yoursite.crt和yoursite.key就是前面说过的私钥和域名证书。
重点说一下server-ca.crt,这个就是前面谈到商业证书时提到的中间证书链(包括CA根证书)。对于Let’s Encrypt这样的免费证书,这个就是Let’s Encrypt的证书(见旧文),对于自签名证书,这一项可以去掉。
中间证书链的生成方法如下:
cat provider.crt provider-parent.crt root.crt > server-ca.crt
很简单,就是把那一堆证书串起来生成一个证书文件即可,不过需要注意顺序,从最低级的证书(你的域名证书的上一级)开始到最高级的CA根证书。
Apache从2.2.12开始支持SNI,可以为多个域名的虚拟主机使用各自独立的证书,用法与HTTP虚拟主机类似,只需要在每个虚拟主机配置里加上相应的证书配置即可。
需要注意的是:WinXP,JAVA6,Android 2.3等不支持SNI。
最后,如我在去年的旧文里所说,SSLv2/v3之类的协议和某些SSL加密算法已经不再安全,所以在没有特定的兼容性需要的情况下,需要配置禁用这些不安全的选项。
在全局配置(注意,不是单个虚拟主机配置里)里加上:
SSLProtocol TLSv1 +TLSv1.1 +TLSv1.2
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:!DHE-RSA-AES128-GCM-SHA256:!DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:!DHE-RSA-AES128-SHA256:!DHE-RSA-AES128-SHA:!DHE-DSS-AES128-SHA256:!DHE-RSA-AES256-SHA256:!DHE-DSS-AES256-SHA:!DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
以上协议和加密算法都是目前还安全的,并且提供了最大可能的兼容性。未来如果出现新的安全问题,请自行调整。
基本上在旧文里都说过了,这里再总结一下。
相比Apache的配置,Nginx没有单独的中间证书链项目,所以是把中间证书链和域名证书串在一起作为完整的域名证书来用:
cat yoursite.crt server-ca.crt > new_yoursite.crt
配置HTTPS:
ssl on;
ssl_certificate "/path_to_ssl/new_yoursite.crt";
ssl_certificate_key "/path_to_ssl/yoursite.key";
SNI配置见旧文,从略。
全局安全配置:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:!DHE-RSA-AES128-GCM-SHA256:!DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:!DHE-RSA-AES128-SHA256:!DHE-RSA-AES128-SHA:!DHE-RSA-AES256-SHA256:!DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS;
配置完成后重启服务即可生效。
不论是用Apache还是Nginx,都建议配置完HTTPS以后到SSL Labs验证一下安全性。