在|在 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 |
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- |
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- |
- 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
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 Yearwhen 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 是可选参数,只有当你申请将自己的域名加入到浏览器内置列表的时候才需要使用到它。
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
编辑 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.
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.2.1 IIS 获得 A 级别
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.
测试环境:IIS 10 on Windows Server 2019
执行 ps 脚本 或者使用 IIS Crypto,将获得 A,这里以 IIS Crypto 为例:
IIS Crypto:点击 “Best Pratices”,Server Protocols 只勾选 TLS 1.2,Apply 并重启生效。
文章图片
仅启用 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
文章图片
文章图片
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")。
文章图片
在 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 {
listen443 ssl;
server_namewww.example.com;
ssl_certificatewww.example.com.crt;
ssl_certificate_key www.example.com.key;
ssl_protocolsTLSv1 TLSv1.1 TLSv1.2;
ssl_ciphersHIGH:!aNULL:!MD5;
...
}
证书文件使用 PEM 格式。更多配置,这篇文章可以参考:Strong SSL Security on nginx
证书文件使用相对路径时,证书文件要放在主配置文件相同目录下(默认 /etc/nginx)。
3.2 TLSv1.3
版本支持如下:
- The
TLSv1.1
andTLSv1.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.
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 {
#listen443 ssl;
listen443 ssl http2;
# HTTP/2 Enable
listen[::]:443 ssl http2;
# IPv6
server_namewww.sysin.org;
ssl_certificatewww.sysin.org.crt;
ssl_certificate_key www.sysin.org.key;
ssl_protocolsTLSv1.2 TLSv1.3;
# Requires nginx >= 1.13.0 else use TLSv1.2
ssl_ciphersHIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA;
add_header Strict-Transport-Security "max-age=31536000;
includeSubdomains;
preload" always;
...
}#ssl_protocolsTLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
#ssl_ciphersHIGH:!aNULL:!MD5;
#B
#ssl_ciphersHIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA;
#A
#ssl_ciphersALL:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4;
#B
#ssl_ciphersECDHE-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.soListen 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.soLoadModule 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 FIPS28 May 2019[root@c8 ~]# dnf list httpd
Installed Packages
httpd.x86_642.4.37-21.module_el8.2.0+382+15b0afa8@AppStream
root@u20:~# openssl version
OpenSSL 1.1.1f31 Mar 2020root@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/htmlSSLEngine 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/htmlSSLEngine 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
hstsEnabledtrue
hstsMaxAgeSeconds31536000
hstsIncludeSubDomainstrue
hstsPreloadtrue
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
- ssl-default-server-ciphersuites
- ssl-default-server-options
参考配置:
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
语法:
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 httpssl_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 httpssl_fc,not
acl httpsssl_fc
acl u_loginpath_beg/login
acl u_logoutpath_beg/logout
acl up_useridurlp_len(userid) gt 0
acl cookie_set hdr_sub(cookie) SEEN=1
http-request redirect scheme https if httpu_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
##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-ticketsssl-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/dhparamdefaults
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.httpfrontend 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 forwardforbackend marketing
balance roundrobin
server static 127.0.0.1:8000 checkbackend 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 featurefeature
Value is: none (default)Enable/Disable various minor features.
noneDisable all features.Use +/- prefix to enable/disable individual feature:
short_panicShort panic message.
wait_siloWait for persistent silo.
no_coredumpNo coredumps.
esi_ignore_httpsTreat HTTPS as HTTP in
ESI:includes
esi_disable_xml_checkDon't check of body looks like
XML
esi_ignore_other_elementsIgnore non-esi XML-elements
esi_remove_bomRemove UTF-8 BOM
https_schemeAlso split https URIs
http2Support HTTP/2 protocol
http_date_postelRelax 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.bakecho '
# 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 coresdaemon = 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 headersyslog = 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
【在|在 Qualys SSL Labs SSL 测试中获得 A+ 评级的秘技 2021 版】编辑 varnish vcl,如下字段添加:
sub vcl_deliver {
set resp.http.Strict-Transport-Security = "max-age=31536000;
includeSubDomains;
preload";
}