八个HTTPS和SSL优化使用心得-减少等待时间和降低Https性能损耗

随着大家上网安全意识的增强,以及各大主要互联网公司对Https普及工作的推动,HTTPS SSL现在基本上成了建站的标配了。得益于Let’s Encrypt、Digicert、TrustAsia、Symantec等提供的免费SSL证书,现在不管是个人建站还是企业建站,上Https的成本可以忽略不计了。

为了安全,我们要上Https,但是开启 SSL 会增加内存、CPU、网络带宽的开销。相对于http,使用TCP 三次握手建立连接,客户端和服务器需要交换3个包,https除了 TCP 的三个包,还要加上 ssl握手需要的9个包,一共是12个包。所以,HTTPS优化得不少反而容易出现性能慢的问题。

当然,有人可能为会认为HTTPS与SSL增加的服务器开销基本上没有感觉到,这是因为网站的流量比较少,加上服务器的性能配置足以支撑起当前的流量。但是对于大型的网站,例如百度、Google以及热门APP,优化Https性能,减少资源消耗还是非常有用的。

八个HTTPS和SSL优化使用心得-减少等待时间降低Https性能损耗加大SSL缓存

本篇文章就来分享一下HTTPS和SSL优化使用几点心得体会,更多的有关于SSL证书和Https经验教程还有:

  1. 免费SSL证书收集整理汇总-免费给网站添加Https安全加密访问
  2. 十个你可能不知道的CloudFlare免费CDN加速技巧-SSL\DDOS\Cache
  3. 启用HSTS并加入HSTS Preload List让网站Https访问更加安全-附删除HSTS方法

一、如何选择免费SSL证书?

建议选择Let’s Encrypt。Let’s Encrypt免费SSL证书虽然只有90天,但是可以无限期续期,并且支持手动和自动续期。Let’s Encrypt SSL在各大浏览器上都得到认可,是免费SSL证书的首选。教程:Let’s Encrypt Wildcard 免费泛域名SSL证书一键申请与SSL使用教程

如何选择免费SSL证书

Let’s Encrypt适用于VPS等有独立IP的主机上,否则只能使用一些利用Let’s Encrypt API开发的在线SSL证书申请。当然,有一定的经济实力的话自然选择付费的SSL证书更为可行,更多SSL证书见:免费SSL证书收集整理汇总

二、服务器开启HSTS

采用 HSTS 协议的网站将保证浏览器始终连接到网站的HTTPS版本,而不需要用户手动在URL地址栏中输入包含https://的加密地址。我用的是Nginx 服务器,只需要编辑 Nginx 配置文件(如:/usr/local/nginx/conf/nginx.conf)将下面行添加到 HTTPS 配置的 server 块中即可:

add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

Apache、Lighttpd等启用HSTS详细的方法见:服务器启用HSTS

服务器开启HSTS

三、域名加入HSTS preload list计划

上面虽然是启用了HSTS 协议保证了用户访问的始终是Https连接,但是一般地首次访问网站用户都会习惯性地输入非https域名,这就导致了第一次访问网站容易出现http劫持的问题。HSTS preload list计划就是为了解决这个问题的,它是chrome\Firefox\Edge等浏览器内置的列表。

域名加入HSTS preload list计划

加入HSTS Preload List的方法:启用HSTS并加入HSTS Preload List让网站Https访问更加安全-附删除HSTS方法。目前wzfou.com已经成功加入到了HSTS preload list,如果你用的是Chrome或者Firefox,第一次访问本站就是默认用Https连接的。

域名加入HSTS preload list计划成功提交

四、开启HTTP/2和OCSP Stapling

HTTP/2 相比于之前的HTTP/1.1 在性能上的大幅度提升,所以只要你启用了Https,记得一定要开启HTTP/2,检查一下你的配置文件是否有:listen 443 ssl http2;

OCSP Stapling 服务器事先模拟浏览器对证书链进行验证,然后将 OCSP 验证结果缓存到本地。这样,当浏览器访问站点时,在握手阶段,可以直接拿到 OCSP 响应结果和证书链,对访问速度有明显提升。

开启HTTP/2和OCSP Stapling

Nginx 中开启 OCSP Stapling。(如果 ssl_certificate 指令指定了完整的证书链,则 ssl_trusted_certificate 可省略)

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/certs/chained.pem;

Apache 中开启 OCSP Stapling

<VirtualHost></VirtualHost> 中添加:

SSLUseStapling on

<VirtualHost></VirtualHost> 外添加:

SSLStaplingCache shmcb:/tmp/stapling_cache(128000)

五、使用ECC和RSA双证书

默认的我们都会使用RSA证书,因为RSA证书的兼容性最为广泛。但是ECC 证书拥有体积小、运算速度快、安全性高(256位ECC key就能起到相当于3072位的RSA key的安全性)等特点,可以在一定程度上提供Https性能。

使用ECC和RSA双证书

Let’s Encrypt已经支持生成ECC 证书了,使用 acme.sh 签发SSL证书, 指定 --keylength ec-256 就可以将证书类型改为 ECC:

acme.sh --issue -w /data/wwwroot/wzfou.com -d wzfou.com -d www.wzfou.com --keylength ec-256

需要注意的是ECC在Windows XP上不兼容,这个时候我们就会想到用双证书了,即当不支持ECC证书时Nginx自动将RSA证书展示给用户。如果nginx 的版本大于1.11,直接就可以在配置文件中写上ECC和RSA双证书的路径了,wzfou.com演示如下:

#ECC
ssl_certificate /root/.acme.sh/wzfou.com_ecc/fullchain.cer;
ssl_certificate_key /root/.acme.sh/wzfou.com_ecc/wzfou.com.key;
#RSA
ssl_certificate /usr/local/nginx/conf/ssl/wzfou.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/wzfou.com.key;

重启Nginx,当XP等不支持ECC证书的用户访问网站时,显示的是RSA证书。

显示RSA证书

而其它的用户则优先使用ECC证书。

使用ECC证书

如果你发现ECC没有优先显示,检查一下ssl_prefer_server_ciphers是否开启,同时ssl_ciphers有没有配置好,以下是wzfou.com当用的配置:

ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;

另外,下面三个任选其一即可(仅供测试):

ssl_ciphers 'EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5';

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';

ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-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:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';

六、 开启DNS CAA

DNS CAA的作用是只允许在记录中列出的 CA 机构颁发针对该域名(或子域名)的证书,以防止有人伪造SSL证书,同时CAA 记录可以控制单域名 SS L证书的发行,也可以控制通配符证书。详细方法见:京东云DNS设置CAA

开启CAA

问题:开启DNS CAA导致错误:Verify error:CAA record for *.wzfou.comprevents issuance。解决的办法就是增加 issuewild 记录: 0 issuewild "letsencrypt.org" 。 另外提供两个检测CAA配置是否正确的网站:

  1. https://caatest.co.uk/
  2. https://dnsspy.io/labs/caa-validator

七、定期自动更新SSL证书

想手动更新方法:

# RSA
$ acme.sh --renew -d wzfou.com –d www.wzfou.com --force

# ECC
acme.sh --renew -d wzfou.com –d www.wzfou.com --force --ecc

一般地acme.sh已经自动添加了定时任务了,定期更新Let’s Encrypt证书,如果你发现没有定期更新证书,检查一下你的Cron任务是否正确,也可以试试强制更新:

"/root/.acme.sh"https://wzfou.b0.upaiyun.com/acme.sh --cron --home "/root/.acme.sh" --force

定期自动更新SSL证书

八、检测SSL证书配置

常用的检测网站有:

  1. https://www.ssllabs.com/ssltest/analyze.html
  2. https://myssl.com/

重点推荐用ssllabs.com,检测的结果还是非常地准确,如下:

检测SSL证书配置

九、综合

综合以上优化策略,Nginx的配置文件具体的优化如下:

server {

listen 443 ssl http2;
#使用HTTP/2,需要Nginx1.9.7以上版本

add_header Strict-Transport-Security "max-age=6307200; includeSubdomains; preload";
#开启HSTS,并设置有效期为“6307200秒”(6个月),包括子域名(根据情况可删掉),预加载到浏览器缓存(根据情况可删掉)

add_header X-Frame-Options DENY;
#禁止被嵌入框架

add_header X-Content-Type-Options nosniff;
#防止在IE9、Chrome和Safari中的MIME类型混淆攻击

ssl_certificate /usr/local/nginx/conf/vhost/sslkey/www.linpx.com.crt;
ssl_certificate_key /usr/local/nginx/conf/vhost/sslkey/www.linpx.com.key;
#SSL证书文件位置

ssl_trusted_certificate /usr/local/nginx/conf/vhost/sslkey/chaine.pem;
#OCSP Stapling的证书位置

ssl_dhparam /usr/local/nginx/conf/vhost/sslkey/dhparam.pem;
#DH-Key交换密钥文件位置

#SSL优化配置

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#只允许TLS协议

ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
#加密套件,这里用了CloudFlare's Internet facing SSL cipher configuration

ssl_prefer_server_ciphers on;
#由服务器协商最佳的加密算法

ssl_session_cache builtin:1000 shared:SSL:10m;
#Session Cache,将Session缓存到服务器,这可能会占用更多的服务器资源

ssl_session_tickets on;
#开启浏览器的Session Ticket缓存

ssl_session_timeout 10m; 
#SSL session过期时间

ssl_stapling on; 
#OCSP Stapling开启,OCSP是用于在线查询证书吊销情况的服务,使用OCSP Stapling能将证书有效状态的信息缓存到服务器,提高TLS握手速度

ssl_stapling_verify on;
#OCSP Stapling验证开启

resolver 8.8.8.8 8.8.4.4 valid=300s;
#用于查询OCSP服务器的DNS

resolver_timeout 5s;
#查询域名超时时间

···

}

实际使用过程中发现个别的“优化”还得根据自身的需要来确定,以下是wzfou.com正在用的Nginx配置,仅供参考:

listen 80; 
listen 443 ssl http2;
#ECC
ssl_certificate /root/.acme.sh/wzfou.com_ecc/fullchain.cer;
ssl_certificate_key /root/.acme.sh/wzfou.com_ecc/wzfou.com.key;  
#RSA 
ssl_certificate /usr/local/nginx/conf/ssl/wzfou.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/wzfou.com.key; 
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_buffer_size 1400;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
ssl_stapling on; 
ssl_stapling_verify on;

PS:2018年8月5日更新,感谢xiaoz的提醒,这里有一个在线生成SSL配置的网站,出自Mozilla,参考性非常高:

  1. https://mozilla.github.io/server-side-tls/ssl-config-generator/

文章出自:挖站否 https://wzfou.com/https-ssl/,内容参考来自 segmentfaultlinpximququ 版权所有。本站文章除注明出处外,皆为作者原创文章,可自由引用,但请注明来源。

关于站长(Qi),8年前经常混迹于免费资源圈中,有幸结识了不少的草根站长。之后自己摸爬滚打潜心学习Web服务器、VPS、域名等,兴趣广泛,杂而不精,愿意将自己经验与心得分享出来,与大家共勉。

28 个评论

  • 可乐 回复

    2018年8月4日 at 下午5:23

    很详细 。

  • 汉娜 回复

    2018年8月4日 at 下午5:31

    写得真好

  • 恰恰 回复

    2018年8月4日 at 下午5:51

    还可以再加一个,启用tls1.3

  • 岩兔站 回复

    2018年8月4日 at 下午5:56

    生命不息,优化不止 !

  • wxp 回复

    2018年8月4日 at 下午6:37

    时间就是生命

  • WJ 回复

    2018年8月4日 at 下午6:53

    这篇文章很强大,虽然我双证书折腾了一番还是没成功……依旧优先RSA

    • 12 点半 回复

      2018年8月4日 at 下午9:46

      我这边看你的博客使用的是 ECC 证书呀?

      • WJ 回复

        2018年8月4日 at 下午11:58

        为啥我Firefox显示“PKCS #1 SHA-256 RSA 加密”呢,换了360极速浏览器,也是RSA

        • 12 点半 回复

          2018年8月5日 at 上午1:26

          呃,你这个问题我在闲逛的时候看到过别人的讨论,讨论结果差不多是这么个意思:根据最新的规范说明,证书的签名算法和证书的密钥算法可以是不同的,也就是说一个含有 ECDSA 公钥的 ECC 证书可以用 RSA 签名算法对它进行签名。目前 Let’s Encrypt 颁发的证书就是这种,因为 Let’s Encrypt 现在的根证书和中间证书还是用的 RSA 证书。至于你想知道是否有配置成功,应该看一下证书里面的持有者公钥算法和浏览器 F12 之后连接使用的密码套件等信息。 smile smile

          • WJ 回复

            2018年8月5日 at 下午1:20

            kiss 原来如此,感谢科普~~~

          • Qi 回复

            2018年8月5日 at 下午3:33

            解释得很全面。 laugh

    • Qi 回复

      2018年8月5日 at 下午4:55

      其实,不考虑XP的话,直接上ECC证书吧。

  • xiaoz 回复

    2018年8月4日 at 下午11:39

    推荐一个网站:https://mozilla.github.io/server-side-tls/ssl-config-generator/ 在线生成各种webserver https最优配置。

    • Lisa.Su 回复

      2018年8月5日 at 上午10:35

      不会用233,而且点什么都没反应

      • xiaoz 回复

        2018年8月5日 at 上午11:02

        自备梯子

  • Aaron 回复

    2018年8月6日 at 下午4:59

    实用干货,收藏了

  • baoang 回复

    2018年8月7日 at 上午11:28

    文中提及的chained.pem具体是哪一个文件呢?用acme.sh申请证书生成的文件有domain.tld.csr、domain.tld.cer、domain.tld.key、ca.cer、fullchain.cer这五个。我一般是把domain.tld.key和fullchain.cer这两个文件上传到Nginx的证书路径中去的。

    • 12 点半 回复

      2018年8月9日 at 上午1:33

      我在你下面的朋友回复里说了,你可以看一下,一不小心回复错地方了。_(:з)∠)_

      • baoang 回复

        2018年8月9日 at 上午9:13

        这样看来,那也就是fullchain.cer了。除CSR以外,涉及到证书的只有domain.tld.cer和ca.cer以及fullchain.cer这三个,对比了一下文件内容,fullchain就是前两者的合并。

        • 12 点半 回复

          2018年8月9日 at 上午11:38

          不对,如果我没有猜错的话,你说的 fullchain.cer 里面应该不会有包含根证书,因为这对于只配置 HTTPS 的人来说不仅没必要更是一种浪费。所谓的 fullchain.cer 大部分可能是里面只包含有网站证书和中间证书,所以我建议你还是另建一个文件,手动添加内容。

          • baoang 回复

            2018年8月9日 at 下午2:02

            多谢@12点半 !
            饭点前,查到了这几个URL
            https://imququ.com/post/letsencrypt-certificate.html
            https://imququ.com/post/why-can-not-turn-on-ocsp-stapling.html#toc-2
            https://letsencrypt.org/certificates/
            发现还真是这么回事,acme.sh申请下来的证书的文件名有点绕。在Nginx配置文件中,key文件的文件名是正常的,不会弄混,是domain.tld.key,但domain.tld.cer就会让人误以为是网站证书从而直接填进Nginx配置中的ssl_certificate一栏去了。实际上这一栏应当填fullchain.cer才能正确通过ssllab的测试。
            我刚才生成了一个chained.pem,试了试,这下应当对了。不过话说似乎ssl_stapling_verify on和ssl_trusted_certificate=chained.pem在Nginx下,Letsencrypt的证书下,没有用。上面那篇文章里提到Nginx会忽略。

            • 12 点半 回复

              2018年8月10日 at 上午12:17

              这个我也看过,不过我当时还是配置了的。因为我看 Let’s Encrypt 论坛里的讨论,说 ssl_trusted_certificate 这一项还是必须要有的,且我配置之后也并没有发现什么问题。 smile

            • Qi 回复

              2018年8月11日 at 上午1:00

              我刚开始也是被这个名称搞混了。

  • 小清新 回复

    2018年8月7日 at 下午1:37

    Qi总 ssl怎么升级呢?

    • 12 点半 回复

      2018年8月9日 at 上午1:31

      OCSP stapling 中说的 chained.pem 指的是包含有根证书和所有中间证书(如果不止一级的话)一起的一个证书,这里不需要把用户网站的证书也带上。另外里面写的证书也是有先后顺序的,按照从小到大的顺序,子证书在前,父证书在后来写,最后写的一定是根证书。简单的说:直接浏览器查看你的证书层次结构,除了最后的用户网站证书,逆方向往上一个一个添加就可以了。

    • 12 点半 回复

      2018年8月9日 at 上午1:32

      对不起,好像回复错地方了~

      • baoang 回复

        2018年8月9日 at 上午9:07

        原来如此,多谢回复

  • 小清新 回复

    2018年8月7日 at 下午1:47

    Qi总,检测您的网站是否存在该漏洞,如下:http://possible.lv/tools/hb/?domain=wzfou.com

发表评论

Login

欢迎!请登录你的账号。

记住我 忘记密码?

还未注册 注册

Lost Password

Register

返回顶部