钱,就像一个熨斗,能烫平生活的所有褶皱。------>电影《寄生虫》
Nginx配置
这里推荐给大家一个生成Nginx配置文件的web工具。
网址是:https://www.digitalocean.com/community/tools/nginx
Nginx介绍
Nginx (engine x) 是一个高性能的 Web 服务器和反向代理服务器,也是一个 IMAP/POP3/SMTP 服务器。它由俄罗斯程序员 Igor Sysoev 于 2002 年开始开发。Nginx 是增长最快的 Web 服务器,市场份额已达 33.3%。全球使用量排名第二,2011 年成立商业公司。
Nginx 分支
- Openresty:作者 @agentzh(章宜春)开发的,最大特点是引入了 ngx_lua 模块,支持使用 Lua 开发插件,并且集合了很多丰富的模块,以及 Lua 库
- Tengine:主要是淘宝团队开发。特点是融入了因淘宝自身的一些业务带来的新功能。
- Nginx 官方版本,更新迭代比较快,并且提供免费版本和商业版本
Nginx支持反向代理、负载均衡,具有高可靠性,是单Master多worker模式。
Nginx具有高可扩展性,且高度模块化。
Nginx是事件驱动的非阻塞I/O模型。
Nginx消耗内存极低,且支持热部署。
Nginx应用
- 静态文件服务器
- 反向代理,负载均衡
- WAF防火墙,安全防御
- 智能路由(企业级灰度测试、地图 POI 一键切流)
- 灰度发布
- 消息推送,推流服务器
- 图片实时压缩
- 防盗链
- 静态化
SSL优化
缓存连接凭据
存 SSL 连接凭据可以避免频繁握手带来的速度降低和性能损耗。
TLS 协议有两类会话缓存机制:会话标识 session ID 与会话记录 session ticket。session ID 由服务器端支持,协议中的标准字段,因此基本所有服务器都支持,服务器端保存会话ID以及协商的通信信息,Nginx 中1M 内存约可以保存4000个 session ID 机器相关信息,占用服务器资源较多;而 session ticket 属于一个 TLS 扩展字段,需要服务器和客户端都支持。
二者对比,主要是保存协商信息的位置与方式不同,类似与 HTTP 中的 session 与 cookie。都存在的情况下,Nginx 优先使用 session_ticket。
# SSL
ssl_session_timeout 1d;
# 过期时间,分钟
ssl_session_cache shared:SSL:10m;
# SSL session 缓存区大小
ssl_session_tickets off;
Forward Secrecy(前向加密)
forward secrecy 也称之为 perfect forward secrecy,或者 PFS。称之为完美远期加密。是在HTTPS基础上进一步保护用户电脑同服务器之间的加密通讯。
其解决的一个安全场景就是,如果服务器同用户间的加密通讯内容被窃听,也被储存下来,这些被加密的内容虽然当时无法被解密,被破解,但是当日后,服务器的SSL密钥被取得后(不管是何种原因被取得密钥),这些过往的内容是可以用这个密钥来解密的。这样虽然时效性可能差些,但是仍然是会有被破解的危险存在。
而采用 完美远期加密 的 SSL 或者 HTTPS 通讯,加密钥匙只是短暂性的,而且不能从服务器的 SSL 密钥中推算出来,这样即使日后 SSL 密钥被第三方取得,过去和未来的 HTTPS 通讯仍然安全,窃听者始终无法破解所窃听的内容(以目前的技术而言)。
目前只有用 ephemeral Diffie-Hellman 的算法才算是完美远期加密
配置方法
在终端运行(建议把这个 Diffie-Hellman 参数文件和证书放在一起)
openssl dhparam -out dhparam.pem 2048
在 Nginx 的配置文件中加入:
# Diffie-Hellman parameter for DHE ciphersuites
ssl_dhparam /etc/nginx/dhparam.pem;
HSTS(HTTP Strict Transport Security,严格传输安全)
HSTS 简单说就是在一定时间内强制客户端使用 HTTPS 访问页面。原理如下:
- 在服务器响应头中添加
Strict-Transport-Security
,可以设置max-age
- 用户访问时,服务器种下这个头
- 下次如果使用 HTTP 访问,只要
max-age
未过期,客户端会进行内部跳转,可以看到 307 Redirect Internel 的响应码(注意是客户端浏览器相应的,这里给服务器省下了一次 302 跳转) - 变成 HTTPS 访问源服务器
这个过程有效避免了中间人对 80 端口的劫持。但是这里存在一个问题:如果用户在劫持状态,并且没有访问过源服务器,那么源服务器是没有办法给客户端种下 Strict-Transport-Security 响应头的(都被中间人挡下来了)。如何解决?请自行谷歌 HSTS preload。
需要注意的是,只有启用 preload 之后才是严格意义上安全的 HTTPS。否则都可能在最薄弱环节被攻破。比如:
允许 SSL 连接但不强制从 HTTP 跳转到 HTTPS,用户访问 HTTP 被劫持
部署了 HSTS,但用户第一次访问是 HTTP 的,Strict-Transport-Security 的响应头没有作用的机会,还是被劫持
开启HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
Nginx ocsp Stapling
OCSP (Online Certificate Status Protocol) 通常由 CA 提供,用于在线实时验证证书是否合法有效,这样客户端就可以根据证书中的 OCSP 信息,发送查询请求到 CA 的验证地址,来检查此证书是否有效。
然而这些默认查询 OCSP 的客户端在获得查询结果的响应前势必会一直阻塞后续的事件,在网络情况堪忧的情况下(尤其是大陆地区)会造成较长时间的页面空白。
而 OCSP Stapling ,顾名思义,是将查询 OCSP 接口的工作交给服务器来做,服务器除了可以直接查询 OCSP 信息,还可以仅进行少数次查询并将响应缓存起来。当有客户端向服务器发起 TLS 握手请求时,服务器将证书的 OCSP 信息随证书链一同发送给客户端,从而避免了客户端验证会产生的阻塞问题。由于 OCSP 响应是无法伪造的,因此这一过程也不会产生额外的安全问题。
在服务器上部署ocsp装订,能大大缓解链接数与高并发量。省去多次握手操作,使网站访问速度更快。
-
获取证书
在您完成服务证书的申请之后,一般会给您两个文件,一个是crt或者pem格式结尾的是站点本身的证书文件,例如
www.domainname.com.crt
; 还有填写csr之后以key格式结尾并下载的私钥文件,例如www.domainname.com.key
; 除了站点证书以外,我们还需要中级证书以及根证书。首先打开浏览器,输入您之前部署好的证书的站点网址,这里以本博客为例,如下图所示:然后点击查看证书,选择-详细信息,最后复制到文件;
如下图中,编码格式选择Base64-cer格式;
!
选择要导出的文件名,然后保存!
PS: 然后按照相同的操作,导出根证书。中级证书名称为:issuer.crt.cer 根证书名称为:root.crt.cer
-
将三份证书上传到服务器,生成OCSP Stapling验证文件。即是将中级证书与根证书合并一起。注意,中级证书在上、根证书在下。
Linux中使用如下命令:
cat issuer.crt.cer >> chain.crt cat root.crt.cer >> chain.crt
Windows下使用文本编辑打开中级证书与根证书分别按照中级证书在上、根证书在下的顺序排列合并,然后重命名即可.
最后合并生成的chain.crt就是所需的ocsp stapling验证文件.
-
Nginx 启用 OCSP Stapling
在nginx的主配置文件中,http模块中添加如下配置;这里需要注意的是在HTTP模块中,就代表所有的站点都将启用OCSP Stapling。
# OCSP Stapling ssl_stapling on; ssl_stapling_verify on; resolver 223.5.5.5 223.6.6.6 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 114.114.114.114 valid=60s; resolver_timeout 2s;
然后在该站点的server模块中配置如下,前两行是您之前的HTTPS配置,
ssl_trusted_certificate
是您要添加的配置:# SSL ssl_certificate /etc/pki/nginx/ihere.io/fullchain.crt; ssl_certificate_key /etc/pki/nginx/ihere.io/privkey.key; ssl_trusted_certificate /etc/pki/nginx/ihere.io/chain.crt;
然后检测配置并重载:
nginx -t nginx -s reload
PS: 如果只针对该站点启用,而不想对该nginx下的所有站点启用,之需要在该站点的server添加如下内容:
ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /path/to/certs/chained.pem;
-
随后验证OCSP Stapling是否开启
手动验证
echo QUIT | openssl s_client -connect ihere.io:443 -status 2> /dev/null | grep -A 17 'OCSP response:'
若出现一下内容,则开启成功:
OCSP response: ====================================== OCSP Response Data: OCSP Response Status: successful (0x0) Response Type: Basic OCSP Response Version: 1 (0x0) Responder Id: 9058FFB09C75A8515477B1EDF2A34316389E6CC5 Produced At: Mar 23 18:04:01 2020 GMT Responses: Certificate ID: Hash Algorithm: sha1 Issuer Name Hash: 777A7BA877D6F10F1CE9202196FB6B1A6E37F5ED Issuer Key Hash: 9058FFB09C75A8515477B1EDF2A34316389E6CC5 Serial Number: 08BF04E59C7D7A734E3EF18507AC59E6 Cert Status: good This Update: Mar 23 18:04:01 2020 GMT Next Update: Mar 30 17:19:01 2020 GMT
使用 SSLLAB 自动验证
访问
https://www.ssllabs.com/ssltest/
,输入欲测试的域名,稍等片刻后,如果发现结果中出现如下内容则证明已成功开启 OCSP Stapling: