给你的博客上一把锁
本文主要讲解给自己的博客或站点配置https的必要性和配置方法。
再不https都老了
说到https,可能有一个问题是大家必问的,那就是为啥要用https,我这里能给到的答案就是: 美啊。 先来一张图观赏下:
其实最重要的还是安全,在这个根本没有隐私的时代,https显得更加那么的重要。在你网站被运营商 乱插
的时候,你就会更加迫切的想要一把锁。上锁之前,我们需要对https有一定的了解,下面我们简要学习下。
六问 HTTPS
https握手会使得网站变慢?
大家最关心的就是这个协议会让我们的连接变慢,这个看起来似乎是不可避免的;毕竟建立SSL连接的过程比http多了好几次握手。所以一个https请求的过程中,握手阶段包含了 TCP协议的握手
和 SSL协议的握手
的时间,总体上我通过工具测试大概SSL握手是TCP握手的三倍,而且证书的秘钥越长加解密时间则越多。
然而事实就这么简单吗? 非也
作为中国人,一定对GFW毕竟熟悉了,实际上根据我多年来实际的经历来看,除了GFW,其实不管是在国内的公司还是学校(甚至运营商),实际上都有监控或劫持本组织内网络流量的嫌疑。当网站使用了https,实际上这些监控系统成为摆设,既然无法拆解你的信息,他唯一的做法自然是放过,这就大大加速了数据在网络中的传输速度。所以:
使用了https表面上看起来是在连接建立阶段增加了时间,然而实际上对网站整体的速度来说,未必真的慢了。
只需要在注册登录页面使用https?
注册登录页面肯定是要做 https的,但这只能防止密码劫持,并不能防止cookie劫持和js注入等问题;这年头想劫持一个局域网络的简直易如反掌(何况还有天朝的无耻运营商可以随意注入呢),所以如今要想安全,必须全站所有页面都https
静态资源是否需要https?
如果主要页面已经https了,则你的CDN静态资源也得走https,否则浏览器会给出简单的控制台警告(对于被动混合mixed内容):
而对于主动混合内容(如js脚本),大部分浏览器会直接阻止加载,这会导致你的站点出现故障。
混合内容有两种:主动混合内容和被动混合内容
被动混合内容指的是不与页面其余部分进行交互的内容,从而使中间人攻击在拦截或更改该内容时能够执行的操作受限。被动混合内容包括图像、视频和音频内容,以及无法与页面其余部分进行交互的其他资源。
主动混合内容作为整体与页面进行交互,并且几乎允许攻击者对页面进行任何操作。 主动混合内容包括浏览器可下载和执行的脚本、样式表、iframe、flash 资源及其他代码。
不过cdn服务器遍布全球,要想把证书安装到上面可是很费劲的。所以如果想用自己的域名来实现静态资源https化,只能有这两条路:
- 要么自己部署cdn自己搞
- 要么把证书和秘钥交给自己的cdn服务商。
但是第二个办法实在是太危险了。所以CDN服务商推出了新的服务: 除了允许你上传自己的证书和私钥之外,也可以由你来申请CDN服务商的CA证书的服务。这意味着 你可以专门为使用CDN资源的这个域名申请个单独的证书,这个证书是部署到CDN服务商所有服务器的(这样就不用担心自己主业务的服务器私钥泄露给第三方)。目前国内的七牛已经提供了该服务,所以我的博客图片也顺便开启了https。
https没有缓存机制吗?
是的。不过要明确这里的缓存指的是中间网络设施的缓存,而不是客户端缓存。中间网络设施无法缓存的原因在于他们根本无法获取https报文,无法读取缓存策略。
从https的意义上来看 既然想保护信息的隐私,确实也没必要让中间设施进行缓存了。
https是否足够安全?
SSL/TLS的设计只能说是从技术上最大限度地保护网络报文的安全,但它无法防止用户自己作死;比如浏览器已经提示你证书错误(有可能网络已经被中间人劫持)的情况下你依然点击”继续访问”。
验证HTTPS证书带来的性能开销是否很大?
实际上整个证书验证的过程中,还可能因为一些其他原因导致耗时增加:
- 服务端发送的Server Certificate包可能包含上级证书链,在普遍使用2048位RSA的环境中,这个包会超过2K或者3K,在移动或慢速网络下可能会丢包并引起TCP的重传
- 浏览器会检查服务端证书的吊销状态—-根据服务端证书扩展项中的地址去下载黑名单或访问OCSP服务,如果这些地址无法访问或者被墙,则会让浏览器等上很长一段时间。 这可就蛋疼了,毕竟我们处在大中国,而浏览器都是舶来品
- 建立连接时的非对称加密算法本身非常耗时,这对CPU性能要求比较高。所以每次握手,对服务器来说都是一次压力的考验
怎么办呢? 我认为是没有办法的,为了安全我们必须做出这样的牺牲;当然这可以从网络协议本身来减轻这个性能和速度开销的负担,比如http2.0就已经支持了多路复用的技术,目前的http1.1也支持keep-alive
,这就大大减轻了多次创建连接和握手带来的开销。
福利:免费申请https证书
Let’s Encrypt
提供了免费的https证书,目前2018年初已经开始支持 泛域名
。 因此对于有多个子域的网站来说,只需要申请根域的证书,就可以应用在所有的子域上面。
申请脚本
网络上已经有写好的申请脚本,使用此脚本申请证书非常方便, 步骤如下:
1 | curl https://get.acme.sh | sh |
以上命令,如果碰上curl错误,可以尝试退出当前terminal再次进入。 由于CA机构需要校验你对域名的所有权,所有你需要把你域名服务商的API接口的 API_id
和 API_key
告诉 Let's Encrypt
.
过期重申
Let's Encrypt
申请的证书只有3个月有效期,到期需要重新申请。所幸网络上的这个 acme
脚本已经实现了自动检查并重新申请的能力,我们就不用关心了。(本质上它在系统上创建了 crontab 脚本每天零点定时检查)
nginx配置https
nginx配置https其实很简单,只需要按照如下格式,将里面的证书地址和秘钥地址配置成你自己的即可。
1 | server { |
在使用 acme.sh
脚本时,证书和秘钥key都会生成到~/.acme.sh/yourdomain
目录下。
例如我的 cuiyongjian.com
域名证书就被生成到了/root/.acme.sh/cuiyongjian.com/fullchain.cer;
目录下。
如果你的站点希望强制走https,那么你可以再加一个nginx的server配置项,让http请求重定向到https:
1 | server { |
浏览器端查看证书
点击chrome地址栏左侧的小锁图标,可以看到当前网站的证书信息