HTTP/2 是超文本传输协议的较新版本,用于在 Web 上将页面从服务器传送到浏览器。HTTP/2 是近二十年来 HTTP 的第一次重大更新:HTTP1.1 早在 1999 年就被引入公众,当时网页的大小要小得多。从那时起,互联网发生了巨大的变化,我们现在面临着 HTTP 1.1 的限制。该协议限制了大多数现代网站的潜在传输速度,因为它在队列中下载页面的一部分——前一部分必须在下一部分开始下载之前完全下载——而一个普通的现代网页会下载数十个单独的 CSS、JavaScript、和图像资产。
HTTP/2 解决了这个问题,因为它带来了一些根本性的变化:
- 所有请求都是并行下载的,而不是在队列中
- HTTP 标头被压缩
- 页面作为二进制文件传输,而不是作为文本文件传输,这样效率更高
- 服务器可以在没有用户请求的情况下“推送”数据,为高延迟用户提高速度
尽管 HTTP/2 不需要加密,但两个最流行的浏览器 Google Chrome 和 Mozilla Firefox 的开发人员表示,出于安全原因,他们将仅支持 HTTP/2 用于 HTTPS 连接。因此,如果您决定设置支持 HTTP/2 的服务器,您还必须使用 HTTPS 保护它们。
本教程将帮助您设置一个支持 HTTP/2 的快速且安全的 Nginx 服务器。
先决条件
在开始之前,您需要准备一些东西:
- 设置的 Ubuntu 20.04 服务器,包括 sudo 非 root 用户和防火墙。
- Nginx 安装在您的服务器上,您可以按照如何在 Ubuntu 20.04 上安装 Nginx 来完成。
- 配置为指向您的服务器的域名。
- 为您的服务器配置的 TLS/SSL 证书。您有几个选择:
- 您可以按照如何在 Ubuntu 20.04 上使用 Let's Encrypt 保护 Nginx 来从Let's Encrypt获得免费证书。
- 您还可以按照如何在 Ubuntu 20.04 中为 Nginx 创建自签名 SSL 证书来生成和配置自签名证书。
- Nginx 配置为将流量从端口重定向80到端口443,这应该包含在前面的先决条件中。
- Nginx 配置为使用 2048 位或更高的 Ephemeral Diffie-Hellman (DHE) 密钥,这也应包含在先前的先决条件中。
步骤 1 — 启用 HTTP/2 支持
如果您按照Nginx 安装教程中的服务器块设置步骤进行操作,则您的域中应该有一个服务器块,并且已正确设置了指令。我们将进行的第一个更改是修改您域的服务器块以使用 HTTP/2。/etc/nginx/sites-available/your_domainserver_name
使用nano或首选编辑器打开您的域的配置文件:
- sudo nano /etc/nginx/sites-enabled/your_domain
在文件中,找到listen与 port 关联的变量443:
/etc/nginx/sites-enabled/your_domain
- ...
- listen [::]:443 ssl ipv6only=on;
- listen 443 ssl;
- ...
第一个用于 IPv6 连接。第二个用于所有 IPv4 连接。我们将为两者启用 HTTP/2。
修改每个listen指令以包括http2:
/etc/nginx/sites-enabled/your_domain
- ...
- listen [::]:443 ssl http2 ipv6only=on;
- listen 443 ssl http2;
- ...
这告诉 Nginx 在支持的浏览器中使用 HTTP/2。
保存配置文件并退出文本编辑器。如果您使用的是,请在出现提示时nano按Ctrl+Xthen,Y然后按 Enter。
每当您对 Nginx 配置文件进行更改时,您都应该使用-t运行 Nginx 内置语法检查命令的标志来检查配置是否存在错误:
- sudo nginx -t
如果语法没有错误,您将收到如下输出:
sudo nginx -t 的输出
- nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
- nginx: configuration file /etc/nginx/nginx.conf test is successful
接下来,您将配置 Nginx 服务器以使用更严格的密码列表来提高服务器的安全性。
步骤 2 — 删除旧的和不安全的密码套件
HTTP/2 有一个应该避免的旧的和不安全的密码的阻止列表。密码套件是描述传输数据应如何加密的加密算法。
您将用于定义密码的方法取决于您为 Nginx 配置 TLS/SSL 证书的方式。
如果您使用 Certbot 获取证书,它还会创建/etc/letsencrypt/options-ssl-nginx.conf包含对 HTTP/2 不够安全的密码的文件。但是,修改此文件将阻止 Certbot 将来应用更新,因此我们只会告诉 Nginx 不要使用此文件,我们将指定我们自己的密码列表。
打开您的域的服务器块配置文件:
- sudo nano /etc/nginx/sites-enabled/your_domain
找到包含该options-ssl-nginx.conf文件的行并通过#在该行的开头添加一个字符来将其注释掉:
/etc/nginx/sites-enabled/your_domain
- # include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot<^>
在该行下方,添加此行以定义允许的密码:
/etc/nginx/sites-enabled/your_domain
- ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
保存文件并退出编辑器。
如果您使用自签名证书或使用第三方证书并根据先决条件对其进行配置,请/etc/nginx/snippets/ssl-params.conf在文本编辑器中打开该文件:
- sudo nano /etc/nginx/snippets/ssl-params.conf
找到以下行:
/etc/nginx/snippets/ssl-params.conf
- ...
- 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;
- ...
修改它以使用以下密码列表:
/etc/nginx/snippets/ssl-params.conf
- ...
- ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
保存文件并退出编辑器。
再次使用以下nginx -t命令检查配置是否存在语法错误:
- sudo nginx -t
如果您遇到任何错误,请解决它们并再次测试。
一旦您的配置通过语法检查,请使用以下systemctl命令重新启动 Nginx :
- sudo systemctl reload nginx.service
重新启动服务器后,让我们验证它是否有效。
步骤 3 — 验证 HTTP/2 是否已启用
让我们确保服务器正在运行并使用 HTTP/2。
使用该curl命令向您的站点发出请求并查看标头:
- curl -I -L --http2 https://your_domain
您将收到如下输出:
- HTTP/2 200
- server: nginx/1.18.0 (Ubuntu)
- date: Wed, 10 Nov 2021 17:53:10 GMT
- content-type: text/html
- content-length: 612
- last-modified: Tue, 09 Nov 2021 23:18:37 GMT
- etag: "618b01cd-264"
- accept-ranges: bytes
您还可以验证 HTTP/2 是否在 Google Chrome 中使用。打开 Chrome 并导航到. 打开 Chrome 开发人员工具(查看->开发人员->开发人员工具)并重新加载页面(查看->重新加载此页面)。导航到Network选项卡,右键单击以Name开头的表行,然后从弹出菜单中选择Protocol选项。https://your_domain
您将拥有一个包含(代表 HTTP/2)的新协议列h2,表明 HTTP/2 正在运行。
此时,您已准备好通过 HTTP/2 协议提供内容。让我们通过启用 HSTS 来提高安全性和性能。
步骤 4 - 启用 HTTP 严格传输安全 (HSTS)
即使您的 HTTP 请求重定向到 HTTPS,您也可以启用HTTP 严格传输安全(HSTS) 以避免必须执行这些重定向。如果浏览器找到 HSTS 标头,它不会在给定的时间段内再次尝试通过常规 HTTP 连接到服务器。无论如何,它将仅使用加密的 HTTPS 连接来交换数据。此标头还保护我们免受协议降级攻击。
再次打开您的域的服务器块配置文件:
- sudo nano /etc/nginx/your_domain
将此行添加到包含 SSL 密码的文件的同一块以启用 HSTS:
/etc/nginx/your_domain
- server {
- ...
- ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
- add_header Strict-Transport-Security "max-age=15768000" always;
- }
- ...
在max-age以秒为单位设定。该值15768000相当于 6 个月。
默认情况下,此标头不会添加到子域请求中。如果您有子域并希望 HSTS 应用于所有子域,则应includeSubDomains在行尾添加变量,如下所示:
/etc/nginx/your_domain
- add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
保存文件,然后退出编辑器。
再次检查配置是否有语法错误:
- sudo nginx -t
最后,重新启动 Nginx 服务器以应用更改。
sudo systemctl reload nginx.service
结论
您的 Nginx 服务器现在正在为 HTTP/2 页面提供服务。如果您想测试 SSL 连接的强度,请访问Qualys SSL 实验室并针对您的服务器运行测试。如果一切配置正确,您应该获得 A+ 标记以确保安全。