序
这样一篇技术向文章,为什么非要写个序呢?
HTTPS ,不就是“申请张证书然后让服务器使用它”的事吗?
刚接触建站时,我也这样认为过,随着姿势解锁和经验累积,发现整个过程存在非常多要考量的细节,最后的完成着实消耗了不少精力和时间。
于是考虑后决定写成一个系列,内容分为三部分:「配置 HTTPS」、「加强 HTTPS」、「启用 HTTP/2」
这是第一篇,本文的章节如下:
- HTTPS 简介和麻烦的地方
- 全站 HTTPS 的条件
- 免费 SSL 证书申请和推荐
- 公私钥、证书链的格式和作用
- Apache 下的配置方法
- Nginx 下的配置方法
- CDN 的选择和 SSL 证书上传细节
- 后续工作(重要,百度分享本地化等)
HTTPS 简介和麻烦的地方
近段时间 HTTPS 越来越受到关注,苹果从 IOS 9 开始规定 App 内访问的网络必须使用 HTTPS 协议,刚上线不久的微信小程序也做了强制 HTTPS 的要求,今年 2 月,一个叫做 EFF(Electronic Frontier Foundation))的非营利组织发布报告称, 2016 年全球已有过半的 web 流量通过 HTTPS 传输,所以 HTTPS 还颇有点“山雨欲来风满楼”之势。
HTTPS 是 HTTP 协议的安全升级版,以前 HTTP 明文传输的内容将通过 SSL 层变为加密传输。
每次写文章,都想尽可能地把所有“坑”盘一遍,所以在这一节,先归集那些弄 HTTPS 麻烦的地方:
|1. HTTPS 比起 HTTP 多出了 SSL 证书验证环节,会增加客户端和服务端的握手次数,当 HTTPS 开启之初,你可能会发现网站的访问速度,比起 HTTP 慢了很多;
|2. 由于多了加解密工作,会增加服务器资源负担,尤其是 CPU 占用;
|3. 流行的云存储 HTTPS 流量比 HTTP 贵;
|4. 并不是启用了 HTTPS ,传输就不会被劫持,老旧的浏览器多只支持不再安全的加密协议,比如 SSLv2 SSlv3 ,“安全、高效、兼容性好”是个无法定量的标准,为了尽可能靠近它,启用 HTTPS 后还有许多优化工作要做;
|5. 另外 CDN ,HTTPS 下的稳定性、节点服务器安全程度、以及是否需要支持 HTTP/2 ,都需要考量和试用,比如腾讯 CDN,虽然安全评分较高(SSLLABS 测试 A-),但还没有开放 HTTP/2;再比如 VeryCloud ,虽然支持 HTTP/2 ,但安全评分超低(F)。
总之,启用全站 HTTPS 紧跟着成本考量和后期优化。
全站 HTTPS 的条件
申请一套受各大浏览器信任的 SSL 证书是首当其冲的一环,过程并不复杂,所以就跟证书推荐一起就放到下节,这一节先说服务端的要求。
要启用全站 HTTPS,所有页面加载的资源必须符合 W3C 的 Mixed Content(混合内容)规范。不知道看官对 IE 询问用户是否加载的安全提示,或者 Chrome 左上角的黄色小锁有无印象。
现代浏览器(包括移动端)对 HTTP 来源的图片、视频资源,一般是默认允许加载,但是如果不是 HTTPS 来源的 js、css 等资源不会加载;如果是 IE ,无论是早期的还是较新的,只要出现非 HTTPS 的资源都会弹出不安全提示,然后交由用户决定是否加载。
这种情况就是浏览器识别到了自身认为不安全的 HTTP 资源,而不同时期不同的浏览器又有不同的要求,即使当前图片、视频类资源可以加载,在 HTTPS 日益普及的未来也说不准。
所以,为了避免这里提示安全那里又提示不安全的尴尬境况,让所有的资源请求都走 HTTPS 才是稳妥的办法,即全站 HTTPS。
从 HTTP 过渡到 HTTPS,网站的管理者就可能会面临大量的资源替换工作,最常见的比如:文章里的图片引用、从站外通过 HTTP 引用的 js、css 。
除此之外,HTTPS 使用的是 443 端口,注意开放;
最后用命令 openssl version 检查下 OpenSSL 的安装情况,HTTPS 、HTTP/2 都需要它的支持。
尤其是对于 HTTP/2 ,更应该尽可能把 OpenSSL 升级到最新(截止到本文发布,OpenSSL的最新版是 1.0.2K )
免费 SSL 证书申请和推荐
免费 SSL 证书一般是 DV 等级,属于基础级,只验证域名所有权。
但证书被不被浏览器信任,并不是只看收费与否,比如之前一度流行的沃通和 StartCOM 签发的新证书就已经相继被 Moziila ,Google ,苹果封杀。
这里推荐几个 2017 年初认可度比较高的免费证书:
|1. 腾讯云可以免费申请 TrustAsia 证书,1 次签发有效期 1 年,传送门;
|2. 阿里云可以免费申请 Symantec 证书,1 次签发有效期 1 年,传送门;
|3. 还有拥有众多粉丝的 Let’s Encrypt 免费证书,1 次签发有效期 3 个月。
我还没来得及尝试 Let’s Encrypt(现在用的 TrustAsia),不过仍想重点介绍下。
Let’s Encrypt 是一个发展迅猛的公益组织,它的证书是已得到各大主流浏览器和权威机构支持的,并且不像很多免费证书只包含根域名和 www 二级域名,Let’s Encrypt 允许在一张证书里添加更多域名。
虽然一次签发最多只有 90 天有效期,但有自动续期脚本,配置好后一劳永逸,还有很关键的一点:
Let’s Encrypt 支持加密算法更安全的 ECC 证书签发。
这种证书也有缺点,先进的加密算法牺牲了一些老环境下的兼容性,比如 Window XP、Android 4.x 以下版本就不支持,有关 ECC 证书的详解,我推荐一篇 Jerry Qu 的文章:传送门
Apache 下的配置方法
先上传证书,放置路径自由决定;
找到 Apache 的配置文件 httpd.conf ,如果不知道文件位置,可以用命令 # find / -name httpd.conf 查找。
编辑 httpd.conf ,在大约 411 行找到 #Include conf/extra/httpd-ssl.conf 去掉前面的 # 号;
然后进入 httpd.conf 同目录的 extra 文件夹,找到并编辑 httpd-ssl.conf 文件:
在大约77行找到 DocumentRoot ,把后面的路径修改为网站的目录
在大约78行找到 ServerName ,把后面的网址修改为 你的网址:443;
在大约117行找到 #SSLCertificateFile ,去掉前面的 # 号,后面填上公钥的路径;
在大约125行找到 #SSLCertificateKeyFile ,去掉前面的 # 号,后面填上私钥的路径;
在大约135行找到 #SSLCertificateChainFile ,去掉前面的 # 号,后面填上根证书的路径;
最后重启 Apache,命令 # service httpd restart
Nginx 下的配置方法
先上传证书,放置路径自由决定;
找到网站的 Nginx 配置文件,一般在 Nginx 安装目录的 /conf/vhost 路径下,文件名为:域名.conf
编辑该文件,在原配置的第一行: listen 80; 下,插入如下配置:
listen 443 ssl; server_name 域名; if ($server_port = 80 ) { return 301 https://你的域名$request_uri; } ssl on; ssl_certificate 公钥路径; ssl_certificate_key 私钥路径;
上面的语句同时还开启了 Nginx 下的 HTTP → HTTPS 301 跳转。
当然,单独写个 443 端口的 server 也是可以得,记得把 301 跳转的语句 return 301 https://你的域名$request_uri; 放在 80 端口的 server,if 的判断句就不要了。
Apache 下的 HTTP 强制 301 跳转 HTTPS 可以在文章「配合CDN进行301跳转完美隐藏源站IP」里找到,就不重复写了。
CDN 的选择和 SSL 证书上传细节
看到这里,也许你已经为爱站申请到了证书,但可能还是一脑子懵逼,因为:
“哪个是私钥哪个是公钥啊?”
“这个 .pem 文件又是干嘛的?”
“为什么这个 .pem 有两组密文啊,内容还是跟两个 .crt 重复的?”
“CDN 叫我上传证书,我上传 .crt 还是 .pem 啊?!”
“麻蛋,只有两个地方可以上传啊,可是我有四个文件,上传哪两张啊喂?!!!”
解决这些疑惑,我推荐一篇言简意赅生动形象的文章,通俗易懂地解释了证书体系,也许文章的比喻不够严谨,但值得一读:传送门
如果实在不想看,伸手党们你就按下面这样搞:
CDN 提供了三个上传入口,分别上传 私钥 .key 、公钥 .crt 、根证书链 .crt,
CDN 只有两个上传入口,那么一个上传的是 私钥 .key ,一个上传的 .pem 文件,即公钥+根证书链。
然后,我们来盘点下当前国内流行的支持 HTTPS 的 CDN 方案:
|七牛云,HTTPS 不免费,但提供了云存储服务,可以用来做图床,HTTP/2 ;
|又拍云,申请又拍云联盟,免费 1 年,每月 15/GB 流量,超出的费用和七牛相近,HTTP/2 ;
|腾讯CDN,新用户赠送 6 个月 50 GB 月流量,HTTP 1.1,HTTP/2 内测中,对网站规模有信心可以尝试工单申请,腾讯的工作人员会进行评估,评估标准未知;
|VeryCloud,现在用的,赠送 50 GB 月流量,HTTPS 不稳定,SSLLABS 安全评级低,HTTP/2 ;
|360 的 CDN,已被我拉进黑名单,对接后自家浏览器和搜狗浏览器打不开网站,具体可以看我 TTFB 那篇文章,而且也不稳定。
综合来说,如果你不需要 HTTP/2 ,腾讯 CDN 靠谱;
如果想加入次世代协议 HTTP/2 的弄潮大军,又拍云比较合适,就是要手持身份证拍照特别麻烦,我已经准备转战又拍了,毕竟 HTTP/2 才是最吼的 8)
后续工作(重要,百度分享本地化等)
WordPress 的网站启用 HTTPS ,一定要把后台「WordPress地址(URL)」和「站点地址(URL)」中的 URL 起头也改成 https
你可以先在 WordPress 后台改完再去配置服务端和 CDN ,但此时网站就无法访问了;
建议先把混合内容、服务端配置、CDN 弄好后,再通过数据库修改,修改的表项在「wp_options」。
最后,是许多人关心的百度分享本地化。
由于百度分享的资源加载地址 http://bdimg.share.baidu.com/* 不支持 HTTPS ,根据上文提到的 Mixed Content 规范,直接使用会出现问题。
我们要做的是:把原本从外部加载的资源放到自己的服务器上。
这里我已经把本站的百度分享资源打包了,需要的话请自行:百度网盘
下载后解压到网站根目录,然后如下修改百度分享的引用代码:
src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5) 把上面原本的这部分改为 src='/static/api/js/share.js?cdnversion='+~(-new Date()/36e5)
从百度进来的,博客不错哦!