加固站点

前几天给同事秀我的博客主页的时候,由于主页很久没有维护过了,证书弹出已过期的字样,作为一个安全公司的Team Lead,这着实有些尴尬。

于是,我在百忙之中,抽时间把站点加固了一番。

重新生成证书

首先面对的是SSL证书的问题,既然已经过期,那么就需要重新生成一张证书。

从时间上考虑,一个短周期的有效时间可以通过更换证书来达到保证站点持续更新至最新状态,但是与之带来的是维护成本的提高。就像这次证书过期一样,一个疏忽就导致可能引入了更严重的问题。因此我选用了20年为证书的有效时间。参考网上很多人使用3650天作为10年的周期,本人有些强迫症,3650天并不是10年,因为他根本没有考虑闰年的事情……所以最终我选用的是7305作为20年的数值。

从强度上考虑,密钥的长度与复杂度成正比,与消耗时间成反比。考虑到这只是一张网站的证书,并不会有太高的延迟限制要求,因此我选用一个比较大的数值作为密钥的长度,2048. 对于签名算法,由于sha1已经不安全,所以至少要启用sha256作为签名算法,在这里我又激进了一点,使用了sha512.

openssl req -x509 -nodes -days 7305 -sha512 -newkey rsa:2048 -keyout website.key -out website.pem

至此,证书重新生成完毕。需要注意的是,这本证书依旧是self-signed,CA是自己的,所以在哪别人都不会认的,换句话说,这本证书算是一种自我安慰了。

SSL Protocol 版本

首先看到我的服务器还在使用SSLv3的时候自己真的很无语…这若是被攻击早就死了一百次了。于是第一个操作是删除掉SSLv3。对于TLSv1来说,我记得也有消息报过其有风险,于是在最终版本中我也同样删除了对其的支持,只留下TLS1.1和TLS1.2。这样做可能会带来一些浏览器访问困难,但是试问如今主流的浏览器哪个不支持TLS1.1和TLS1.2呢?

由于最近工作上接触了TLS1.3,所以我特别希望能在自己的站点率先启用TLS1.3。但是仔细查过nginx的版本和文档,目前nginx还并没有支持TLS1.3。看在连openssl都没有正式发布支持TLS1.3的版本的份上,我就先忽略掉它吧。

ssl_protocols    TLSv1.1 TLSv1.2;

加强cipher list

在重新生成证书之后,我重新启动了nginx。看着Nginx的配置文件,突然发现cipher list里竟然还有RC4。

RC4已经被证明不安全,于是我参考了我研究的一个产品上的Cipher list:

ssl_ciphers    “ALL:!ADH:!RC4:!EXP:!DES:@STRENGTH”;

修改完成后自己做测试,发现这样的范围仍然会有一些不安全的Cipher被启用,比如LOW下的有SHA1之类的cipher。而我又不想把Cipher限定至一两种,于是最终我决定使用HIGH的cipher list作为范围:

ssl_ciphers    “HIGH:!aNULL:!ADH:!RC4:!EXP:!DES”;

增加XSS防护

这个算是不经意间想到的,之前改产品界面服务器的时候,遇到过这个SVM,于是我也把这个限制引入到我的站点中:

add_header    X-Frame-Options SAMEORIGIN;

add_header    X-Content-Type-Options nosniff;

add_header    X-XSS-Protection “1; mode=block”;

ssl_dhparam

一边运用自己掌握的知识修正我所知道的内容,我同时也在网上搜索着还有哪些参数需要调整。于是我找到了这篇文章 Getting a Perfect SSL Labs Score 。

这篇文章里提到了一点,关于密钥交换的:

By default, Nginx will use the default DHE (Ephemeral Diffie-Hellman) paramaters provided by openssl. This uses a weak key that gets lower scores. The best thing to do is build your own. You can create a 2048 bit key, but let’s go ahead and toss 4096 at it.

说得在理,于是我使用它提供的方法,生成4096位的dhparam。

openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096

这足足花了我一顿午饭的时间,大约一个小时才生成好。
然后启用:

ssl_dhparam    dhparam.pem;

升级openssl

至此我很自信我的站点足够安全,于是我前往https://www.ssllabs.com/ssltest/ 进行压力测试,结果我得了个F……

定睛一看,原来中了一个CVE:OpenSSL Padding Oracle vulnerability.

速查了一下,这个缺陷是openssl自己的,升级openssl可以解决,于是决定将openssl升级至最新稳定版(1.0.2k):

http://stackoverflow.com/questions/22952287/how-to-upgrade-openssl-in-centos-6-5-linux-unix-from-sourcehttps://www.openssl.org/source/openssl-1.0.2k.tar.gz

[root@iZu10697nesZ openssl-1.0.2k]# openssl version
OpenSSL 1.0.2k 26 Jan 2017

然后重新生成了key和证书。重新测试后,还是没有得到A的评价,取而代之的是一个红色的T,定睛一看,下面有一行小字:If trust issues are ignored: A。好吧就算成功了吧。

完整报告: https://www.ssllabs.com/ssltest/analyze.html?d=www.kevin-wang.com

升级wordpress 4.7.3

最后一步,突然想起之前看过wordpress也有漏洞,细查了一下我正在使用的版本……4.3……最新的版本已经4.7.3。于是义无反顾地升级了……

至此,加固站点任务全部结束!