HTTPS协议介绍—使用Nginx+SSL实现部署与性能优化

一、HTTPS协议简介


HTTPS 可以认为是 HTTP + TLS。HTTP 协议大家耳熟能详了,目前大部分 WEB 应用和网站都是使用 HTTP 协议传输的。

TLS 是传输层加密协议,它的前身是 SSL 协议,最早由 netscape 公司于 1995 年发布,1999 年经过 IETF 讨论和规范后,改名为 TLS。如果没有特别说明,SSL 和 TLS 说的都是同一个协议。

HTTP 和 TLS 在协议层的位置以及 TLS 协议的组成如下图:

wKioL1Vud1ST6T5XAAGTp_OTWBc009.jpg


TLS 协议主要有五部分:应用数据层协议,握手协议,报警协议,加密消息确认协议,心跳协议。

TLS 协议本身又是由 record 协议传输的,record 协议的格式如上图最右所示。

目前常用的 HTTP 协议是 HTTP1.1,常用的 TLS 协议版本有如下几个:TLS1.2, TLS1.1, TLS1.0 和 SSL3.0。其中 SSL3.0 由于 POODLE ***已经被证明不安全,但统计发现依然有不到 1% 的浏览器使用 SSL3.0。TLS1.0 也存在部分安全漏洞,比如 RC4 和 BEAST ***。

TLS1.2 和 TLS1.1 暂时没有已知的安全漏洞,比较安全,同时有大量扩展提升速度和性能,推荐大家使用。

需要关注一点的就是 TLS1.3 将会是 TLS 协议一个非常重大的改革。不管是安全性还是用户访问速度都会有质的提升。不过目前没有明确的发布时间。

同时 HTTP2 也已经正式定稿,这个由 SPDY 协议演化而来的协议相比 HTTP1.1 又是一个非常重大的变动,能够明显提升应用层数据的传输效率。

二、HTTPS功能介绍


HTTP 本身是明文传输的,没有经过任何安全处理。例如用户在浏览器进行登陆提交数据时,中间者可以劫持数据并看到这个数据的信息,可能泄漏用户的隐私数据,给用户造成不便。

这里提到的中间者主要指一些网络节点,是用户数据在浏览器和服务器中间传输必须要经过的节点。比如 WIFI 热点,路由器,防火墙,反向代理,缓存服务器等。

在 HTTP 协议下,中间者可以随意嗅探用户搜索内容,窃取隐私甚至篡改网页。不过 HTTPS 是这些劫持行为的克星,能够完全有效地防御。

总体来说,HTTPS 协议提供了三个强大的功能来对抗上述的劫持行为:

1,  内容加密。浏览器到服务器的内容都是以加密形式传输,中间者无法直接查看原始内容。

2,  身份认证。保证用户访问的是官方的服务,即使被 DNS 劫持到了第三方站点,也会提醒用户没有访问到服务,有可能被劫持

3,  数据完整性。防止内容被第三方冒充或者篡改。

三、HTTPS原理介绍

3.1、内容加密

加密算法一般分为两种,对称加密和非对称加密。所谓对称加密(也叫密钥加密)就是指加密和解密使用的是相同的密钥。而非对称加密(也叫公钥加密)就是指加密和解密使用了不同的密钥。

wKiom1VueZHhBqGfAADjrgkVkUA309.jpg

对称内容加密强度非常高,一般破解不了。但存在一个很大的问题就是无法安全地生成和保管密钥。假如客户端软件和服务器之间每次会话都使用固定的,相同的密钥加密和解密,肯定存在很大的安全隐患。如果有人从客户端端获取到了对称密钥,整个内容就不存在安全性了,而且管理海量的客户端密钥也是一件很复杂的事情。

非对称加密主要用于密钥交换(也叫密钥协商),能够很好地解决这个问题。浏览器和服务器每次新建会话时都使用非对称密钥交换算法协商出对称密钥,使用这些对称密钥完成应用数据的加解密和验证,整个会话过程中的密钥只在内存中生成和保存,而且每个会话的对称密钥都不相同(除非会话复用),中间者无法窃取。

非对称密钥交换很安全,但同时也是 HTTPS 性能和速度严重降低的“罪魁祸首”。想要知道 HTTPS 为什么影响速度,为什么消耗资源,就一定要理解非对称密钥交换的整个过程。

3.2、非对称密钥交换

在非对称密钥交换算法出现以前,对称加密一个很大的问题就是不知道如何安全生成和保管密钥。非对称密钥交换过程主要就是为了解决这个问题,使得对称密钥的生成和使用更加安全。

密钥交换算法本身非常复杂,密钥交换过程涉及到随机数生成,模指数运算,空白补齐,加密,签名等操作。

常见的密钥交换算法有 RSA,ECDHE,DH,DHE 等算法。它们的特性如下:

  • RSA:算法实现简单,诞生于 1977 年,历史悠久,经过了长时间的破解测试,安全性高。缺点就是需要比较大的素数(目前常用的是 2048 位)来保证安全强度,很消耗 CPU 运算资源。RSA 是目前唯一一个既能用于密钥交换又能用于证书签名的算法。

  • DH:diffie-hellman 密钥交换算法,诞生时间比较早(1977 年),但是 1999 年才公开。缺点是比较消耗 CPU 性能。

  • ECDHE:使用椭圆曲线(ECC)的 DH 算法,优点是能用较小的素数(256 位)实现 RSA 相同的安全等级。缺点是算法实现复杂,用于密钥交换的历史不长,没有经过长时间的安全***测试。

  • ECDH:不支持 PFS,安全性低,同时无法实现 false start。

  • DHE:不支持 ECC。非常消耗 CPU 资源

建议优先支持 RSA 和 ECDH_RSA 密钥交换算法。原因是:

1,  ECDHE 支持 ECC 加速,计算速度更快。支持 PFS,更加安全。支持 false start,用户访问速度更快。

2,  目前还有至少 20% 以上的客户端不支持 ECDHE,我们推荐使用 RSA 而不是 DH 或者 DHE,因为 DH 系列算法非常消耗 CPU(相当于要做两次 RSA 计算)。

wKioL1Vuf7_DA72EAAFmujvwM0c010.jpg

需要注意通常所说的 ECDHE 密钥交换默认都是指 ECDHE_RSA,使用 ECDHE 生成 DH 算法所需的公私钥,然后使用 RSA 算法进行签名最后再计算得出对称密钥。

非对称加密相比对称加密更加安全,但也存在两个明显缺点:

1,  CPU 计算资源消耗非常大。一次完全 TLS 握手,密钥交换时的非对称解密计算量占整个握手过程的 90% 以上。而对称加密的计算量只相当于非对称加密的 0.1%,如果应用层数据也使用非对称加解密,性能开销太大,无法承受。

2,  非对称加密算法对加密内容的长度有限制,不能超过公钥长度。比如现在常用的公钥长度是 2048 位,意味着待加密内容不能超过 256 个字节。

所以公钥加密目前只能用来作密钥交换或者内容签名,不适合用来做应用层传输内容的加解密。


四、编译Nginx


编译参数:

./configure --user=www --group=www \

> --prefix=/alidata/server/nginx \

> --with-http_stub_status_module \

> --without-http-cache \

> --with-http_ssl_module \

> --with-http_gzip_static_module \

> --with-http_spdy_module \


来到wosign申请免费证书:https://buy.wosign.com/FreeSSL.html

https://buy.wosign.com/Free/


创建ssl目录用于存放证书,将申请到的证书和密钥放在里面。

mkdir ssl

wKioL1Vuks6SOVP6AABUiuMW0yE321.jpg

开启SSL

listen       443 ssl;

ssl on;

添加证书和SSL密钥

ssl_certificate  /alidata/server/nginx/ssl/1_test.qlogo.net_bundle.crt;

ssl_certificate_key  /alidata/server/nginx/ssl/2_test.qlogo.net.key;


五、SSL配置优化


1、HSTS

HSTS(HTTP Strict Transport Security)。服务端返回一个 HSTS 的 http header,浏览器获取到 HSTS 头部之后,在一段时间内,不管用户输入www.baidu.com还是http://www.baidu.com,都会默认将请求内部跳转成https://www.baidu.com;

将下述行添加到你的 HTTPS 配置的 server 块中:

add_header Strict-Transport-Security "max-age=31536000";

2、Session cache

Session cache 的原理是使用 client hello 中的 session id 查询服务端的 session cache, 如果服务端有对应的缓存,则直接使用已有的 session 信息提前完成握手,称为简化握手。

Session cache 有两个缺点:

1,    需要消耗服务端内存来存储 session 内容。

2,    目前的开源软件包括 nginx,apache 只支持单机多进程间共享缓存,不支持多机间分布式缓存,对于百度或者其他大型互联网公司而言,单机 session cache 几乎没有作用。

 Session cache 也有一个非常大的优点:

1,   session id 是 TLS 协议的标准字段,市面上的浏览器全部都支持 session cache。

ssl_session_cache    shared:SSL:20m;

ssl_session_timeout  20m;

参照Nginx的官方文档1MB内存大约可以存储4000个session,按例配置20M大约可以存储80000。根据需求合理设置


3、加密安全设置

1, 非对称密钥交换算法。建议优先使用 ECDHE,禁用 DHE,次优先选择 RSA。

2, 证书签名算法。由于部分浏览器及操作系统不支持 ECDSA 签名,目前默认都是使用 RSA 签名,其中 SHA1 签名已经不再安全,chrome 及微软 2016 年开始不再支持 SHA1 签名的证书 (http://googleonlinesecurity.blogspot.jp/2014/09/gradually-sunsetting-sha-1.html)。

3, 对称加解密算法。优先使用 AES-GCM 算法,针对 1.0 以上协议禁用 RC4( rfc7465)。

4, 内容一致性校验算法。Md5 和 sha1 都已经不安全,建议使用 sha2 以上的安全哈希函数。      

ssl_prefer_server_ciphers On; #指定服务器密码算法在优先于客户端密码算法时,使用SSLv3和TLS协议。

ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-RC4-SHA:!ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:!RC4-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!CBC:!EDH:!kEDH:!PSK:!SRP:!kECDH;

这里禁用了RC4,sha1,MD5等算法。


4、协议安全设置

在 SSL 协议这里默认支持的是 SSLv3, TLSv1, TLSv1.1, TLSv1.2(需要 OpenSSL 支持,针对近两三年的 Nginx 版本),因为 SSLv3 的一些安全问题,还有 TLSv1 的浏览器支持基本没有问题了,所以可以直接禁用掉,(当然 TLSv1 也有安全问题,但是 TLSv1.1 支持有限,所以这里暂时先保留着)。

ssl_protocols    TLSv1 TLSv1.1 TLSv1.2;

5、启用SPDY

SPDY 是 google 推出的优化 HTTP 传输效率的协议(https://www.chromium.org/spdy),它基本上沿用了 HTTP 协议的语义, 但是通过使用帧控制实现了多个特性,显著提升了 HTTP 协议的传输效率。

SPDY 最大的特性就是多路复用,能将多个 HTTP 请求在同一个连接上一起发出去,不像目前的 HTTP 协议一样,只能串行地逐个发送请求。Pipeline 虽然支持多个请求一起发送,但是接收时依然得按照顺序接收,本质上无法解决并发的问题。

可以在编译Nginx带上参数 --with-http_spdy_module 支持SPDY协议,然后可在配置中启用:

listen       443 ssl spdy;

6、Ocsp stapling

Ocsp 全称在线证书状态检查协议 (rfc6960),用来向 CA 站点查询证书状态,比如是否撤销。通常情况下,浏览器使用 OCSP 协议发起查询请求,CA 返回证书状态内容,然后浏览器接受证书是否可信的状态。将证书保存下来,浏览器请求时候直接通过自己的服务器发送回去,防止验证服务器出问题,还能加快访问速度。


查看OSCP验证服务器地址:

openssl x509 -in 1_test.qupeiyin.net_bundle.crt  -text

在输出的文字中找到 OCSP – URI:,后面的 URL 就是 OSCP 的验证服务器地址。

如图:

wKioL1VurzyxytoIAACHryFyLHs361.jpg

请求OSCP证书


openssl ocsp -noverify \
            -issuer /certificate-path/trustchain.crt \
            -cert /certificate-path/trustchain.crt \
            -url http://ocsp2.globalsign.com/gsalphasha2g2


不出意外会收到如下的结果

trustchain.crt: good
        This Update: Oct 18 17:59:10 2014 GMT
        Next Update: Oct 18 23:59:10 2014 GMT

如果出现 403 错误,那就需要在 Header 请求头加上域名参数 -header "HOST" "ocsp2.globalsign.com",没问题后就可以直接保存下来证书文件,完整的命令如下:

openssl ocsp -noverify \
            -issuer /certificate-path/trustchain.crt \
            -cert /certificate-path/trustchain.crt \
            -url http://ocsp2.globalsign.com/gsalphasha2g2 \
            -header "HOST" "ocsp2.globalsign.com"
            -text -respout ./stapling_file.ocsp

将保存下来的 stapling_file.ocsp 证书添加到 nginx 的配置中,如下,Nginx 中配置变成了这样子:

ssl_stapling on;
ssl_stapling_verify on;
ssl_stapling_file /stapling_file.ocsp;
ssl_trusted_certificate /certificate-path/trustchain.crt;

这样子重启 Nginx 后就会生效,可以使用下面的命令测试生效结果:

echo QUIT | openssl s_client -connect blog.alphatr.com:443 -status 2> /dev/null | grep -A 17 'OCSP response:' | grep -B 17 'Next Update'
看到 OCSP Response Status: successful 这样的字样就是成功了。
ocsp证书有效期很短,大概不到一个月,所以过段时间要更新ocsp证书,不然还是会验证失败。
需要用脚本定时更新OCSP证书。


HTTPS性能评估:https://www.ssllabs.com/ssltest/

wKioL1Vut9ryRqZvAAIafzt-Yew215.jpg

本篇博文内容引用了网络上的多篇优秀文档内容

参考文档:

http://linux.cn/article-5266-1.html

https://blog.alphatr.com/nginx-ssl-config.html

http://op.baidu.com/2015/04/https-s01a03/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值