继上一篇《如何打造一个全满分网站》以后,这一次咱们来谈谈如何打造一个在安全方面也能打满分的网站。由于对于一个网站来说,仅有功能是不够的,还须要考虑性能,仅有性能也不够,还须要考虑安全。html
因为网站安全方面涉及因素不少,例如如何防止跨域攻击
,如何防止SQL注入
等等软件开发方面的安全考虑,若是真想作到全面防御的话,还须要有更专业的机构进行漏洞检测,咱们这里谈的只是最基本的在传输层面的https
安全。nginx
跟上次的思路同样,开始动手以前,咱们仍是先来熟悉一下评测工具,此次介绍的主要是3个网站,前2个网站相似,基本上你若是在一个网站上拿不到高分,在另外一个网站也是同样;第3个网站略有不一样。git
又拍云
为了推广本身的HTTPS
服务,提供了一个免费检测工具。就拿咱们熟悉的segmentfault
来讲吧:github
很不幸,在安全方面彻底不合格。又拍云
提供的方案有两个:算法
又拍云HTTPS
服务;若是本身优化的话,其实最关键的核心问题是一点:服务器易受到CVE-2016-2107漏洞攻击,降级为F
。只要解决了这个问题,评分就能上升不少。segmentfault
另一个工具是Qualys SSL Lab提供的免费服务,和又拍云
相似,可是不推销产品。仍是拿segmentfault.com
来作一下实验:跨域
一样是F
,不合格。根本缘由仍是在这个CVE-2016-2107
。浏览器
这个网站主要是用来检测网站的response header是否安全的,咱们仍是拿segmentfault.com来测试一下:安全
得分也不高,有不少问题。服务器
那么,到底什么是CVE-2016-2107
呢?Cloudflare
给出了详细解释,不过若是你不是安全方面的专家,基本上如读天书不知所云。
粗略地来说,CVE-2016-2107
是OpenSSL 1.0
的一个漏洞,是2016
年刚刚发现的编号为2107
号漏洞。安全系统的漏洞就像人的衣服破了一个洞同样,对付漏洞的手段无非就是两个:要否则打个补丁接着穿,要否则换件新的。OpenSSL
官方给出的解决方案是把OpenSSL
升级到1.0.2h
就好了。可是怎么升级是一个问题,若是你用yum update
升的话根本也升不上去,何况就算升上去了,也于事无补,由于你的nginx
软件包里用的继续仍是旧版本的OpenSSL
,只有用正确的参数从新编译nginx
才能解决这个问题。关于如何编译nginx
,能够参考个人《免费给你的网站加上蓝色小闪电》的后半部分。
但据个人实际测试发现,即便把OpenSSL
升级到1.0.2h
也没法解决此问题,为此直接把OpenSSL
升级到了最新的1.1.0g
,但形成的问题是nginx
又不兼容了,为此还须要把nginx
也升级到最新版本1.13.6
。通过这样的升级后,你的网站穿上了新衣服,这个漏洞就算堵住了。
nginx
的相关编译参数以下:
--prefix=/usr/local/nginx --with-http_ssl_module --with-openssl=/root/src/openssl-1.1.0g --user=nginx --group=nginx --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_geoip_module=dynamic --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'
按照这个方法,还顺带解决了http/2
的传输问题,详见《免费给你的网站加上蓝色小闪电》一文。
解决完了CVE-2016-2107
漏洞,咱们来看一看证书,彷佛和别人的不太同样:
那么什么是RSA
,什么又是椭圆曲线
呢?简单来讲,RSA
是利用大数因数分解的困难性来增长黑客破解的难度。好比你问小明:15
等于几乘以几?他能够很快答出3x5
,若是你问他:51
等于几乘以几?他可能就要掏出计算器来算一算,才能告诉你等于17x3
。若是再问:10,497,479
等于几乘以几?恐怕他拿着计算器也算不出来,正确答案是3229x3251
,而实际上咱们真正用于RSA
的两个质数还要远大于这个数字,因此因数分解的困难性是保证RSA
安全的重要前提。
然而,2015
年的时候,号称有一种算法已经能够破译RSA,因而安全专家们又提出了ECC(Elliptic Curve Cryptography)
,中文叫做“椭圆曲线加密
”算法。椭圆
咱们都知道,但椭圆曲线
是个什么东西呢?
这是一个椭圆
:
下面这两个都是椭圆曲线
:
长的根本就不像好吧,那为何又要叫椭圆曲线
呢?简单来讲,椭圆曲线这个名称的来源只是和椭圆周长的计算有关,从图形上看它们没有任何关系。
那好吧,这么一条曲线怎么加密呢?
加密的公式很简单,就如上图所示:P+Q=R
,假设R
就是咱们的公钥,若是只给你一个R
,让你反推出P
和Q
来,就像给你一个大数,让你对它进行因数分解同样困难,这就构成了ECC
加密算法的安全保障。
听上去好高大上,那么我该如何得到一张椭圆曲线加密算法
的证书呢?
花钱能办了的事那都不是事,重要的是咱们能够免费得到!你要知道,之前一张RSA
证书一年的费用是5000
元,每一年还要续费,这构成了不少商业公司盈利的重要来源,其中包括Symantec
赛门铁克。
当你吃饭吃的很舒服的时候,市场就会出来搅局者。感谢开源软件精神,Letsencrypt
砸掉了不少安全公司的饭碗。我在《letsencrypt在nginx下的配置》一文中曾经讲过如何配置Letsencrypt
,后来又写过《CentOS 6.5下利用Docker使用Letsencrypt》,可是如今有更好的方法:acme.sh,你只须要安装好acme.sh
:
curl https://get.acme.sh | sh
而后执行:
cd .acme.sh ./acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-256
就能够获得一张免费的椭圆曲线安全证书
了。注意上面命令结尾这个ec-256
,ec
是否是让你想起了什么呢?对的,这就是咱们提到的椭圆曲线
(elliptic curve
)。
免费的证书有了,安装到你的nginx
里看一下吧,证书签名算法瞬间变成了椭圆曲线
!是否是马上变得高大上了呢?重要的是还免费哦!
升级完了椭圆曲线还不够,接下来咱们再来看看CAA(Certification Authority Authorization)
,中文翻译为受权机构认证
。什么是受权
?什么是机构
?什么又是认证
?
简单来讲,你作了一个网站,为了安全起见,为了须要向别人证实你就是你,你须要一张网站的身份证,那么谁有权颁发这个证件呢?在中国,只有公安局有权发身份证,那么这个有权发证件,而且获得全部人承认的机构,就叫受权机构
。可是互联网的世界比较乱,受权机构不少,万一要是有一个你不知道的机构,也给别人发了一张你的名字的身份证怎么办?因此为了杜绝这个隐患,你做为网站的全部者,你能够规定:只有这个受权机构颁发的证书,才是有效的证书,其它机构颁发的证书一概无效,这个就叫“受权机构认证
”,如下简称CAA
。
CAA
是须要运行在DNS
服务器之上的,可是目前国内的几乎全部DNS
服务提供商没有一家提供这个服务,CarterLi兄的这篇文章《给你的站点添加 DNS CAA 保护》里提到了如何给本身的网站添加CAA
,能够考虑把你的DNS
搬家到能提供CAA
服务的厂家去作一下。
HSTS(HTTP Strict Transport Security)
,中文翻译为HTTP严格传输安全
,就是让浏览器强制使用HTTPS
与网站进行通讯,以减小会话劫持风险,给你的网站安全再加一道锁。
给网站添加HSTS
相对比较容易,只要在header
里加一句
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
就好了。
比TLS 1.2
再上一个台阶,但目前还处于测试阶段,OpenSSL 1.1.1
会支持,但目前尚未正式发表,因此暂时能够先不添加。你要想装也能够,这里提供详细的安装步骤。
Content Security Policy的主要做用是让你的网站只执行限定范围内的Javascript脚本,CSS以及图片,因此咱们能够在nginx里做以下限制:
add_header Content-Security-Policy "script-src 'self'";
更多的关于如何设置CSP的内容能够参考阮一峰的《Content Security Policy入门教程》
X-Frame-Options的做用是禁止别的网站iframe你的网站,在nginx里添加如下配置:
add_header X-Frame-Options "SAMEORIGIN";
X-XSS-Protection的做用是防止跨站脚本攻击,在nginx里添加如下配置:
add_header X-XSS-Protection "1; mode=block";
X-Content-Type-Options的做用是禁止浏览器对你的网页内容进行MIME类型嗅探,而必须以你规定的方式解析网页,在nginx里添加如下配置:
add_header X-Content-Type-Options "nosniff";
以上全部方案都实施以后,咱们再来看一下网站安全评分:
Certificate
拿到了满分,下面几项没有拿到满分,在Protocol Support
这一项里,主要是因为没有对一些老版本的浏览器例如IE8
,Java 6
以及Android 2
作兼容,这个问题不大,咱们就先不解决了,其它两项Key Exchange
和Cipher Strength
应该是和咱们使用的Letsencrypt
有关,目前还不清楚具体缘由,能够再研究。
不管如何,咱们把一个安全得分只有F
的网站,经过各类方法优化到了得分为A+
,是否是小有成就感呢?你也来试一试吧!