如何在 Ubuntu 18.04 上设置支持 HTTP/2 的 Nginx

此教程的早期版本是由 Sergey Zhukaev 撰写的(https://www.digitalocean.com/community/users/lomand)。

介绍

Nginx是一个快速可靠的开源 Web 服务器,由于其低的内存足迹,高可扩展性,易于配置,并支持各种各样的协议而获得了其普及。

HTTP/2是HTTP/2近20年来首个重大更新:HTTP1.1在1999年被引入公众,当时网页通常只是一个单一的HTML文件,内置CSS风格表。互联网从那时起发生了巨大的变化,现在我们面临着HTTP 1.1的局限性 - 该协议限制了大多数现代网站的潜在传输速度,因为它在排列中下载页面的部分(前一部分必须在下载下一个部分开始之前完全下载),平均现代网页需要大约100个下载请求(每个请求都是图像, js文件,css文件等)。

HTTP/2 解决了这个问题,因为它带来了一些基本的变化:

  • 所有请求都是并行下载的,而不是排队
  • HTTP 标题被压缩
  • 页面以二进制形式转移,而不是作为文本文件,这更有效
  • 服务器可以数据,即使没有用户的请求,从而提高了高延迟用户的速度

尽管HTTP/2不需要加密,但两款最受欢迎的浏览器Google Chrome和Mozilla Firefox的开发者表示,出于安全原因,他们只会支持HTTP/2用于HTTPS连接,因此,如果您决定设置支持HTTP/2的服务器,您还必须使用HTTPS保护它们。

本教程将帮助您设置具有 HTTP/2 支持的快速和安全的 Nginx 服务器。

前提条件

在我们开始之前,我们需要一些东西:

步骤 1 – 启用 HTTP/2 支持

如果你遵循了 Nginx 安装教程中的 [服务器块设置步骤](https://andsky.com/tech/tutorials/how-to-install-nginx-on-ubuntu-18-04#step-5-setting-up-server-blocks-(recommended),那么你应该在 /etc/nginx/sites-available/your_domain 上为你的域设置服务器块,并且已经适当设置了 server_name 指令。

打开您的域的配置文件:

1sudo nano /etc/nginx/sites-available/your_domain

在文件中,找到与端口443相关的倾听变量:

1[label /etc/nginx/sites-available/your_domain]
2...
3    listen [::]:443 ssl ipv6only=on; 
4    listen 443 ssl; 
5...

第一个是用于IPv6连接,第二个是用于所有IPv4连接,我们将为两者启用HTTP/2。

修改每个倾听指令以包括http2:

1[label /etc/nginx/sites-available/your_domain]
2...
3    listen [::]:443 ssl http2 ipv6only=on; 
4    listen 443 ssl http2; 
5...

这告诉 Nginx在支持的浏览器中使用 HTTP/2。

保存配置文件并退出文本编辑器。

每当你对 Nginx 配置文件进行更改时,你应该检查配置中的语法错误,如下:

1sudo nginx -t

如果语法没有错误,您将看到以下输出:

1[label Output of sudo nginx -t]
2nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
3nginx: configuration file /etc/nginx/nginx.conf test is successful

接下来,我们将配置我们的服务器以使用更具限制性的加密列表。

步骤 2 — 删除旧和不安全的Cipher套房

HTTP/2 有一个旧的和不安全的加密的黑名单(LINK0),所以我们必须避免它们。

您将使用的定义加密方法取决于您如何为 Nginx 配置 TLS/SSL 证书。

如果您使用 Certbot 获取证书,它还创建了 /etc/letsencrypt/options-ssl-nginx.conf 文件,其中包含对 HTTP/2 不够强大的加密文件。

打开您的域名的服务器封锁配置文件:

1sudo nano /etc/nginx/sites-available/your_domain

查找包含options-ssl-nginx.conf文件的行,并评论它:

1[label /etc/nginx/sites-available/your_domain]
2
3    # include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot

在该行下方,添加此行来定义允许的数字:

1[label /etc/nginx/sites-available/your_domain]
2
3ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

保存文件并离开编辑器。

如果您使用了自签证书或使用了第三方证书并根据前提配置,请在文本编辑器中打开文件 `/etc/nginx/snippets/ssl-params.conf:

1sudo nano /etc/nginx/snippets/ssl-params.conf

查找下列线:

1[label /etc/nginx/snippets/ssl-params.conf]
2...
3ssl_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;
4...

修改它,看起来像这样:

1[label /etc/nginx/snippets/ssl-params.conf]
2
3...
4ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

保存文件并离开编辑器。

再次检查语法错误的配置:

1sudo nginx -t

如果你看到任何错误,解决它们,并再次测试。

一旦没有出现语法错误,请重新启动 Nginx:

1sudo systemctl reload nginx

当服务器重新启动时,让我们检查它是否工作。

步骤 3 — 验证 HTTP/2 已启用

让我们确保服务器运行并使用 HTTP/2。

使用弯曲命令向您的网站提出请求并查看标题:

1curl -I -L https://your_domain

您将看到以下输出:

 1[secondary_label Output]
 2HTTP/1.1 301 Moved Permanently
 3Server: nginx/1.14.0 (Ubuntu)
 4Date: Fri, 06 Jul 2018 19:07:12 GMT
 5Content-Type: text/html
 6Content-Length: 194
 7Connection: keep-alive
 8Location: https://your_domain/
 9
10HTTP/2 200
11server: nginx/1.14.0 (Ubuntu)
12date: Fri, 06 Jul 2018 19:07:12 GMT
13content-type: text/html
14content-length: 16
15last-modified: Fri, 06 Jul 2018 16:55:37 GMT
16etag: "5b3f9f09-10"
17accept-ranges: bytes

您还可以检查HTTP/2是否在Google Chrome中使用。打开Chrome并导航至http://your_domain。打开Chrome Developer Tools(View -> Developer -> Developer Tools)并重新加载页面(View -> Reload This Page)。

您将在新的 Protocol列中看到h2(即HTTP/2),表示HTTP/2正在工作。

Chrome Developer Tools HTTP/2 check

此时,您已准备好通过 HTTP/2 协议提供内容,通过启用 HSTS 来提高安全性和性能。

步骤 4 – 启用 HTTP 严格运输安全(HSTS)

即使您的 HTTP 请求重定向到 HTTPS,您可以启用 _HTTP 严格运输安全(HSTS),以避免需要进行这些重定向。如果浏览器找到 HSTS 标题,它不会尝试通过常规 HTTP 再次连接到服务器一段时间。

在您的编辑器中打开 Nginx 配置文件:

1sudo nano /etc/nginx/nginx.conf

将此行添加到文件中以启用 HSTS:

 1[label /etc/nginx/nginx.conf]
 2http {
 3...
 4    ##
 5    # Virtual Host Configs
 6    ##
 7
 8    include /etc/nginx/conf.d/*.conf;
 9    include /etc/nginx/sites-enabled/*;
10    add_header Strict-Transport-Security "max-age=15768000" always;
11}
12...

最大年龄为秒数,值15768000等于6个月。

默认情况下,此标题不会被添加到子域请求中. 如果您有子域,并且希望 HSTS 适用于所有子域,则应在行末尾添加包括SubDomains变量,如下:

1[label /etc/nginx/nginx.conf]
2add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;

保存文件,然后离开编辑器。

再次检查语法错误的配置:

1sudo nginx -t

最后,重新启动 Nginx 服务器以应用更改。

1sudo systemctl reload nginx

结论

您的 Nginx 服务器现在正在服务 HTTP/2 页面. 如果您想测试您的 SSL 连接的强度,请访问 Qualys SSL Lab并对您的服务器进行测试。

Published At
Categories with 技术
comments powered by Disqus