Author: haoransun
Wechat: SHR—97
学习来源:极客时间-Nginx核心知识100讲,本人购买课程后依据视频讲解汇总成个人见解。
前言
网络安全是当前非常受到关注的一个问题,大部分站点都是通过 HTTPS 来实现安全访问。如何将自己的站点改造成 HTTPS 站点呢?我们需要了解 SSL 协议。
知识普及
抓包或者观察服务器端的配置时,可看到下图
概要介绍
ECDHE: 密钥交换算法(此处是一个椭圆曲线加密算法),用来解决浏览器与服务器则那样独立生成相同的密钥,接下来会用此密钥加密数据。
RSA: 身份验证算法。密钥交换过程中,需要验证各自身份。
数据加密、解密时要用到对称加密算法,即 AES_128_GCM
AES: 算法名称
128:AES支持3种加密强度,此处使用 128
GCM:AES有很多分组模式,GCM是较新的一种模式,可以提高多核CPU下加解密的性能。
SHA256: 摘要算法,用来把不定长度的字符串生成一个固定长度的更短的摘要。
对称加密 VS 非对称加密
对称加密(同一把密钥)
使用相同的 密钥序列 进行 异或运算,第一次加密,再异或一次即解密。
非对称加密
同一份文档,用公钥加密的,只能用对应的私钥进行解密
文档加密
身份验证
SSL证书公信力的保证
爱丽丝 与 鲍勃 进行通信,但有个前提条件,爱丽丝就是爱丽丝,鲍勃就是鲍勃,这样一个新问题,在多方通讯过程中必须有一个公信机构,即 CA机构
CA是怎样颁发证书,使证书过期的呢?
PKI公钥基础设施
流程:
图中的CA即是一个公信机构,用来颁发证书的。
我们作为一个站点的维护者,就是一个 证书订阅人,首先我们要去申请一个证书,必要要登记(我是谁、我属于什么组织、我想做什么)
到了登记机构后,通过 CSR 发送给 CA,申请通过后。
CA会生成一对公私钥,公钥保存在CA的证书链中,公私钥被证书订阅人拿到后。
证书订阅人 会把拿到的公私钥部署到自己的 Web服务器,如 Nginx服务器等。
当 浏览器通过 第 1 步 访问我们的 HTTPS站点时,会去请求我们的证书,而Nginx这样的Web站点服务器 会将我们的 公钥证书 发给我们的浏览器。 浏览器需要去验证 我们颁发给他的证书是否 合法有效
如果我们用 Let’s encrypt 会发现证书只有 90天的有效期。而用其他的SSL-CA可能会有1年的有效期。
有效期如何体现: CA中心 会把过期的证书放到 CRL服务器中
CRL服务器会把所有的过期证书形成一个很长很长的链条,性能极差。
所以又推出一个称为 OCSP响应程序,它可以就一个证书去查询是否过期。 因此 浏览器可以直接查询 OCSP响应程序,但 OCSP 性能依然不高。
因此,我们的 Nginx Web服务器 往往会有一个 OCSP开关,当打开时,会由 Nginx 主动地去OCSP查询, 这样,大量的客户端可以直接从 Nginx 服务器获取到证书是否有效。
证书类型
证书链
浏览器对 DV OV EV 验证效果是一样的,唯一区别的 就是他的 证书链。
目前所有站点的 主证书都是有 3级结构。根证书、二级证书、主证书。
为什么形成这样的3级证书结构呢?
那是因为 根证书的 验证十分谨慎,像 Window 、 Android 等操作系统 每 1年以上才会去更新它的根证书库。所以,一个新的根证书库CA机构是很难快速加入到操作系统、浏览器认可的证书库中的。
大部分浏览器使用的是操作系统的根证书库,像Firefox可能会维护自己的根证书库。所以浏览器在验证我们的证书是否有效时,最主要是验证 根证书是否无过期,有效。
Nginx 服务器向 浏览器发送 两个证书(主证书、二级证书)即可。根证书是被操作系统、浏览器内置的,无需发送。
SSL协议握手时Nginx的性能瓶颈
TLS通讯过程
流程:
1 Client Hello 浏览器发给服务器。因为我们的浏览器是非常多元化的。Chrome、IE、FireFox等。浏览器的版本也在不停的变更。不同的浏览器所支持的安全套件、加密算法是不同的。因此在第一步,主要是告诉服务器,我支持哪些算法。
2 Server Hello 如 Nginx会有一个自己知道自己可支持的加密算法列表,以及自己倾向于使用哪一个加密算法套件,Nginx会选择自己最喜欢的一个加密算法套件发送给客户端。如果想复用 Session,即 Nginx 打开了 Session Cache ,希望一天内断开了连接的客户端,不用再次协商密钥,在这一步可以直接复用之前的密钥。因此 这一步主要是发送 究竟我们选择哪一个安全套件
3 Server Certificates 会把自己的公钥证书发送给浏览器,公钥证书中是包含证书链的,所以浏览器可以找到自己的跟证书库,去验证证书是否有效。Check Certificate validity
4 Server Hello Done 服务器会发送此消息,但如果之前协商的安全套件,如椭圆曲线算法,此时需要在 3 与 4 之间 将椭圆曲线的参数发送给客户端。以方便我们在 6 生成最终加密的密钥。
5 ClientKey Exchange Message 客户端也需要根据椭圆曲线的公共参数生成自己的私钥后,将公钥发送给服务器。此时,服务器也有了自己的私钥,将公钥发送给客户端。
6 Key generation 服务器可以根据自己的私钥和客户端的公钥共同生成双方加密的密钥, 客户端可以根据自己的私钥和服务器的公钥共同生成双方加密的密钥。这两个各自生成的密钥是相同的。这是由 非正式加密算法来保证的。
7 CipherSpec Exchange Finished 接下来就可以用生成的密钥进行数据加密与通讯了。
由上述过程可以看到,TLS通讯过程主要是做 交换密钥 + 加密数据,这两个最耗费性能。
Nginx优化性能
对于小文件。握手是主要影响他 QPS性能的主要指标
Nginx数据加密性能
Nginx综合性能
当以小文件为主时,考虑优化Nginx非对称加密性能(椭圆曲线)。
当以大文件为主时,考虑优化Nginx非对称加密性能(AES)。
免费SSL实现HTTPS站点
前提:
- 拥有一个域名,且ICP备案。
- 在域名服务器创建一条A记录,指向云主机的公网IP地址。例如demo.mydomain.com指向xxx.xxx.xxx.xxx的IP地址。
- 要等到新创建的域名解析能在公网上被解析到。
演示如何使用 Let’s encrypt 生成免费的DV证书,将网站改造为 https站点。
1 http协议请求标识
没有小锁,说明现在是一个 http请求。
2 Nginx.conf配置
在server中,有一个 server_name,这个域名会被 Let’s encrypt脚本所使用,location 指向了一个具体的文件
3 脚本安装与使用
1 | yum install python2-certbot-nginx |
该工具会提供一个命令 certbot
1 | certbot --nginx --nginx-server-root=/usr/local/geek/openrestry/nginx/conf/ -d geektime.taohui.pub |
–nginx 会为nginx的配置文件自动执行相应的修改,通常默认会去修改 /usr/local/nginx/conf/ 下的配置文件,但此处因为路径不同,所以使用
–nginx-server-port 单独指定nginx.conf所在路径。
-d 指定 申请证书的域名。
首先会去获取一个证书,验证证书,投放证书到配置文件。
1:不做重定向。(此处选择1)
2:做重定向。
区别:当有了 https站点后,希望所有的http流量,明文显示的不安全流量都是用 301 、302重定向协议转到https站点。
HTTPS站点标识
此时查看 nginx.conf,增加了5行
1 | 监听443端口 使用ssl协议 |
看一下 /etc/letsencrypt/options-ssl-nginx.conf
ssl中最降低性能的就是握手,因此设置了一个 ssl_session_cache ,大小为1M。在 1440m(分钟)即1天 时间内可以复用之前的。
ssl_protocols: ssl支持哪些版本的协议。
ssl_perfer_server_ciphers on 表示nginx服务器使用那些协议与浏览器进行通讯。
ssl_ciphers 中的安全套件以 分号为分隔符。排在前面的会优先使用。