在 Qualys SSL Labs SSL 测试中获得 A+ 评级的秘技 2021 版

本系列文章将阐述主流应用交付控制器和主流 Web 服务器如何运行 HTTP/2 和 TLSv1.3 协议,以及如何在 SSL Test 中获得 A+ 评级。

请访问原文链接:https://sysin.org/blog/get-a-plus-rating-on-ssl-test/,查看最新版。原创作品,转载请保留出处。

作者:gc(at)sysin.org,主页:www.sysin.org

2021 年 8 月发布的 Windows Server 2022 正式支持 QUIC 和 TLS 1.3 相关特性。至此,主流产品已经全部支持 TLSv1.3 协议。

0. 概述

Qualys SSL Labs 简介

Qualys,Inc.(NASDAQ:QLYS)是云安全和合规解决方案的先驱和领先提供商,在 100 多个国家拥有 6700 多个客户,其中包括福布斯全球 100 强和财富 100 强中的大多数。QualysGuard 云平台和集成解决方案套件通过按需提供关键的安全智能并自动化 IT 系统和 web 应用程序的全方位审核、法规遵从性和保护,帮助组织简化安全操作并降低合规成本。Qualys 成立于 1999 年,与英国电信、戴尔安全工程、富士通、IBM、NTT、Symantec、Verizon 和 Wipro 等领先的托管服务提供商和咨询机构建立了战略合作关系。该公司还是云安全联盟(CSA)的创始成员。

SSL Labs 推出的全球知名的 SSL 网站在线检测工具,会对 HTTPS 网站的证书链、安全性、性能、协议细节进行全面检测,检测完毕后会进行打分,同时给出一份详细的检测报告和改进建议。

测试网站:https://www.ssllabs.com/ssltest/

测试规则概述

2020 年算法变更

January 2020

主要是修改了 TLS 1.0 和 TLS 1.1 的评分标准,TLS 1.0 和 TLS 1.1 是分别于 1996 年和 2006 年发布的老版协议,使用的是弱加密算法和系统。比如 SHA-1 和 MD5,这些算法和系统十分脆弱,存在重大安全漏洞,容易受到降级攻击的严重影响,而在 2008 年和 2017 年分别发布了协议的新版本,即 TLS 1.2 和 TLS 1.3,无疑更优于旧版本,使用起来也更安全。

2018 年,在春季 TLS 1.3 版本发布之后,苹果、谷歌、Mozilla 和微软四大浏览器制造商于 2018 年 10 月联合宣布计划在 2020 年初取消对 TLS 1.0 和 TLS 1.1 的支持。

主流浏览器客户端都提供了禁用 TLS 1.0 和 TLS 1.1 协议的大致期限:

Browser Name Date
Microsoft IE and Edge First half of 2020
Mozilla Firefox March 2020
Safari/Webkit March 2020
Google Chrome January 2020

备注:由于受 COVID-19 影响,浏览器厂商推迟了 TLS 1.0 和 1.1 版本协议的淘汰时间。

Existing Grades Sample

Server Configuration Grade
TLS 1.2, TLS 1.1, TLS 1.0 + HSTS + No Warning + TLS_FALLBACK_SCSV A+
TLS 1.2, TLS 1.1, TLS 1.0 + HSTS + No Warning + No support for TLS_FALLBACK_SCSV A
TLS 1.2, TLS 1.1, TLS 1.0 + HSTS + Warnings + No support for TLS_FALLBACK_SCSV A-

Future Grades Sample

Server Configuration Grade
TLS 1.2, TLS 1.1, TLS 1.0 + HSTS + No Warning + TLS_FALLBACK_SCSV B
TLS 1.2, TLS 1.1, TLS 1.0 + HSTS + No Warning + No support for TLS_FALLBACK_SCSV B
TLS 1.2, TLS 1.1, TLS 1.0 + HSTS + Warnings + No support for TLS_FALLBACK_SCSV B
TLS 1.2 + HSTS + No Warning + TLS_FALLBACK_SCSV A+
TLS 1.2 + HSTS + No Warning + No support for TLS_FALLBACK_SCSV A
TLS 1.2 + HSTS + Warnings + No support for TLS_FALLBACK_SCSV A-

References

  • Modernizing TLS connections in Microsoft Edge and Internet Explorer 11 : https://blogs.windows.com/msedgedev/2018/10/15/modernizing-tls-edge-ie11/
  • Removing Old Versions of TLS : https://blog.mozilla.org/security/2018/10/15/removing-old-versions-of-tls/
  • Deprecation of Legacy TLS 1.0 and 1.1 Versions: https://webkit.org/blog/8462/deprecation-of-legacy-tls-1-0-and-1-1-versions/
  • Modernizing Transport Security: https://security.googleblog.com/2018/10/modernizing-transport-security.html
  • Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS): https://tools.ietf.org/html/rfc7525

1. F5 BIG-IP

BIG-IP ® 系统是一组应用交付产品,它们协同工作以确保高可用性、改进的性能、应用安全和访问控制。BIG-IP 系统的主要功能之一是将不同类型的协议和应用程序流量定向到适当的目标服务器。系统通过其 Local Traffic Manager™ 模块实现这一点,该模块可以将流量直接转发到负载平衡服务器池,或将流量发送到下一跳路由器、路由器池或直接发送到网络上的选定节点。BIG-IP 系统上可用的其他模块提供关键功能,例如将安全策略应用于网络流量、加速 HTTP 连接以及优化广域网中的连接。

F5 BIG-IP 默认 B 级别(本例基于当前最新的 BIG-IP 16.0.0)

TLS 1.2 + HSTS + No Warning + TLS_FALLBACK_SCSV = A+

(No Warning 即受信任 SSL 证书,TLS_FALLBACK_SCSV F5 默认支持)

故:A 级别 + 开启 HSTS = A+,推荐启用 TLSv1_3 和 HTTP/2

其他应用交付产品可以参照 F5 配置

1.1 Ciphers 配置:A 级别 (TLSv1.2)

根据 2020 年 1 月算法变更,需要 TLSv1.2 及以上版本才能获得 A,新的 A 级别如下:

ECDHE+AES-GCM:ECDHE+AES-GCM:ECDHE+AES:ECDHE+3DES:RSA+AES-GCM:RSA+AES:RSA+3DES:-MD5:-RC4:-SSLv3:-TLSv1:-TLSv1_1

或者:

ECDHE+AES-GCM:ECDHE+AES:ECDHE+3DES:RSA+AES-GCM:RSA+AES:RSA+3DES:-MD5:-RC4:-SSLv3:-TLSv1:-TLSv1_1

F5 Cipher TLS 版本写法(与 nginx 和 apache 等使用 OpenSSL 的软件略有不同):

TLSv1
TLSv1_1
TLSv1_2
TLSv1_3

执行步骤:

编辑 SSL Profile,修改 Ciphers,将默认 Default 替换上述内容。

1.2 启用 HSTS

HSTS(HTTP Strict Transport Security,RFC6797),即 HTTP 严格安全传输,是国际互联网工程组织 IETF 正在推行一种新的 Web 安全协议,网站采用 HSTS 后,用户访问时无需手动在地址栏中输入 HTTPS,浏览器会自动采用 HTTPS 访问网站地址,从而保证用户始终访问到网站的加密链接,保护数据传输安全。HSTS 的作用是强制客户端(如浏览器)使用 HTTPS 与服务器创建连接。服务器开启 HSTS 的方法是,当客户端通过 HTTPS 发出请求时,在服务器返回的超文本传输协议响应头中包含 Strict-Transport-Security 字段。

Preload List:让防御更加彻底

HSTS 存在一个比较薄弱的环节,那就是浏览器没有当前网站的 HSTS 信息的时候,或者第一次访问网站的时候,依然需要一次明文的 HTTP 请求和重定向才能切换到 HTTPS,以及刷新 HSTS 信息。而就是这么一瞬间却给攻击者留下了可乘之机,使得他们可以把这一次的 HTTP 请求劫持下来,继续中间人攻击。针对这种攻击,HSTS 也有应对办法,那就是在浏览器里内置一个列表 Preload List,只要是在这个列表里的域名,无论何时、何种情况,浏览器都只使用 HTTPS 发起连接。这个列表由 Google Chromium 维护,FireFox、Safari、IE 等主流浏览器均在使用。

可以通过官网(https://hstspreload.org),查询网站是否在 Preload List,可以申请将网站加入到 Preload List

执行步骤:

v12 及以上版本直接在 TMUI 中 Enabling HSTS in the HTTP profile 或者使用 iRuels

v11 及以下可以只能通过 iRules 实现

### iRule for HSTS HTTP Virtuals ###
when HTTP_REQUEST {
HTTP::respond 301 Location "https://[HTTP::host][HTTP::uri]"
}
### iRule for HSTS HTTPS Virtuals ###

## 31536000 sec = 1 Year

when HTTP_RESPONSE {
 HTTP::header insert Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
}

OR

when HTTP_RESPONSE {
 HTTP::header insert Strict-Transport-Security "max-age=31536000; includeSubDomains"
}

其中:

  • max-age 是必选参数,是一个以秒为单位的数值,它代表着 HSTS Header 的过期时间,通常设置为 1 年,即 31536000 秒。
  • includeSubDomains 是可选参数,如果包含它,则意味着当前域名及其子域名均开启 HSTS 保护。
  • preload 是可选参数,只有当你申请将自己的域名加入到浏览器内置列表的时候才需要使用到它。

1.3 启用 TLSv1_3

F5 BIG-IP 当前 LTS 版本 14.1.0、15.1.0、16.1.0 及以上版本都可以完整支持 TLSv1_3。

BIG-IP v14 开始支持 TLSv1_3(In BIG-IP 14.0.0, the BIG-IP system adds limited support for Transport Layer Security (TLS) 1.3. Starting in BIG-IP 14.1.0.1 and later, this support was updated to provide production level support for TLS 1.3.)

默认没有启用:By default, TLS 1.3 is disabled. To enable TLS 1.3, you must remove the No TLSv1.3 option from the Enabled Options list in the Configuration utility for the Client SSL and Server SSL profiles

You can view a list of TLS 1.3 supported ciphers and groups using the following TMOS Shell (tmsh) commands:

  • To view the supported client-side ciphers, use the following command:

    tmsh run util clientssl-ciphers TLSv1_3

  • To view the supported server-side ciphers, use the following command:

    tmsh run util serverssl-ciphers TLSv1_3

配置启用 TLSv1_3:

编辑 ClientSSL Profle:

Ciphers:选择 Cipher Group,下拉选择 f5-secure

Options:Options List...

Enabled Options,

Disable No TLSv1.3

添加,No TLSv1 和 TLSv1.1,保留默认的 “Don't insert empty fragments”

1.4 配置 HTTP/2

不在赘述,详见 官方文档。

配置 HTTP/2 就是在启用 HTTP profile 的 VS 上关联一个 HTTP/2 profile,核心参数配置任然在原有的 HTTP profile 上。

特殊配置是 SSL profile 要取消勾选 Renegotiation,其他都可以使用默认配置。

1.5 TLS-FALLBACK-SCSV

TLS-FALLBACK-SCSV(TLS Fallback Signaling Cipher Suite Value)是 OpenSSL 的一种阻止协议降级攻击的特性和机制。F5 BIG-IP,Nginx 和 Apache httpd 的 HTTPS 皆基于 OpenSSL 实现,符合要求的 OpenSSL 版本即可支持。

Poodle and TLS-FALLBACK-SCSV

SSLv3 allows exploiting of the POODLE bug. This is one more major reason to disable this.

Google have proposed an extension to SSL/TLS named TLS FALLBACK SCSV that seeks to prevent forced SSL downgrades. This is automatically enabled if you upgrade OpenSSL to the following versions:

  • OpenSSL 1.0.1 has TLS FALLBACK SCSV in 1.0.1j and higher.
  • OpenSSL 1.0.0 has TLS FALLBACK SCSV in 1.0.0o and higher.
  • OpenSSL 0.9.8 has TLS FALLBACK SCSV in 0.9.8zc and higher.

TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks。

2. Microsoft IIS

Windows® Server 的 Internet 信息服务 (IIS) 是一种灵活、安全且可管理的 Web 服务器,用于托管 Web 上的任何内容。从媒体流到 Web 应用程序,IIS 的可扩展和开放架构已准备好处理最苛刻的任务。

根据规则:TLS 1.2 + HSTS + No Warning + TLS_FALLBACK_SCSV = A+

理论上 Windows & IIS 不支持 TLS_FALLBACK_SCSV,所以无法 A+,但是 开启 HSTS,并仅启用 TLS1.2 可以获得 A+ 得分,这样就不存在协议降级风险。

Microsoft 的 SSL 基于 Schannel 实现,与 OpenSSL 无关(或称 Microsoft TLS)。

Schannel is a Security Support Provider (SSP) that implements the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) Internet standard authentication protocols.
The Security Support Provider Interface (SSPI) is an API used by Windows systems to perform security-related functions including authentication. The SSPI functions as a common interface to several SSPs, including the Schannel SSP.

2.1 IIS 获得 A 级别

测试环境:IIS 10 on Windows Server 2019

执行 ps 脚本 或者使用 IIS Crypto,将获得 A,这里以 IIS Crypto 为例:

IIS Crypto:点击 “Best Pratices”,Server Protocols 只勾选 TLS 1.2,Apply 并重启生效。

在 Qualys SSL Labs SSL 测试中获得 A+ 评级的秘技 2021 版_第1张图片

仅启用 TLS 1.2 将获得 A,远程桌面也可以正常连接,启用 HSTS 将获得 A+。

在早期的 Windows 版本中,仅启用 TLS 1.2 远程桌面将无法连接。

2.2 HSTS

分位两种情况,旧版需要安装 IIS 模块,新版(Windows Server 2019+)自带 HSTS 选项。

  • In older versions of IIS (IIS 7.0 to 10.0 R1703) this requirement can only archived the simple way with an installation of HTTP Strict Transport Security IIS Module.

  • Microsoft added native HTTP Strict Transport Security (HSTS) Support to IIS 10.0 Version 1709

IIS 管理器 -- 选择站点 -- 高级设置 -- HSTS

在 Qualys SSL Labs SSL 测试中获得 A+ 评级的秘技 2021 版_第2张图片

在 Qualys SSL Labs SSL 测试中获得 A+ 评级的秘技 2021 版_第3张图片

2.3 TLSv1.3

2021 年 8 月发布的 Windows Server 2022 正式支持 HTTP/3、QUIC 和 TLS 1.3 相关特性。

在 Windows Server 2022 中的 IIS 新建一个站点将默认启用 TLS 1.3 以及 QUIC,除非手动勾选禁用。

备注:IIS 10 & Windows Server 2019 以及之前版本无法支持,参看。

2.4 HTTP/2

版本要求:

HTTP2 requires Windows 2016 with IIS 10 or later.

配置方法:

首先配置好 SSL 证书并创建 HTTPS 站点,IIS 10 默认开启 HTTP/2 协议,所以我们都不要额外去设置(可以禁用,新建站点时或者 "编辑网站" > "绑定..." 勾选 "禁用 HTTP/2")。

在 Qualys SSL Labs SSL 测试中获得 A+ 评级的秘技 2021 版_第4张图片

在 Windows Server 2022 中的 IIS 新建一个站点将默认启用 TLS 1.3 以及 QUIC(HTTP/3),除非手动勾选禁用。

3. Nginx

nginx [engine x] 是一个 HTTP 和反向代理服务器,邮件代理服务器,和一个通用的 TCP/UDP 代理服务器,最初由 Igor Sysoev 编写。在许多负载很重的俄罗斯网站上运行了很久,包括 Yandex,Mail.Ru,VK,和 Rambler。根据 Netcraft 的说法,nginx 服务或代理 22.36% 最繁忙的网站 (2021 年 11 月)。
以下是一些成功案例:Dropbox,Netflix,Wordpress.com,FastMail.FM。

3.1 Nginx SSL 证书配置方法

官方文档

server {
    listen       443 ssl;
    server_name  www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ...
}

证书文件使用 PEM 格式。

证书文件使用相对路径时,证书文件要放在主配置文件相同目录下(默认 /etc/nginx)。

更多配置,这篇文章可以参考:Strong SSL Security on nginx

3.2 TLSv1.3

版本支持如下:

  • The TLSv1.1 and TLSv1.2 parameters (1.1.13, 1.0.12) work only when OpenSSL 1.0.1 or higher is used.
  • The TLSv1.3 parameter (1.13.0) works only when OpenSSL 1.1.1 built with TLSv1.3 support is used.

More info on the NGINX documentation

3.3 HTTP/2

版本要求:

openssl 的版本必须在 1.0.2e 及以上,执行以下命令验证:

openssl version

nginx 的版本必须在 1.9.5 以上,需要添加 --with-http_v2_module 模块,执行以下命令验证:

nginx -V

3.4 参考配置

以下配置:启用 HTTP/2、TLSv1.3、推荐的 Ciphers、HSTS,可以获得 A+ 得分

server {
    #listen       443 ssl;
    listen       443 ssl http2; # HTTP/2 Enable
    listen       [::]:443 ssl http2; # IPv6
    server_name  www.sysin.org;
    ssl_certificate     www.sysin.org.crt;
    ssl_certificate_key www.sysin.org.key;
    ssl_protocols       TLSv1.2 TLSv1.3; # Requires nginx >= 1.13.0 else use TLSv1.2
    ssl_ciphers         HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA;
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload" always;
    ...
}

    #ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    #ssl_ciphers  HIGH:!aNULL:!MD5;  #B
    #ssl_ciphers  HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA;  #A
    #ssl_ciphers  ALL:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4;  #B
    #ssl_ciphers  ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;  #A (Mozilla Intermediate)

4. Kubernetes ingress-nginx

4.1 概述

默认 TLS 版本和 Ciphers

nginx-ingress 默认仅使用 TLS 1.2 和 1.3,with a secure set of TLS ciphers.

默认 cipher 列表: 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.

Legacy TLS 支持

如果需要兼容一些老旧的浏览器和操作系统,需要使用 ConfigMap 修改默认配置,例如:

mozilla-ssl-config-old

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
data:
  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:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
  ssl-protocols: "TLSv1 TLSv1.1 TLSv1.2 TLSv1.3"

HSTS 默认启用

可以在 ConfigMap 中配置参数 hsts: "false" 禁用默认行为

HTTP redirect

对于 TLS 类型的 ingress,控制器默认将 HTTP 请求定向到 HTTPS(308 Permanent Redirect response),

可以在 NGINX config map,中使用 ssl-redirect: "false" 参数全局禁用,或者针对单个 ingress 规则使用 annotation nginx.ingress.kubernetes.io/ssl-redirect: "false" 来禁用。

本例部署的 ingress-nginx 版本为 0.30.0,经过测试只要使用受信任证书,即可获得 A+ 得分。

4.2 示例

以下发布 Dashboard 为例,配置受信任 SSL 证书。

查看 Dashboard 已经正常部署(部署 Dashboard 参看其他文档):

kubectl get po,svc -n kubernetes-dashboard -o wide

部署受信任的 SSL 证书:

# 创建 secret,在 ingress 不能直接使用证书需要转换为 secret 才能使用
# key 和 cert 都为 PEM 格式,cert 包含证书文件和证书链部分
kubectl create secret tls dashboard-ingress-tls --key dashboard-ingress.key --cert dashboard-ingress.crt -n kubernetes-dashboard
# 查看 secret 内容
kubectl get secret dashboard-ingress-tls -n kubernetes-dashboard -o yaml
# 删除命令
kubectl delete secret dashboard-ingress-tls -n kubernetes-dashboard

配置 ingress 转发文件

# vi dashboard-ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
  name: kubernetes-dashboard-ingress
  namespace: kubernetes-dashboard #注意修改
spec:
  tls:
  - secretName: dashboard-ingress-tls #上述创建的 secret
  rules:
    - host: k8s.sysin.cn #域名
      http:
 paths:
 - path: /
   backend:
     serviceName: kubernetes-dashboard
     servicePort: 443

host: 对应的域名
path: url 上下文
backend: 后向转发到对应的 serviceName: 和 servicePort:

注意,dashboard 默认使用 https 提供服务,ingress 默认 backend-protocol 使用 http,这里发布成功的关键是要添加 annotations 参数

  annotations:
    nginx.ingress.kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"

部署:

kubectl apply -f dashboard-ingress.yaml

部署成功后可以通过域名访问:https://k8s.sysin.cn

5. Apache httpd

Apache HTTP Server 项目致力于开发和维护一个用于现代操作系统的开源 HTTP 服务器,包括 UNIX 和 Windows。该项目的目标是提供一个安全、高效和提供与当前 HTTP 同步的 HTTP 服务的可扩展服务器标准。

Apache HTTP 服务器(“httpd”)于 1995 年推出,自 1995 年以来一直是 Internet 上最受欢迎的 Web 服务器。1996 年 4 月。它在 2020 年 2 月庆祝了它作为一个项目的 25 岁生日。

5.1 基本配置

参看 官网文档

LoadModule ssl_module modules/mod_ssl.so

Listen 443

    ServerName www.example.com
    SSLEngine on
    SSLCertificateFile "/path/to/www.example.com.cert"
    SSLCertificateKeyFile "/path/to/www.example.com.key"
    SSLCipherSuite HIGH:!aNULL:!MD5
    #SSLCipherSuite RC4-SHA:AES128-SHA:HIGH:!aNULL:!MD5

5.2 HTTP/2

Apache Module mod_http2 Available in version 2.4.17 and later

两种配置:

HTTP/2 in a VirtualHost context (TLS only)

Protocols h2 http/1.1

Allows HTTP/2 negotiation (h2) via TLS ALPN in a secure . HTTP/2 preamble checking (Direct mode, see H2Direct) is disabled by default for h2.

HTTP/2 in a Server context (TLS and cleartext)

Protocols h2 h2c http/1.1

Allows HTTP/2 negotiation (h2) via TLS ALPN for secure . Allows HTTP/2 cleartext negotiation (h2c) upgrading from an initial HTTP/1.1 connection or via HTTP/2 preamble checking (Direct mode, see H2Direct).

5.3 HSTS

# Load modules (or use the IfModule)
LoadModule headers_module modules/mod_headers.so

LoadModule rewrite_module modules/mod_rewrite.so

Rewrite HTTP connections and redirect them to HTTPS:

# Redirect HTTP connections to HTTPS


RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Now configure the virtual host:


Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

5.4 TLSv1.3

版本要求:

Apache version 2.4.36 or greater. (网上文章传言 2.4.38 是错误的!)

OpenSSL version 1.1.1 or greater.

CentOS 8 和 Ubuntu 20.04 自带软件包满足要求,低版本需要编译安装。

[root@c8 ~]# openssl version
OpenSSL 1.1.1c FIPS  28 May 2019

[root@c8 ~]# dnf list httpd
Installed Packages
httpd.x86_64        2.4.37-21.module_el8.2.0+382+15b0afa8        @AppStream
root@u20:~# openssl version
OpenSSL 1.1.1f  31 Mar 2020

root@u20:~# apt list apache2
Listing... Done
apache2/focal 2.4.41-4ubuntu3 amd64

仅启用 TLS 1.2:

SSLProtocol -all +TLSv1.2

配置项如下所示:


    ServerName www.example.com
    DocumentRoot /var/www/html

    SSLEngine on
    SSLProtocol -all +TLSv1.2
    SSLCertificateFile "/path/to/www.example.com.cert"
    SSLCertificateKeyFile "/path/to/www.example.com.key"

启用 TLS 1.3 和 1.2:

The Apache version 2.4.36 or higher versions support TLS v1.3. You must upgrade Apache packages before enabled TLS 1.3 in SSL settings.

 SSLProtocol -all +TLSv1.2 +TLSv1.3

配置项如下所示:


    ServerName www.example.com
    DocumentRoot /var/www/html

    SSLEngine on
    SSLProtocol -all +TLSv1.2 +TLSv1.3
    SSLCertificateFile "/path/to/www.example.com.cert"
    SSLCertificateKeyFile "/path/to/www.example.com.key"

记得重启 Apache 服务才能生效。

5.5 参考配置

# For CentOS
yum install mod_ssl
mv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.bak

配置文件自动增加 "/etc/httpd/conf.modules.d/00-ssl.conf"

echo '
Listen 443

    Protocols h2 http/1.1
    ServerName sysin.org
    DocumentRoot /var/www/html
    SSLEngine on
    SSLProtocol -all +TLSv1.2 +TLSv1.3
    SSLCertificateFile "/etc/httpd/ssl/sysin.org.pem"
    SSLCertificateKeyFile "/etc/httpd/ssl/sysin.org.key"
    SSLCipherSuite HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

' > /etc/httpd/conf.d/sysin.org.conf

其他 Cipher 参考配置

SSLCipherSuite HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA  #A
SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384  #A (Mozilla Intermediate)

6. Apache Tomcat

Apache Tomcat® 软件是 Jakarta Servlet、Jakarta Server Pages、Jakarta Expression Language、Jakarta WebSocket、Jakarta Annotations 和 Jakarta Authentication 规范的开源实现。这些规范是 Jakarta EE 平台的一部分。Jakarta EE 平台是 Java EE 平台的演变。Tomcat 10 及更高版本实现了作为 Jakarta EE 一部分开发的规范。Tomcat 9 及更早版本实现了作为 Java EE 一部分开发的规范。

Tomcat 不使用 OpenSSL,所以不支持 TLS-FALLBACK-SCSV 特性,在 Tomcat 9 最新版默认配置即可获得 A 得分,开启 HSTS 也是 A 得分。

6.1 基本配置

打开 conf/server.xml 文件可以看到默认的 SSL/TLS HTTP/1.1 和 HTTP/2 配置方法如下:

    
    
        
            
        
    

    
    
        
        
            
        
    

Certificate 参数配置参考

6.2 HTTP/2

版本要求:Tomcat 8.5.0,2016-03-24,开始支持 HTTP/2

配置 HTTP/2:即增加

根据官方文档使用 PEM 格式证书测试失败,这里使用 PFX 格式。

Tomcat 9 强制要求证书别名设置为 tomcat。您需要使用以下 keytool 命令(这里的证书原来别名是 alias,阿里云申请的免费证书默认别名)转换证书别名为 tomcat:

keytool -changealias -keystore my-cert.pfx -alias alias -destalias tomcat

    
    
        
        
            
        
    

    

ciphers 参看:Ciphers,HowTo SSLCiphers

protocols 写法:

The names of the protocols to support when communicating with clients. This should be a list of any combination of the following:

    SSLv2Hello
    SSLv3
    TLSv1
    TLSv1.1
    TLSv1.2
    TLSv1.3
    all

列表中的每个标记都可以以加号(“+”)或减号(“-”)为前缀。加号添加协议,减号将其从当前列表中删除。该列表是从一个空列表开始构建的。

字符 all 是 SSLv2Hello,TLSv1,TLSv1.1,TLSv1.2,TLSv1.3 的别名。

请注意,只有在使用实现 TLSv1.3 的 JVM 时,JSSE 才支持 TLSv1.3。

请注意,对于基于 OpenSSL 的安全连接器,将忽略 SSLv2Hello。如果为基于 OpenSSL 的安全连接器指定了多个协议,它将始终支持 SSLv2Hello。如果指定了单个协议,它将不支持 SSLv2Hello。

请注意,SSLv2 和 SSLv3 本质上是不安全的。

如果未指定,则将使用 all 的默认值。

6.3 HSTS

Response Header 配置

Enabling HSTS (to include maxAgeSeconds = 31536000, includeSubDomains, and preload) requires two modifications of the Tomcat’s conf/web.xml file:

1). 启用 HSTS 支持,查找以下部分(通过搜索 “httpHeaderSecurity” 关键词):


替换为(或者新增):

    
        httpHeaderSecurity
        org.apache.catalina.filters.HttpHeaderSecurityFilter
            
                hstsEnabled
                true
            
            
                hstsMaxAgeSeconds
                31536000
            
            
                hstsIncludeSubDomains
                true
            
            
                hstsPreload
                true
            
        true
    

2). 继续搜索 “httpHeaderSecurity” 关键词,查找如下内容,在 “Built In Filter Mappings” 这一段:


移除注释,如下:

    
        httpHeaderSecurity
        /*
        REQUEST
    

6.4 HTTP redirection

编辑 server.xml,将 HTTP 重定向到 HTTPS,这里分别使用 80 和 443 端口,搜索 “Connector” 关键词,查找到如下部分:

    

修改为:

    

或者修改这里:

    

修改为:

    

7. HAProxy

HAProxy 是一种免费、快速且可靠的反向代理,可为基于 TCP 和 HTTP 的应用程序提供高可用性、负载平衡和代理。它特别适用于流量非常高的网站,并为世界上大部分访问量最大的网站提供支持。多年来,它已成为事实上的标准开源负载均衡器,现在随大多数主流 Linux 发行版一起提供,并且通常默认部署在云平台中。由于它不做广告,我们只知道它在管理员报告时被使用:-)

HAProxy 核心团队并行维护多个版本。从 1.8 版开始,每年都会发布两个主要版本。第一个数字通常表示重大更改(配置格式等),但实际上很少更改。第二个数字表示新功能。两者构成一个分支。这些数字后面会出现一个额外的数字,以指示错误修复版本。

偶数的分支称为 “LTS”(用于 “长期支持”),并且在发布后维护 5 年的区域。在此期间,他们将收到针对发布后发现的错误的修复程序。这些分支针对的是寻求极端稳定性并且不想过于频繁地验证新版本但仍希望收到修复程序的一般用户。

奇数分支仅被称为 “稳定”,它们针对那些喜欢经常升级以从现代功能中受益的高技能用户,并且在出现问题时也能够回滚。这些版本的维护期为 12 到 18 个月。

7.1 SSL cipher

Global 参数中关于 SSL 的配置

以下三个参数是定义 front:

  • ssl-default-bind-ciphers
ssl-default-bind-ciphers  #适用于 TLSv1.2 及以下版本
  • ssl-default-bind-ciphersuites
ssl-default-bind-ciphersuites  #OpenSSL 1.1.1 or later,TLSv1.3

同时需要同时支持 TLSv1.2 及以下版本和 TLSv1.3 两个参数需要同时设置。

  • ssl-default-bind-options

示例:

ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets

以下对应定义 backend server:

  • ssl-default-server-ciphers

适用于 TLSv1.2 及以下版本

  • ssl-default-server-ciphersuites

适用于 OpenSSL 1.1.1 or later,TLSv1.3

  • ssl-default-server-options

参看官方文档:Configuring TLS Settings

参考配置:

global
......
    #ssl-default-bind-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 #for TLSv1.2, Mozilla Intermediate
    ssl-default-bind-ciphers HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA #for TLSv1.2
    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 #for TLSv1.3
    ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
    #ssl-default-bind-options prefer-client-ciphers no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
.....

7.2 HTTP/2

HAProxy 1.8 及以上版本支持 HTTP/2

From the 1.8 announcement:

HAProxy 1.8 now supports HTTP/2 on the client side (in the frontend sections) and can act as a gateway between HTTP/2 clients and your HTTP/1.1 and HTTP/1.0 applications.

HTTP/2 协议已经被迅速采用,HAProxy 1.8 现在在客户端支持 HTTP/2(在前端部分),并且可以充当 HTTP/2 客户端与 HTTP/1.1 和 HTTP/1.0 应用程序之间的网关。

要启用对 HTTP/2 的支持,前端部分的绑定行必须配置为 SSL 端点,alpn 必须宣布 h2,如下:

frontend myapp
  bind :443 ssl crt /path/to/cert.crt alpn h2,http/1.1
  mode http

备注:cert.crt 证书采用 PEM 格式,包含私钥、证书,证书链在一个文件中。

7.3 TLSv1.3

要求:HAProxy 1.8.1 及以上,OpenSSL 1.1.1 及以上。

参数:ssl-default-bind-ciphersuites,参看上述 SSL cipher 部分的描述。

7.4 HSTS

方法如下:

frontend public

......

    http-response add-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

......

Rewriting HTTP responses 方法示例

  • add-header

语法:

http-response add-header []

示例:

http-response add-header X-Via %[env(HOSTNAME)]

  • set-header

相当于覆盖或者替换原有 header

语法:

http-response set-header []

示例:

http-response set-header Server webserver #hide server header

  • del-header

语法:

http-response del-header []

示例:

http-response del-header X-Varnish

  • replace-value

高级替换

语法:

http-response replace-value []

7.5 Redirecting HTTP Requests

重定向 HTTP 请求到 HTTPS,可以参考以下官方示例:

Examples of traffic redirection:

Append a www. prefix in front of all URLs that do not have it:

acl has_www hdr_beg(host) -i www
http-request redirect code 301 location http://www.%[hdr(host)]%[req.uri] unless has_www

Redirect all HTTP traffic to HTTPS when SSL is handled by haproxy:

acl http      ssl_fc,not
http-request redirect scheme https if http

Send redirects for requests for articles without a '/':

acl missing_slash path_reg ^/article/[^/]*$
http-request redirect code 301 prefix / drop-query append-slash if missing_slash

Move the login URL only to HTTPS:

acl http       ssl_fc,not
acl https      ssl_fc
acl u_login    path_beg   /login
acl u_logout   path_beg   /logout
acl up_userid  urlp_len(userid) gt 0
acl cookie_set hdr_sub(cookie) SEEN=1
http-request redirect scheme https if http  u_login
http-request redirect prefix https://%[req.hdr(Host)] set-cookie SEEN=1 if !cookie_set
http-request redirect prefix https://%[req.hdr(Host)] drop-query if u_login !up_userid
http-request redirect scheme http if https !u_login
http-request redirect location / clear-cookie USERID=       if u_logout

7.6 参考配置

Config files and scripts for HAProxy 1.8 with HTTP/2 and dynamic reconfiguration

An 'haproxy.cfg' with:

  • The ability to switch backends dynamically
  • HTTP/2 support in all browsers
  • Logging to systemd
  • The various www vs non-www, HTTP vs HTTPS combinations redirected to a single HTTPS site.
  • A branded 'sorry' page
  • A separate server that handles blogs and marketing content
  • Support for HTML5 Server Sent Events
  • An A+ on the SSL Labs test

See the full docs at fast EV HTTPS verification provider CertSimple.

##https://github.com/certsimple/haproxy-http2-load-balancing-config/blob/master/haproxy.cfg
global
 # Log to systemd's /dev/log compatibility socket
 log /dev/log local0 info

 chroot /var/lib/haproxy
 pidfile /var/run/haproxy.pid
 maxconn 4000
 user haproxy
 group haproxy
 daemon

 # turn on stats unix socket - see http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#3.1-stats%20socket
 stats socket /var/lib/haproxy/stats mode 600 level admin
 stats timeout 2m

 # generated 2020-09-12, Mozilla Guideline v5.6, HAProxy 2.1, OpenSSL 1.1.1d, intermediate configuration
 # https://ssl-config.mozilla.org/#server=haproxy&version=2.1&config=intermediate&openssl=1.1.1d&guideline=5.6
    # intermediate configuration
    ssl-default-bind-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-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
    ssl-default-bind-options prefer-client-ciphers no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
    #ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

    ssl-default-server-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-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
    ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets

    # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
    ssl-dh-param-file /path/to/dhparam

defaults
 mode http

 # Needed for GeoIP
 # Enable insertion of the X-Forwarded-For header to requests sent to servers
 # May be used in sections :defaults frontend listen backend
 # http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#4.2-option%20forwardfor
 option forwardfor

 # See http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#option%20http-server-close
 option http-server-close

 log global
 option httplog
 option dontlognull
 option http-server-close
 option forwardfor except 127.0.0.0/8
 option redispatch
 retries 3
 timeout http-request 10s
 timeout queue 1m
 timeout client 1m
 timeout server 1m

 timeout check 10s
 maxconn 3000

 # From http://stackoverflow.com/questions/21419859/configuring-haproxy-to-work-with-server-sent-events
 # Set the max time to wait for a connection attempt to a server to succeed
 timeout connect 30s
 # handle a client suddenly disappearing from the net
 timeout client-fin 30s
 option http-server-close

 # The 'stats' site, where we see what's up and what's down - uncomment and set a password if you want it!
 # stats enable
 # stats uri /haproxy?stats
 # stats realm Strictly\ Private
 # stats auth someusername:i-am-an-awful-password-and-you-should-change-me

 # Show a custom page during site maintenance (ie, when 'blue' and 'green' are both down)
 errorfile 503 /etc/haproxy/errors/503-mycustom.http

frontend public
 # HTTP/2 - see https://www.haproxy.com/blog/whats-new-haproxy-1-8/
 # h2 is HTTP2 with TLS - see https://http2.github.io/faq/
 # Order matters, so h2 before http1.1
 bind :443 ssl crt /etc/https/cert-and-private-key-and-intermediate-and-dhparam.pem alpn h2,http/1.1

 # Redirect http -> https
 bind :80
 redirect scheme https code 301 if ! {ssl_fc}

 # Redirect www -> example.com
 redirect prefix https://example.com code 301 if {hdr(host) -i www.example.com }

 # HSTS (15768000 seconds = 6 months)
 # HSTS (31536000 seconds = 1 years)
 http-response set-header Strict-Transport-Security max-age=31536000

 # Use the marketing site for marketing URLs
 acl marketing path_beg -i /help /sitemap.xml /BingSiteAuth.xml /about /blog /videos/blog /images/blog /fonts/blog /css/blog /js/blog
 use_backend marketing if marketing

 # Everything else goes to the app servers
 default_backend app
 option httpclose
 option forwardfor

backend marketing
 balance roundrobin
 server static 127.0.0.1:8000 check

backend app
 # From http://blog.haproxy.com/2014/01/17/emulating-activepassing-application-clustering-with-haproxy/
 # See also https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#stick-table
 stick-table type ip size 1m
 stick on dst
 # See https://cloud.digitalocean.com/droplets for these IPs
 server green 10.1.1.1:8000 check
 server blue 10.1.1.2:8000 check backup
 # http://stackoverflow.com/questions/21419859/configuring-haproxy-to-work-with-server-sent-events
 timeout tunnel 10h

8. Varnish with Hitch

笔者写了一篇文章描述了整个配置过程,访问这里查看:Varnish with Hitch HTTP/2 implement on CentOS 8.0

Varnish Cache 是一种 web 应用程序加速器,同时以被用于缓存的 HTTP 反向代理而闻名。Varnish HTTP/2 前端通过 Hitch 代理实现。Hitch 是 Varnish Software 开发的基于 libev 的高性能 SSL/TLS 开源代理软件。

8.1 启动 Varnish 支持 HTTP/2

默认情况下,Varnish 中的 HTTP/2 支持是禁用的,因此必须添加一个特性标志才能启用它。即通过传递 “-p feature=+http2” 作为 Varnish 的启动参数来实现。

您可以通过运行 varnishadm param.show feature 命令来检查是否已启用参数。

# varnishadm param.show feature

feature
        Value is: none (default)

        Enable/Disable various minor features.
           none                       Disable all features.

        Use +/- prefix to enable/disable individual feature:
           short_panic                Short panic message.
           wait_silo                  Wait for persistent silo.
           no_coredump                No coredumps.
           esi_ignore_https           Treat HTTPS as HTTP in
                                      ESI:includes
           esi_disable_xml_check      Don't check of body looks like
                                      XML
           esi_ignore_other_elements  Ignore non-esi XML-elements
           esi_remove_bom             Remove UTF-8 BOM
           https_scheme               Also split https URIs
           http2                      Support HTTP/2 protocol
           http_date_postel           Relax parsing of timestamps in
                                      HTTP headers

启动 Varnish

本例中,Varnish 使用默认配置,事先运行了 Nginx,将 Nginx 默认端口修改为 8080 即可(具体过程略)。

varnishd -a :80 -a localhost:6086,PROXY -p feature=+http2 -f /etc/varnish/default.vcl
#或者
varnishd -a localhost:6086,PROXY -p feature=+http2 -f /etc/varnish/default.vcl

验证 Varnish 已经开启 HTTP/2 支持

varnishadm param.show feature
feature
        Value is: +http2
        Default is: none

        ......

8.2 hitch 参考配置:Ciphers,HTTP/2 和 TLSv1.3

版本要求:

  • Cache 5.0 开始实验性的支持 HTTP/2
  • Varnish 6.0 完整支持 HTTP/2
  • hitch 1.5 版本开始支持 TLS 1.3

示例配置(更多参数参看官方文档):

mv /etc/hitch/hitch.conf /etc/hitch/hitch.conf.bak

echo '
# Run 'man hitch.conf' for a description of all options.

frontend = {
    host = "*"
    port = "443"
}
backend = "[127.0.0.1]:6086"    # 6086 is the default Varnish PROXY port.
workers = 4                     # number of CPU cores

daemon = on

# We strongly recommend you create a separate non-privileged hitch
# user and group
user = "hitch"
group = "hitch"

# Enable to let clients negotiate HTTP/2 with ALPN. (default off)
# Varnish 启动参数必须增加 `-p feature=+http2`,开启 HTTP/2 特性(默认关闭)
alpn-protos = "h2, http/1.1"

# run Varnish as backend over PROXY; varnishd -a :80 -a localhost:6086,PROXY ..
write-proxy-v2 = on             # Write PROXY header

syslog = on
log-level = 1

# Add pem files to this directory
#pem-dir = "/etc/pki/tls/private"

## PEM 文件包含 key、cert 和 chain 的组合,可以支持多个 PEM 文件
## cat example.com.key example.com.crt my-ca-bundle.crt > example.com.pem
pem-file = "/etc/hitch/varnish.pem"
# 定义第二个 PEM 文件
#pem-file = "/etc/hitch/mydomain.pem"
## 官方推荐默认 cipher
ciphers = "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
## Hitch supports TLS (1.0, 1.1, 1.2, 1.3) and SSL 3. By default
tls-protos = TLSv1.2 TLSv1.3
## TCP Fast Open saves up to one full round-trip time (RTT) over the standard three-way connection handshake during a TCP session.
tcp-fastopen = on
' > /etc/hitch/hitch.conf

OCSP staple 相关配置参看 官方文档

以上配置将获得 A 评级,加上下面的 HSTS 即可获得 A+ 评级。

8.3 HSTS

编辑 varnish vcl,如下字段添加:

sub vcl_deliver {
 set resp.http.Strict-Transport-Security = "max-age=31536000; includeSubDomains; preload";
}

你可能感兴趣的:(在 Qualys SSL Labs SSL 测试中获得 A+ 评级的秘技 2021 版)