nginx-https安全最佳实践

一、介绍

使网站SSL/TLS的服务符合行业最佳实践,符合PCI DSS支付卡行业安全标准,符合Apple ATS规范


二、https安全实践事项


1.PCI DSS支付卡行业安全标准

PCI DSS,全称Payment Card Industry Data Security Standard,第三方支付行业数据安全标准,是由PCI安全标准委员会制定,力在使国际上采用一致的数据安全措施。
早在去年6月30号PCI安全标准委员会官方发表博文将于2018年6月30号(最晚),也就是本月月底禁用早期SSL/TLS,并实施更安全的加密协议 (TLS v1.1或更高版本,强烈建议使用TLS v1.2)以满足PCI数据安全标准的要求,从而保护支付数据。

解决方案
评估兼容性后,禁用 TLS1.0

nginx-
ssl_protocols  TLSv1.1 TLSv1.2 TLSv1.3;

2.Apple ATS规范

自2017年1月1日起,根据苹果要求,所有iOS应用必须使用ATS(App Transport Security),即iOS应用内的连接必须使用安全的HTTPS连接。同时,苹果要求使用的不仅是一个简单的HTTPS协议连接,而且必须要满足iOS9中的新增特性。
App Transport Security(ATS) 是Apple为增强iOS App网络通信安全提出的安全功能,它会强制应用通过HTTPS(而不是HTTP)连接网络服务。

ATS默认的安全要求

- SSL证书由操作系统信任的CA根证书签发;
- 服务器必须支持传输层安全(TLS)协议1.2以上版本;
- 连接必须使用AES-128或AES-256对称加密算法;
- TLS协商算法必须通过规定的ECDHE密钥交换保证完全正向保密;
- SSL证书必须使用SHA256或更高的哈希算法签名;以及2048位以上RSA密钥或256位以上ECC密钥。

HTTP/2协议便使用TLS 1.2+版本作为安全加密层

解决方案
评估兼容性后,启用大于等于 TLS1.2 
优化配置Ciphers,支持完全正向加密技术

nginx-
ssl_protocols  TLSv1.2 TLSv1.3;

3.防御XSS攻击

跨站点脚本(XSS 或 CSS)的保护被构建到大多数流行的浏览器中,除了 Firefox 之外。
这种保护是用户可配置的,可以关闭。因此,明确要求浏览器在你的网站上使用它的 XSS 过滤器是个好主意。

解决方案
使用加入 HTTP header, 启用xss攻击防御 

nginx-
add_header 'X-XSS-Protection' '1; mode=block' always;

4.启用HTTP严格传输安全(HSTS)

指示浏览器只使用 HTTPS 连接到目标服务器。这可以防止一些潜在的中间人攻击,包括 SSL 剥离,会话 cookie 窃取(如果没有被 适当保护)。如果遇到任何与证书相关的错误,它还可以阻止浏览器连接到网站。当浏览器访问一个设置相应 HTTP header 的 HTTPS 网站时,HSTS 将被激活。
HSTS 有一个固定期限,由 max-age 字段值控制。这个值可以是静态的,也可以是相对于将来某个特定日期的,你可以设置成 SSL 证书的过期时间。

解决方案
设置 HSTS header 长的生命周期,最好是半年及以上。

nginx-
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

5.预防降级攻击

可以看到 HSTS 可以很好的解决 HTTPS 降级攻击,但是对于 HSTS 生效前的首次 HTTP 请求,依然无法避免被劫持。浏览器厂商们为了解决这个问题,提出了 HSTS Preload List 方案:内置一份可以定期更新的列表,对于列表中的域名,即使用户之前没有访问过,也会使用 HTTPS 协议。
目前这个 Preload List 由 Google Chrome 维护,Chrome、Firefox、Safari、IE 11 和 Microsoft Edge 都在使用。
如果要想把自己的域名加进这个列表,首先需要满足以下条件:

- 拥有合法的证书(如果使用 SHA-1 证书,过期时间必须早于 2016 年);
- 将所有 HTTP 流量重定向到 HTTPS;
- 确保所有子域名都启用了 HTTPS;
- 输出 HSTS 响应头:
- max-age 不能低于 18 周(10886400 秒);
- 必须指定 includeSubdomains 参数;
- 必须指定 preload 参数;

即便满足了上述所有条件,也不一定能进入 HSTS Preload List,更多信息可以看这里。通过 Chrome 的 chrome://net-internals/#hsts 工具,可以查询某个网站是否在 Preload List 之中,还可以手动把某个域名加到本机 Preload List

Google已经提议一种叫TLSFALLBACKSCSV的SSL/TLS的拓展,旨在防止强制SSL降级。以下是升级后自动启用的OpenSSL版本:( http://nginx.org/en/docs/http/ngx_http_ssl_module.html
OpenSSL 1.0.1 有 TLSFALLBACKSCSV 在 1.0.1j 及更高的版本.
OpenSSL 1.0.0 有 TLSFALLBACKSCSV 在 1.0.0o 及更高的版本.
OpenSSL 0.9.8 有 TLSFALLBACKSCSV 在 0.9.8zc 及更高的版本.


6.启用安全强度的加密套件

TLS1.3 废弃了RSA密钥交换方案(因为RSA不具有前向保密性),仅支持(EC)DHE密钥协商方案.
所以我在ssl_ciphers屏蔽了RSA的密钥交换方案,保留了tls1.3的最佳标准


ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4:!RSA;


三、https安全实践配置

在nginx server 中加入


ssl_certificate           /etc/nginx/cert.d/xxx.com.crt;
ssl_certificate_key       /etc/nginx/cert.d/xxx.com.key;

ssl_session_cache  builtin:1000  shared:SSL:10m;
ssl_session_timeout 1h;

ssl_prefer_server_ciphers on;

#启用TLS1.1、TLS1.2要求OpenSSL1.0.1及以上版本
ssl_protocols  TLSv1.1 TLSv1.2 TLSv1.3;
ssl_early_data on;

ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4:!RSA;
#ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header 'X-XSS-Protection' '1; mode=block' always;

TLS 1.3可以在第一个网络往返中完成共享密钥协商和身份认证,在完成共享密钥协商和身份认证后可以直接切换到应用数据协议,所以TLS 1.3 完整握手过程只需要一个网络往返(1-RTT)


关于nginx-ssl_ciphers

nginx中的加密套件是通过ssl_ciphers指令指定的,加密套件格式通常就是以‘:’分隔,然后写在一行.

ssl_ciphers 宏定义

ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;

HIGH代表是高级的加密套件,也就是密钥长度大于128位的,在openssl的ciphers中,还有MEDIUM和LOW,
但是LOW已经在openssl 1.0.2g中禁用了.

点我查看 openssl-ciphers 文档


nginx-ssl_protocols与 ssl_ciphers的注意点


1. 在实际测试中发现,在低版本的nginx(1.17版本或者小于1.17版本)虽然两个配置都在server 块内,ssl_protocols 却属于全局配置(http配置),而 ssl_ciphers 却针对特定的虚拟主机(server配置)起作用, 如果server内配置了 ssl_protocols,那么nginx还是会用 全局配置 的覆盖server块的 配置,并且在全局配置和server都配置了ssl_protocols,语法不会提示有问题。
2. ssl_ciphers的配置就可以根据域名来区分开来。

解决办法:
低版本的nginx(1.17版本或者小于1.17版本) 全局配置(http配置)内加上ssl_protocols 。(隐患:会导致全局nginx使用新配置的ssl_protocols。好的建议是:升级nginx到1.19版本)


查看ssl整个连接过程

通过openssl工具来建立连接,查看整个连接过程,比如通过openssl s_client -connect xxx.com:443(这里端口要带,或者可以-h查看使用方法)

openssl s_client -connect xxx.com:443

openssl的ciphers查看加密套件

# openssl ciphers 'HIGH' -v|column -t
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH        Au=RSA    Enc=AESGCM(256)    Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH        Au=ECDSA  Enc=AESGCM(256)    Mac=AEAD
ECDHE-RSA-AES256-SHA384        TLSv1.2  Kx=ECDH        Au=RSA    Enc=AES(256)       Mac=SHA384
ECDHE-ECDSA-AES256-SHA384      TLSv1.2  Kx=ECDH        Au=ECDSA  Enc=AES(256)       Mac=SHA384
ECDHE-RSA-AES256-SHA           SSLv3    Kx=ECDH        Au=RSA    Enc=AES(256)       Mac=SHA1
ECDHE-ECDSA-AES256-SHA         SSLv3    Kx=ECDH        Au=ECDSA  Enc=AES(256)       Mac=SHA1
DH-DSS-AES256-GCM-SHA384       TLSv1.2  Kx=DH/DSS      Au=DH     Enc=AESGCM(256)    Mac=AEAD
DHE-DSS-AES256-GCM-SHA384      TLSv1.2  Kx=DH          Au=DSS    Enc=AESGCM(256)    Mac=AEAD
DH-RSA-AES256-GCM-SHA384       TLSv1.2  Kx=DH/RSA      Au=DH     Enc=AESGCM(256)    Mac=AEAD
DHE-RSA-AES256-GCM-SHA384      TLSv1.2  Kx=DH          Au=RSA    Enc=AESGCM(256)    Mac=AEAD
DHE-RSA-AES256-SHA256          TLSv1.2  Kx=DH          Au=RSA    Enc=AES(256)       Mac=SHA256
DHE-DSS-AES256-SHA256          TLSv1.2  Kx=DH          Au=DSS    Enc=AES(256)       Mac=SHA256
DH-RSA-AES256-SHA256           TLSv1.2  Kx=DH/RSA      Au=DH     Enc=AES(256)       Mac=SHA256
DH-DSS-AES256-SHA256           TLSv1.2  Kx=DH/DSS      Au=DH     Enc=AES(256)       Mac=SHA256

查看加密套的复杂程度

# yum -y install nmap

#  nmap --script ssl-cert,ssl-enum-ciphers -p 443 www.baidu.com

Starting Nmap 6.40 ( http://nmap.org ) at 2022-07-26 19:04 CST
Nmap scan report for www.baidu.com (14.215.177.39)
Host is up (0.0066s latency).
Other addresses for www.baidu.com (not scanned): 14.215.177.38
PORT    STATE SERVICE
443/tcp open  https
| ssl-cert: Subject: commonName=baidu.com/organizationName=Beijing Baidu Netcom Science Technology Co., Ltd/stateOrProvinceName=beijing/countryName=CN
| Issuer: commonName=GlobalSign RSA OV SSL CA 2018/organizationName=GlobalSign nv-sa/countryName=BE
| Public Key type: rsa
| Public Key bits: 2048
| Not valid before: 2022-07-05T05:16:02+00:00
| Not valid after:  2023-08-06T05:16:01+00:00
| MD5:   ed19 4909 8287 a63d 206f 549a 2291 8c38
|_SHA-1: 486a edd1 6852 e597 4fa0 9246 b33c 5646 3dd9 9cd5
| ssl-enum-ciphers: 
|   SSLv3: 
|     ciphers: 
|       TLS_RSA_WITH_RC4_128_SHA - strong
|     compressors: 
|       NULL
|   TLSv1.0: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_RC4_128_SHA - strong
|       TLS_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_RSA_WITH_RC4_128_SHA - strong
|     compressors: 
|       NULL
|   TLSv1.1: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_RC4_128_SHA - strong
|       TLS_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_RSA_WITH_RC4_128_SHA - strong
|     compressors: 
|       NULL
|   TLSv1.2: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - strong
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_RC4_128_SHA - strong
|       TLS_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_RSA_WITH_RC4_128_SHA - strong
|     compressors: 
|       NULL
|_  least strength: strong

Nmap done: 1 IP address (1 host up) scanned in 0.79 seconds



密码套件

密码套件是认证,加密和消息认证码(MAC)算法的组合

功能 算法
密钥交换 RSA,Diffie-Hellman,ECDH,SRP,PSK
认证 RSA,DSA,ECDSA
批量密码 RC4,3DES,AES
消息验证 HMAC-SHA256,HMAC-SHA1,HMAC-MD5,GCM-SHA384

加密套件的示例

ECDHE-RSA-AES256-GCM-SHA384

部分 描述 名字
ECDHE 密钥交换算法 "短暂 - 椭圆曲线 - 迪菲 - 赫尔曼" 算法
RSA 认证算法 非对称加密算法
AES256 对称加密算法 高级加密标准
GCM-SHA384 消息验证算法

握手时使用 ECDHE 算法进行密钥交换;用 RSA 签名和身份认证;握手后的通信使用 AES 对称算法,密钥长度 256 位;分组模式是 GCM, 摘要算法 SHA384 用于消息认证和产生随机数


ssl_ciphers屏蔽不安全的加密套

ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4:!RSA;
这里额外屏蔽了RSA


ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;


四、注意事项

如有客户端因为超低版本无法访问,请使用最新版谷歌浏览器或者火狐浏览器


五、外部参考

SSL/TLS安全评估报告


亚洲诚信ssl测试


ssllab测试


ssl证书配置指南

posted @ 2022-07-26 17:40  爱折腾的大臭臭  阅读(3449)  评论(0编辑  收藏  举报