如何让HTTPS站点评级达到A+? 还得看这篇HTTPS安全优化配置最佳实践指南

0x00 前言简述

SSL/TLS 简单说明

描述: 当下越来越多的网站管理员为企业站点或自己的站点进行了SSL/TLS配置, SSL/TLS 是一种简单易懂的技术,它很容易部署及运行,但要对其进行安全部署的情况下通常是不容易。

如果想掌握如何配置一个安全的 web 服务器或应用,往往需要系统管理员和开发者去了解 SSL 和 TLS 相关的技术, 这无疑会耗费很大的精力去看相关的技术文档,乏味且宽泛并加大了学习成本。

所以本篇文章主要是为了让系统管理员或开发者用尽可能少的时间部署一个安全的 web 站点或应用,即 SSL 和 TLS 部署最佳实践,但在学习实践之前我们需要了解一下SSL/TLS 相关术语,避免在后续实践中一头雾水。

原文地址:

前置知识推荐了解


SSL/TLS 相关术语一览

EV : EV证书(Extended Validation Certificate)是一种根据一系列特定标准颁发的X.509电子证书,根据要求,在颁发证书之前,证书颁发机构(CA)必须验证申请者的身份。不同机构根据证书标准发行的扩展验证证书并无太大差异,但是有时候根据一些具体的要求,特定机构发行的证书可以被特定的软件识别。
OV : OV证书(Organization Validation SSL),指需要验证网站所有单位的真实身份的标准型SSL证书,此类证书不仅能够起到网站信息加密的作用,而且能向用户证明网站的真实身份。
DV : DV证书(Domain Validation SSL),指需要验证域名的有效性。该类证书只提供基本的加密保障,不能提供域名所有者的信息。

CAA : DNS Certification Authority Authorization,使用DNS来指定该域名可以由哪些CA机构签发证书,这不是为TLS层的安全提供保证,而是作为CA签发证书程序中的一部分。使用CAA可以避免一些CA签发错误证书的情况。
CSR : CSR(Certificate Signing Request),在PKI系统中,CSR文件必须在申请和购买SSL证书之前创建,也就是证书申请者在申请数字证书时由CSP(加密服务提供者)在生成私钥的同时也生成证书请求文件,证书申请者只要把CSR文件提交给证书颁发机构后,证书颁发机构使用其根证书私钥签名就生成了证书公钥文件
CT : CT (Certificate Transparency) 证书透明,Certificate Transparency的目标是提供一个开放的审计和监控系统,可以让任何域名所有者或者CA确定证书是否被错误签发或者被恶意使用,从而提高HTTPS网站的安全性。
CRL : CRL(Certificate revocation list 证书吊销列表)是一个已经被吊销的数字证书的名单,这些在证书吊销列表中的证书不再会受到信任,但目前OCSP(在线证书状态协议)可以代替CRL实现证书状态检查。
OCSP : OCSP(Online Certificate Status Protocol)是一个用于获取X.509数字证书撤销状态的网际协议,在RCF 6960中定义,作为证书吊销列表的替代品解决公开密钥基础建设(PKI)中使用证书吊销列表而带来的多个问题。协议数据传输过程中使用ASN.1编码,并通常创建在HTTP协议上
OCSP Stapling : OCSP装订,是TLS证书状态查询扩展,作为在线证书状态协议的替代方法对X.509证书状态进行查询,服务器在TLS握手时发送事先缓存的OCSP响应,用户只要验证该响应的时效性而不用再向数字证书认证机构(CA)发送请求,可以加快握手速度。

RSA : RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。对极大整数做因数分解的难度决定了RSA算法的可靠性,支持签名和加密。
ECC : ECDSA(椭圆曲线签名算法)的常见叫法,和RSA同时具有签名和加密不同,它只能做签名,它的优势是具有很好的性能、大小和安全性更高。
DH/DHE : Diffie-Hellman(DH)密钥交换是一种密钥交换的协议,DH的诀窍是使用了一种正向计算简单、逆向计算困难的数学函数,即使交换中某些因子已被知晓,情况也是一样。DH密钥交换需要6个参数,其中两个(dh_p和dh_g)称为域参数,由服务器选取,协商过程中,客户端和服务器各自生成另外两个参数,相互发送其中一个参数(dh_Ys和dh_Yc)到对端,在经过计算,最终得到共享密钥。临时Diffie-Hellman(ephemeral Diffie-Hellman,DHE)密钥交换中没有任何参数被重复利用。与之相对,在一些DH密钥交换方式中,某些参数是静态的,并被嵌入到服务器和客户端的证书中,这样的话密钥交换的结果是一直不变的共享密钥,就无法具备前向保密的能力。
ECDH/ECHDE : 椭圆曲线Diffie-Hellman(elliptic curve Diffie-Hellman,ECDH)密钥交换原理与DH相似,但是它的核心使用了不同的数学基础,ECHD基于椭圆曲线加密,ECDH密钥交换发生在一条由服务器定义的椭圆曲线上,这条曲线代替了DH中域参数的角色,理论上,ECDH支持静态的密钥交换。临时椭圆曲线Diffie-Hellman密钥交换,和DHE类似,使用临时的参数,具有前向保密的能力。
RC4 : 是一种流加密算法,对称加密,密钥长度可变。由于RC4算法存在弱点,2015年2月所发布的 RFC 7465 规定禁止在TLS中使用RC4加密算法, Chrome 48版本开始会拒绝与「以 RC4 做为对称加密算法的 CipherSuite」建立 TLS 连接 。
3DES : 在加密套件中很多的密码使用的是3DES_EDE_CBC这种类型的,在维基上3DES提供的bits数是192bits(168+24),但由于Meet-in-the-middle attack攻击的影响,只能提供112bits的安全。因此在等级评定上使用192bits,在套件的安全性上使用112bits.
PSK : PSK 是“Pre-Shared Key”的缩写。就是 预先让通讯双方共享一些密钥(通常是对称加密密钥), 这种算法用的不多它的好处是:不需要依赖公钥体系,不需要部属 CA 证书。不需要涉及非对称加密,TLS 协议握手(初始化)时的性能好于 RSA 和 DH,密钥交换时通讯双方已经预先部署了若干个共享的密钥为了标识多个密钥,给每一个密钥定义一个唯一的 ID客户端通过ID 和服务端进行通讯。
SRP : TLS-SRP( Secure Remote Password)密码套件有两类:第一类密码套件仅使用SRP认证。第二类使用SRP认证和公共密钥证书来增加安全性。
TLS GREASE : 为了保持可扩展性,服务器必须忽略未知值,是Chrome 推出的一种探测机制。GREASE for TLS (https://tools.ietf.org/html/draft-davidben-tls-grease-01)
AEAD : 全称是使用关联数据的已验证加密,Authenticated Encryption with Associated Data (AEAD) algorithms, 是用一个算法在内部同时实现cipher+MAC,是TLS1.2、TLS1.3上采用的现代加密算法,相关密码套件(https://tools.ietf.org/html/rfc6655):

TLS_RSA_WITH_AES_128_CCM = {0xC0,0x9C}
TLS_RSA_WITH_AES_256_CCM = {0xC0,0x9D)
TLS_DHE_RSA_WITH_AES_128_CCM = {0xC0,0x9E}
TLS_DHE_RSA_WITH_AES_256_CCM = {0xC0,0x9F}
TLS_RSA_WITH_AES_128_CCM_8 = {0xC0,0xA0}
TLS_RSA_WITH_AES_256_CCM_8 = {0xC0,0xA1)
TLS_DHE_RSA_WITH_AES_128_CCM_8 = {0xC0,0xA2}
TLS_DHE_RSA_WITH_AES_256_CCM_8 = {0xC0,0xA3}

AES-GCM : AES-GCM是一种AEAD,是目前TLS的主力算法,互联网上https流量的大部分依赖使用AES-GCM。
ChaCha20-poly1305 : ChaCha20-poly1305是一种AEAD,提出者是Daniel J. Bernstein教授,针对移动互联网优化,目前Google对移动客户端的所有流量都使用ChaCha20-Poly1305
AES-CBC : 关于AES-CBC,在AES-GCM流行之前,TLS主要依赖AES-CBC,而由于历史原因,TLS在设计之初固定选择了MAC-then-Encrypt结构,AES-CBC和MAC-then-encrypt结合,为选择密文攻击(CCA)创造了便利条件,TLS历史上有多个漏洞都和CBC模式有关。

PFS : PFS(perfect forward secrecy)正向保密 ,在密码学中也可以被称为FS(forward secrecy),是安全通信协议的特性,要求一个密钥只能访问由它所保护的数据,用来产生密钥的元素一次一换,不能再产生其他的密钥,一个密钥被破解,并不影响其他密钥的安全性。
HPKP : 公钥固定,这是一种https网站防止攻击者使用CA错误颁发的证书进行中间人攻击的一种安全机制,用于预防诸如攻击者入侵CA偷发证书、浏览器信任CA签发伪造证书等情况,采用该机制后服务器会提供一个公钥哈希列表,客户端在后续的通信中只接受该列表上的一个或多个公钥。

HPKP是一个响应头 Public-Key-Pins:max-age=xxx;pin-sha256=xxxx;includeSubDomains; 其中可以使用多个pin-sha256,pin-sha256的值是对证书公钥sha256的值,includeSubDomains决定是否包含所有子域名,在max-age所指定的时间内(秒),证书链中的证书至少一个公钥须和固定公钥相符,这样客户端才认为该证书链是有效的,
还有一种响应头:Public-Key-Pins-Report-Only:max-age=xxx;pin-sha256=xxxx;includeSubDomains;report-uri=xxx,Public-Key-Pins-Report-Only 中的report-uri,决定是否回报违反HTTP公钥固定策略的事件。客户端进行HTTP公钥固定验证失败后,将把此次错误详情以JSON格式回报个report-uri参数中指定的服务器。

H2 : HTTP/2 的协议名称,口语叫法HTTP2和http/1.1 是一个概念,通过ALPN协商, HTTP/2 中只能使用 TLSv1.2+协议。

CSP : CSP,全称是 Content Security Policy,它有非常多的指令,用来实现各种各样与页面内容安全相关的功能。 这里只介绍两个与 HTTPS 相关的指令,更多内容可以看我之前写的《Content Security Policy Level 2 介绍》。

block-all-mixed-content :前面说过,对于 HTTPS 中的图片等 Optionally-blockable 类 HTTP 资源,现代浏览器默认会加载。图片类资源被劫持,通常不会有太大的问题,但也有一些风险,例如很多网页按钮是用图片实现的,中间人把这些图片改掉,也会干扰用户使用。通过 CSP 的 block-all-mixed-content 指令,可以让页面进入对混合内容的严格检测(Strict Mixed Content Checking)模式。在这种模式下,所有非 HTTPS 资源都不允许加载。跟其它所有 CSP 规则一样,可以通过以下两种方式启用这个指令。
HTTP 响应头方式:Content-Security-Policy: block-all-mixed-content
标签方式:upgrade-insecure-requests 通过 CSP 指令,可以让浏览器帮忙做这个转换。启用这个策略后,有两个变化页面所有 HTTP 资源,会被替换为 HTTPS 地址再发起请求, 页面所有站内链接,点击后会被替换为 HTTPS 地址再跳转;
跟其它所有 CSP 规则一样,这个指令也有两种方式来启用,具体格式请参考上一节。需要注意的是 upgrade-insecure-requests 只替换协议部分,所以只适用于 HTTP/HTTPS 域名和路径完全一致的场景。

HSTS: 在网站全站 HTTPS 后,如果用户手动敲入网站的 HTTP 地址,或者从其它地方点击了网站的 HTTP 链接,依赖于服务端 301/302 跳转才能使用 HTTPS 服务。而第一次的 HTTP 请求就有可能被劫持,导致请求无法到达服务器,从而构成 HTTPS 降级劫持。该问题可以通过 HSTS(HTTP Strict Transport Security,RFC6797)来解决。

HSTS 是一个响应头,格式如下:Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]

  • max-age,单位是秒,用来告诉浏览器在指定时间内,这个网站必须通过 HTTPS 协议来访问。也就是对于这个网站的 HTTP 地址,浏览器需要先在本地替换为 HTTPS 之后再发送请求。
  • includeSubDomains,可选参数,如果指定这个参数,表明这个网站所有子域名也必须通过 HTTPS 协议来访问。
  • preload,可选参数,后面再介绍它的作用。
    温馨提示: HSTS 这个响应头只能用于 HTTPS 响应;网站必须使用默认的 443 端口;必须使用域名且不能是 IP。而且启用 HSTS 之后一旦网站证书错误,用户无法选择忽略。

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

如果要想把自己的域名加进这个列表,首先需要满足以下条件,不过值得注意的是即便满足了上述所有条件,也不一定能进入 HSTS Preload List,更多信息可以看这里。

  • 拥有合法的证书(如果使用 SHA-1 证书,过期时间必须早于 2016 年);
  • 将所有 HTTP 流量重定向到 HTTPS;
  • 确保所有子域名都启用了 HTTPS;
  • 输出 HSTS 响应头:
  • max-age 不能低于 18 周(10886400 秒);
  • 必须指定 includeSubdomains 参数;
  • 必须指定 preload 参数;
    温馨提示: 通过 Chrome 的 chrome://net-internals/#hsts 工具,可以查询某个网站是否在 Preload List 之中,还可以手动把某个域名加到本机 Preload List。

SNI : SNI(服务器名称指示),这个是一个扩展的TLS协议,在该协议中,在TLS握手过程中客户端可以指定服务器的主机名称,这允许服务器在相同的IP和端口上部署多个证书,并允许在相同的IP地址上提供多个HTTPS网站或者基于TLS的服务。
SRI : HTTPS 可以防止数据在传输中被篡改,合法的证书也可以起到验证服务器身份的作用,但是如果 CDN 服务器被入侵,导致静态文件在服务器上被篡改,HTTPS 也无能为力。W3C 的 SRI(Subresource Integrity)规范可以用来解决这个问题。SRI 通过在页面引用资源时指定资源的摘要签名,来实现让浏览器验证资源是否被篡改的目的。只要页面不被篡改,SRI 策略就是可靠的, 有关 SRI 的更多说明请看Jerry Qu写的《Subresource Integrity 介绍》。SRI 并不是 HTTPS 专用,但如果主页面被劫持,攻击者可以轻松去掉资源摘要,从而失去浏览器的 SRI 校验机制。
ALPN : ALPN(应用层协议协商 Application-Layer Protocol Negotiation) 是一个进行应用层协议协商的传输层安全协议(TLS)扩展,ALPN允许应用层协商应该在安全连接上实行哪个协议,以避免额外且独立于应用层协议的往返协商通信, 它已被HTTP/2使用。
NPN : NPN(Next Protocol Negotiation) 下一协议协商,在TLS上允许应用层协商使用哪个协议,在2014年7月11日的RFC 7301中使用ALPN代替NPN。
STARTTLS : STARTTLS 是对纯文本通信协议(SMTP/POP3/IMAP)的扩展。它提供一种方式将纯文本连接升级为加密连接(TLS或SSL),而不是另外使用一个端口作加密通信。RFC 2595定义了IMAP和POP3的STARTTLS;RFC 3207定义了SMTP的;

Session ID : Session ID 完成SSL握手后会获得一个编号(Session ID)。如果对话中断,下次重连的时候,只要客户端给出这个编号,且服务器有这个编号的缓存,双方就可以重新使用已有的”对话密钥”,而不必重新生成一把(握手的主要开销)。 因为要缓存每个连接的握手参数,服务端存储开销会比较大。
Session Ticket : Session ticket获得方式和SessionID类似,但是使用时是在每次握手时由服务器进行解密,获得加密参数。服务端无需维持握手参数,可以减少内存开销。

POODLE : POODLE(贵宾犬漏洞 CVE-2014-3566),贵宾犬漏洞的根本原因是CBC模式在设计上的缺陷,具体来说就是CBC只对明文进行了身份验证,但是没有对填充字节进行完整性校验。这使得攻击者可以对填充字节修改并且利用填充预示来恢复加密内容,让POODLE攻击成为可能的原因是SSL3中过于松散的填充结构和校验规则。
TLS POODLE :TLS POODLE(TLS 贵宾犬漏洞 CVE-2014-8730) 该漏洞的原理和POODLE漏洞的原理一致,但不是SSL3协议,而是在TLS协议上,TLS协议本身没有问题,但是在其实现上。一些开发人员在进行SSL3到TLS的转换的时候,没有遵守协议规定的填充要求,使得他们的实现容易受到POODLE攻击的威胁

DROWN : 一句话概括就是“使用SSLv2对TLS进行交叉协议攻击”,DROWN(CVE-2016-0800)表示仅支持SSL2是对现代服务器和客户端的威胁,它允许攻击者通过讲探测发送到支持SSLv2的服务器并使用相同的私钥来解密最新客户端和服务器之间的TLS连接,如果如果服务器容易受到DROWN的影响,有两种原因:

  • 服务器允许SSL2连接
  • 私钥用于允许SSL2连接的其他服务器,即使是另一个支持SSL/TLS的协议,例如,Web服务器和邮件服务器上使用相同的私钥和证书,如果邮件服务器支持SSL2,即使web服务器不支持SSL2,攻击者可以利用
  • 邮件服务器来破坏与web服务器的TLS连接。
    使用40bit的出口限制RSA加密套件,单台PC能在一分钟内完成工具,对于攻击的一般变体(对任何SSL2服务起作用)也可以在8个小时内完成。

Logjam : Logjam(CVE-2015-4000) 使用 Diffie-Hellman 密钥交换协议的 TLS 连接很容易受到攻击,尤其是DH密钥中的公钥强度小于1024bits。中间人攻击者可将有漏洞的 TLS 连接降级至使用 512 字节导出级加密。这种攻击会影响支持 DHE_EXPORT 密码的所有服务器。这个攻击可通过为两组弱 Diffie-Hellman 参数预先计算 512 字节质数完成,特别是 Apache 的 httpd 版本 2.1.5 到 2.4.7,以及 OpenSSL 的所有版本。

BEAST : BEAST(CVE-2011-3389) BEAST攻击针对TLS1.0和更早版本的协议中的对称加密算法CBC模式,初始化向量IV可以预测,这就使得攻击者可以有效的讲CBC模式削弱为ECB模式,ECB模式是不安全的
Downgrade : Downgrade attack(降级攻击) 是一种对计算机系统或者通信协议的攻击,在降级攻击中,攻击者故意使系统放弃新式、安全性高的工作方式,反而使用为向下兼容而准备的老式、安全性差的工作方式,降级攻击常被用于中间人攻击,讲加密的通信协议安全性大幅削弱,得以进行原本不可能做到的攻击。 在现代的回退防御中,使用单独的信号套件来指示自愿降级行为,需要理解该信号并支持更高协议版本的服务器来终止协商,该套件是TLS_FALLBACK_SCSV(0x5600)

MITM : MITM(Man-in-the-middle) 是指攻击者与通讯的两端分别创建独立的联系,并交换其所有收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但事实上整个对话都被攻击者完全控制,在中间人攻击中,攻击者可以拦截通讯双方的通话并插入新的内容。一个中间人攻击能成功的前提条件是攻击者能够将自己伪装成每个参与会话的终端,并且不被其他终端识破。

Openssl Padding Oracle : Openssl Padding Oracle(CVE-2016-2107) openssl 1.0.1t到openssl 1.0.2h之前没有考虑某些填充检查期间的内存分配,这允许远程攻击者通过针对AES CBC会话的padding-oracle攻击来获取敏感的明文信息。

CCS : CCS(openssl MITM CCS injection attack CVE-2014-0224) 0.9.8za之前的Openssl,1.0.0m之前的以及1.0.1h之前的openssl没有适当的限制ChangeCipherSpec信息的处理,这允许中间人攻击者在通信之间使用0长度的主密钥。

FREAK : FREAK(CVE-2015-0204) 客户端会在一个全安全强度的RSA握手过程中接受使用弱安全强度的出口RSA密钥,其中关键在于客户端并没有允许协商任何出口级别的RSA密码套件。

Export-cipher : 在1998年9月之前,美国曾经限制出口高强度的加密算法。具体来说,限制对称加密强度为最大40位,限制密钥交换强度为最大512位。

CRIME : CRIME(Compression Ratio Info-leak Made Easy CVE-2012-4929),这是一种可攻击安全隐患,通过它可窃取启用数据压缩特性的HTTPS或SPDY协议传输的私密Web Cookie。在成功读取身份验证Cookie后,攻击者可以实行会话劫持和发动进一步攻击。
Heartbleed : Heartbleed(心血漏洞 CVE-2014-0160) 是Openssl的程序漏洞,如果使用带缺陷的Openssl版本,无论是服务器还是客户端,都可能因此受到攻击。此问题的原因是在实现TLS的心跳扩展时没有对输入进行适当的验证(缺少边界检查),该程序错误属于缓冲区过读,即可以读取的数据比应该允许读取的还多。


0x01 HTTPS安全实践指南

1.证书(certificate)与私钥(Private key)

描述: 在TLS中所有的安全性都从服务器的密码标识开始,所以我们需要一个强大的私钥以及有一个有效的和强大的证书来防止攻击者进行模拟攻击。

最佳安全实践
1.1) 建议使用2048位的RSA私钥或者128位的ECDSA私钥, 注意如果使用RSA私钥想要获得128位的安全性,则需要3072位的RSA key, 但会对性能造成一定影响, 所以推荐使用ECDSA key它是一种提供更好安全性和更好性能的替代方法。

1.2) 建议保护好你的私钥, 在可信计算机上用足够的熵生成私有密钥, 将密钥进行加密存储分配给指定人员管理, 可以访问拥有私钥的人越少越好, 除非保持相同的密钥对于公钥密钥很重要,否则每当获得新证书时,还应该生成新的私钥。

1.3) 建议从可信 CA 颁发获取证书, 选择CA时重点考虑如果以下条件提供商是否发生过安全风险、业务侧重点、是否提供对证书吊销列表(CRL)和在线证书状态协议(OCSP)撤销方法的支持、是否提供便捷的证书管理无法。

1.4) 建议使用强签名算法,证书安全性取决于用于签署证书的私钥的强度、签名中使用的散列函数的强度, 当前大多数的证书都依赖于SHA256散列函数,截止2022年。

1.5) 建议为指定站点名称申请对应证书而非使用通配符(泛域名)证书,通配符证书能满足更广泛的需求但如果准备将密钥暴露给更多的人员,特别是跨团队或部门,则避免使用它们。

温馨提示: 为了获得最佳效果,请提前获得证书,并在部署到生产业务环境之前至少一周,有助于避免在计算机上没有正确时间的一些用户的证书警告,以及避免与 CA 需要额外时间的 CA 失败的撤销检查,以向 OCSP 响应者传播有效的新证书

2.中间件SSL/TLS服务器配置

描述: 使用正确的TLS服务器配置,您可以确保将凭据正确呈现给站点的访问者,仅使用安全的加密原语,并减轻所有已知的缺陷。

最佳安全实践

2.1) 建议使用完整的证书链, 通过情况下仅服务器证书不够的,我们需要两个或多个证书来建立完整的信任链,当部署具有有效证书但没有所有必要的中间证书的服务器时会发生常见的配置问题,这是因为无效的证书链有效地使服务器证书无效并导致浏览器警告。

Let’sEncrypt快速颁发及自动续签泛域名证书实践指南(https://blog.weiyigeek.top/2022/3-11-589.html)

# 例如, 我采用Let'sEncrypt进签发的证书,生成nginx响应的证书配置链。
acme.sh  --installcert -d weiyigeek.top \
  --key-file /etc/nginx/ssl/weiyigeek.top.key \
  --fullchain-file /etc/nginx/ssl/fullchain.cer \
  --reloadcmd "service nginx force-reload"

# Nginx 中证书链与证书密钥配置
ssl_certificate      /etc/nginx/ssl/fullchain.cer;
ssl_certificate_key  /etc/nginx/ssl/weiyigeek.top.key;

2.2) 建议选择使用安全的SSL/TLS协议, 避免使用 SSL v2,SSL v3, 当前推荐使用 TLS v1.0,TLS v1.1和TLS v1.2 以及 TLS 1.3 协议以消除所有过时和不安全的功能。

# Nginx
# intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;

2.3) 建议选择使用安全的套件, 为了安全通信您必须首先确定您正在与所需方(而不是通过将窃听的其他人)直接沟通并安全地交换数据则需要至少128位加密的AEAD套件, 并且在配置中避免使用如下加密套件

NULL 密码套件不提供加密
匿名 Diffie-Hellman(ADH)套件不提供身份验证
弱密码(通常为 40 和 56 位)的套件使用可以轻松破坏的加密
MD5 密码套件是不安全的,容易被碰撞检测
RC4 密码套件是不安全的
DES/3DES 密码套件缓慢而虚弱

例如, Nginx 中的ssl_ciphers配置项里加入不支持如下 !NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DES:!3DES:!MD5:!RC4; 密码套件。
# 使用以RSA和ECDSA键为基础的以下套件配置,作为起点(使用标准 TLS 套件名称):
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES128-SHA
ECDHE-ECDSA-AES256-SHA
ECDHE-ECDSA-AES128-SHA256
ECDHE-ECDSA-AES256-SHA384
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-RSA-AES128-SHA
ECDHE-RSA-AES256-SHA
ECDHE-RSA-AES128-SHA256
ECDHE-RSA-AES256-SHA384
DHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES128-SHA
DHE-RSA-AES256-SHA
DHE-RSA-AES128-SHA256
DHE-RSA-AES256-SHA256

# 使用 openssl 命令查看指定套件对应的标准 TLS 套件名称以及支持的协议。
openssl ciphers -V 'ECDHE-RSA-AES128-GCM-SHA256:ECDH:AES:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:HIGH:!NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DES:!MD5:!RC4;' | column -t
0x13,0x02  -  TLS_AES_256_GCM_SHA384          TLSv1.3  Kx=any   Au=any    Enc=AESGCM(256)             Mac    =AEAD
0x13,0x03  -  TLS_CHACHA20_POLY1305_SHA256    TLSv1.3  Kx=any   Au=any    Enc=CHACHA20/POLY1305(256)  Mac    =AEAD
0x13,0x01  -  TLS_AES_128_GCM_SHA256          TLSv1.3  Kx=any   Au=any    Enc=AESGCM(128)             Mac    =AEAD
0xC0,0x2F  -  ECDHE-RSA-AES128-GCM-SHA256     TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)             Mac    =AEAD

# Nginx
# 推荐安全配置(牺牲了兼容性)生产环境中请根据业务需要配置。
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

2.4) 建议选择合适的协议在SSLv3及更高版本的协议版本中, 将通用性安全较强的套件放在首位,使服务器主动选择最佳可用加密套件对于实现最佳安全性至关重要。

2.5) 建议使用FS前向保密, FS有时也称为完全前向保密是一种协议功能,可实现不依赖服务器私钥的安全对话, 对于不提前向保密的密码套件,如果有可以恢复服务器的私钥的人就可以解密所有较早记录的加密对话(也就是可以先大量记录密文,再解密,比如您的证书到期后没有正确销毁,它的私钥就能用来解密非PFS的密文),所以我们应该使用 DHE 套件作为 ECDHE 后备并且避免 RSA 密钥交换(除非必要)。

2.6) 建议使用强的密钥交换算法,前面我们说不建议选择经典的短暂的 Diffie-Hellman密钥交换(DHE)以及RSA 密钥交换(不提供FS前向保密),通常推荐其椭圆曲线变体 ECDHE 密钥交换,它更加安全和快速。

温馨提示: 我们建议您始终首先在分段环境中测试TLS配置,仅在确定所有内容按预期工作时将更改应用到生产环境。请注意,以上是一个通用列表,并不是所有系统(特别是较旧的)支持所有套件。

3.SSL/TLS站点性能

描述: 本章节HTTPS安全是我们讨论的重点,于此同时我们也需要关注配置了TLS站点的性能, 一个不符合性能标准的安全服务无疑将被丢弃。通过正确配置TLS服务器访问其站点时速度将会有很大提升, 例如使用现代协议(例如 HTTP/2),甚至可能比明文通信更快。。

最佳安全实践
3.1) 建议避免使用过度安全的密钥长度, 使用超过 2048 位的 RSA 密钥和强大于 256 位的 ECDSA 密钥会浪费 CPU 功耗,并可能会损害用户体验。

3.2) 建议使用 session 恢复, 会话恢复是一种性能优化技术,可以节省昂贵的密码操作的结果,并重复使用一段时间.

# Nginx 
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
ssl_session_tickets off;

3.3) 建议使用 WAN 优化和启用 HTTP/2, 通常TLS 开销不是来自CPU的加密操作,而是来自网络延迟, 只有在 TCP 握手完成后才能启动TLS握手,需要进一步交换数据包,并且离开服务器的距离更远, 所以最小化延迟的最佳方法是避免创建新的连接,换句话说就是保持现有的连接长时间(keep-alives)。

# Nginx
server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
}
......

3.4) 建议缓存网站中公共的静态资源, 通过TLS进行通信时浏览器可能会认为所有流量都是敏感的, 默认的浏览器在使用中会缓存某些静态资源但是一旦关闭浏览器所有缓存内容可能会丢失, 所以为了获得性能提升我们需要长期缓存一些静态资源。

3.5) 建议使用 OCSP Stapling, OCSP 装订是 OCSP 协议的扩展,可以直接从服务器提供撤销信息作为 TLS 握手的一部分。因此客户端不需要联系 OCSP 服务器进行带外验证,并且总体 TLS 连接时间显着减少。

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;

# verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;

3.6) 建议使用 ECDSA 密钥进行快速加密, 在选择加密套件时除了保证其安全性还需要其良好的性能表现, 尽可能使用支持硬件加速 AES 的 CPU。

温馨提示: 用于建立安全连接的密码握手是一种操作,其费用受私钥大小的高度影响,使用太短的密钥是不安全的,但使用太长的密钥将导致“太多”的安全性和缓慢的操作。
温馨提示: 残疾或非功能性会话恢复机制可能会引起显着的性能损失。
温馨提示: OCSP装订是一种重要的优化技术,但并不是所有的网络服务器都提供了可靠的 OCSP 装订实现。

4.HTTP与应用安全

描述: HTTP 协议和 Web 应用交付的周边平台在 SSL 诞生后继续快速发展, 所以在进行TLS服务器配置时它们也是最重要的一环。

最佳安全实践
4.1) 建议加密无处不在, https加密不能是可选项,可靠地保护网站通信的唯一方法是无一例外地执行加密。

4.2) 建议消除混合内容, 请将任何地方的所有内容都 HTTPS 化(全站 HTTPS), 通过 TLS 传输但是包含不通过 TLS 传输的资源(例如,JavaScript 文件,images,CSS 文件)的页面, 可能会被一个活跃的中间人(MITM)攻击者可以搭载一个单独的未受保护的 JavaScript 资源,便有可能劫持用户的会话。

4.3) 建议使用可信第三方js或者css并且第三方必须是警告https加密的从而避免MITM 攻击, 于此同时使用子资源完整性(SRI)的新技术,可用于通过第三方资源来减少潜在的风险。

4.4) 建议配置安全cookie,要正确安全网站需要 TLS,而且所有的 Cookie 在创建时都被明确标记为安全的,为了获得最佳效果,请考虑为您的 Cookie 添加加密完整性验证或甚至加密。

4.5) 建议进行安全 HTTP 压缩, TIME 和 BREACH 专注于使用 HTTP 压缩压缩的 HTTP 响应实体中的秘密,HTTP 压缩是必需的不能关闭。

4.6) 建议部署配置 CSP ,内容安全策略(CSP)是网站可以用来限制浏览器操作的安全机制。尽管最初旨在解决跨站点脚本(XSS),CSP 不断发展并支持对增强TLS安全性有用的功能, 部署CSP可以防止第三方混合内容,通常使用Strict-Transport-Security响应头。

4.7) 建议不要缓存敏感内容

4.8) 考虑其它威胁, TLS 旨在仅解决安全机密和您与用户之间通信的完整性的一个方面,但还有许多其他威胁需要处理,确保您的网站尽可能的减少攻击面。

温馨提示: 下述配置是不一定是部署 CSP 的最佳方法,为了提供不破坏混合内容以外的任何内容的示例,我不得不禁用某些默认安全功能。随着时间的推移,当您了解 CSP 的更多信息时,您应该更改您的策略以使其恢复。

Content-Security-Policy: default-src https: 'unsafe-inline' 'unsafe-eval'; connect-src https: wss:

5.定期HTTPS检查避免已知问题

描述: 近几年来已经发生了几次严重的 SSL 和 TLS 攻击,但是如果您正在运行最新的openssl软件以及使用上述指南中的协议和加密套件建议,那么它们通常不会关心您。但是没有什么是完全安全的,所以为了保持对安全性的了解, 你应该排查和关注https相关漏洞, 以便于在第一时间保护或更新您的TLS服务器配置。

所以通常情况下我建议定期使用全面的 SSL/TLS 评估工具来验证您的配置,以确保您开始安全,对于公共网站建议您使用如下SSL实验室服务器进行站点https测试评估。

最佳安全实践
5.1) 建议定期使用如下SSL、TLS 评估工具对TLS配置进行检查评估。

  • 国外推荐:
    ssllabs : 网站地址(https://www.ssllabs.com),其检测内容非常的详细,包括证书、协议以及客户端模拟和兼容行。
    cdn77 : 网站地址(https://www.cdn77.com/tls-test), 功能单一只针对 TLS 、SSL协议版本进行评估。

WeiyiGeek.ssllabs证书配置检测

  • 国内推荐:
    myssl : 网站地址(https://myssl.com),这个是国内的检测站点与 ssllabs 相似,但个人感觉界面更清爽,证书检测的功能更多,访问速度也是快很多杠杠的,它还可以为您的https站点进行多方面综合的评级,其中包括了证书、SSL协议、加密套件、漏洞、不安全的外链等等,便于网站管理人员排查验证服务器应用证书配置是否正确。

WeiyiGeek.检测部署SSL/TLS的服务是否符合行业最佳实践

5.2) 建议排查验证配置的TLS服务器是否使用下述相关漏洞所关联的openssl版本、加密套件以及脆弱的SSL、TLS协议。

DROWN 漏洞
OpenSSL Padding Oracle 攻击
FREAK漏洞
Logjam漏洞
OpenSSL CCS 注入漏洞
心血漏洞(Heartbleed)
POODLE漏洞
CRIME漏洞

5.3) 了解或者使用 HPKP, 公共密钥固定旨在使网站运营商有权限制哪些 CA 可以为其网站颁发证书。Google 已经部署了这个功能了一段时间(硬编码到他们的浏览器,Chrome),并且已被证明是非常有用的,以防止攻击并使公众了解它们, 但是需要一定的成本,部署需要大量精力和专业知识。

5.4) 建议配置使用 DNSSEC, 全称是域名系统安全扩展(Domain Name System Security Extensions),它是一种增加域名系统完整性的技术,是由IETF提供的一系列DNS安全认证的机制(可参考RFC2535)它提供一种可以验证应答信息真实性和完整性的机制,利用密码技术,使得域名解析服务器可以验证它所收到的应答(包括域名不存在的应答)是否来自于真实的服务器,或者是否在传输过程中被篡改过。通过DNSSEC的部署,可以增强对DNS域名服务器的身份认证,进而帮助防止DNS缓存污染等攻击。(配置示例请参考下小节的实践配置)

简单的说,DNSSEC依靠数字签名保证DNS应答报文的真实性和完整性。

WeiyiGeek.DNSSEC运作方式

5.5) 建议为电子邮件系统配置使用 DANE , DANE一种将X.509证书绑定到DNS中的机制, 可用于存储自签名证书或者从CA签发的特定X.509证书, 其中, 证书作为DNS资源记录通过DNSSEC来实现其来源验证和完整性保护,根据证书用途的不同, 基于DANE的DNS资源记录也有所不同, DANE协议的动机之一是解决现有的基于X.509的PKI的问题. 例如, DANE在应对欺诈证书、处理证书撤销、创建可全球发布和检索证书的管理机制并允许自签名证书授权等方面提供了很好的解决方式.

实践配置
1.在腾讯云DNSPod控制台开启DNSSEC流程操作。(PS: 收费版DNS套餐提供)
第一步:登陆 DNSPod 控制台开启 DNSSEC 服务。

[控制台]- DNS 解析 – 我的域名 – 域名设置 – DNSSEC ,点击开启,即可查看该域名的 DS 记录。

第二步:前往域名注册商控制台添加 DS 记录。

前面拿到的 DS 记录,还需在您域名注册商的控制台进行添加。(如果您的域名同样注册于腾讯云(DNSPod),则该步骤自动完成)
PS: 该域名注册于腾讯云且属当前账号,系统将自动为您添加 DS 记录(https://docs.dnspod.cn/dns/dnssec-configuration/)

WeiyiGeek.腾讯云中开启DNSSEC服务

第三步: 查看验证DNSSEC是否配置成功, 此处仍然以腾讯云为例(我的域名在腾讯购买的没办法)。

[控制台]- 域名注册 – 我的域名 -> 管理 -> 域名安全 -> DNSSEC 设置(点击管理)

WeiyiGeek.腾讯云中查看DNSSEC配置

温馨提示: 目前只有少数注册商支持 DNSSEC ,如果您域名所在注册商不支持,可先将域名转入腾讯云,转入后方便一站管理,更可一键开启(带转入链接)

总结说明
描述: HTTPS安全也是网络安全的一个重要点,想要部署 TLS 是非常容易的,但其难点在于如何使用安全的配置来保障站点的安全。尤其是 Protocol 版本和 Cipher 需要小心选择和配置, 然后是一个门户或者其它用途的站点需要根据业务情况、针对用户群体、实际情况制定相应的TLS配置,最大限度的保证在安全的同时下对业务或者用户访问造成的影响越小越好,其次是针对某些严重危害应用或数据安全的应该及时修补,避免造成更大的影响。

本文章来源 我的Blog站点 或者 WeiyiGeek 公众账号 (技术交流、友链交换请邮我哟)
欢迎各位志同道合的朋友一起学习交流,如文章有误请留下您宝贵的知识建议,通过邮箱【master#weiyigeek.top】联系我哟!