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

介绍

NGINX是一个快速可靠的开源 Web 服务器,它因其低的内存足迹,高可扩展性,易于配置,以及对绝大多数不同的协议的支持而获得了普及。

支持的协议之一是相对较新的HTTP/2,该协议于2015年5月发布,HTTP/2的主要优点是其对内容丰富的网站的高传输速度。

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

前提条件

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

如果你有上面列出的所有东西,你已经准备好了。

HTTP 1.1 和 HTTP/2 的区别

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保护它们。

步骤1:安装最新版本的 Nginx

在 Nginx 1.9.5 中引入了 HTTP/2 协议的支持。幸运的是,Ubuntu 16.04 中的默认存储库包含比这更高的版本,所以我们不必添加第三方存储库。

首先,更新 apt 包装系统中可用的包装列表:

1sudo apt-get update

然后安装 Nginx:

1sudo apt-get install nginx

安装过程结束后,您可以通过键入检查 Nginx 的版本:

1sudo nginx -v

输出应该与以下相似:

1[label Ouput of sudo nginx -v]
2nginx version: nginx/1.10.0 (Ubuntu)

在接下来的几个步骤中,我们将修改 Nginx 配置文件. 每个步骤都将更改 Nginx 配置选项. 我们将沿途测试配置文件的语法. 最后,我们将验证 Nginx 是否支持 HTTP/2 并进行一些更改以优化性能。

步骤 2 – 更改倾听端口并启用 HTTP/2

我们要做的第一件事是将听力端口从80更改为443

打开配置文件:

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

默认情况下, Nginx 会听到端口 80,这是标准的 HTTP 端口:

1[label /etc/nginx/sites-available/default]
2listen 80 default_server;
3listen [::]:80 default_server;

正如你所看到的,我们有两种不同的倾听变量,第一种适用于所有IPv4连接,第二种适用于IPv6连接。

更改倾听端口为443,该端口由 HTTPS 协议使用:

1[label /etc/nginx/sites-available/default]
2listen 443 ssl http2 default_server;
3listen [::]:443 ssl http2 default_server;

请注意,除了ssl,我们还添加了http2,这个变量告诉 Nginx在支持的浏览器中使用HTTP/2。

步骤 3 – 更改服务器名称

我们使用server_name条目来指定应该与配置文件关联的域名,在配置文件中找到server_name条目。

默认情况下,server_name设置为_ (undercore),这意味着配置文件负责所有传入的请求。

1[label /etc/nginx/sites-available/default]
2server_name example.com;

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

每当你对 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

步骤 4 – 添加 SSL 证书

接下来,您需要配置 Nginx 来使用您的 SSL 证书. 如果您不知道什么是 SSL 证书或目前没有任何证书,请遵循本文前提部分的教程之一。

创建一个目录来存储您的 SSL 证书在 Nginx 配置目录中:

1sudo mkdir /etc/nginx/ssl

将您的证书和私钥复制到这个位置,我们还将重命名文件,以显示它们与哪个域相关联。在未来,当您有多个域与该服务器相关联时,这将非常有用。

1sudo cp /path/to/your/certificate.crt /etc/nginx/ssl/example.com.crt
2sudo cp /path/to/your/private.key /etc/nginx/ssl/example.com.key

现在,让我们再次打开我们的配置文件,并配置SSL。

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

服务器块内的新行上,定义您的证书的位置:

1[label /etc/nginx/sites-available/default]
2ssl_certificate /etc/nginx/ssl/example.com.crt;
3ssl_certificate_key /etc/nginx/ssl/example.com.key;

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

步骤5 - 避免旧的Cipher套房

HTTP/2 包含一大堆旧的和不安全的加密,所以我们必须避免它们,加密套件是一组加密算法,描述了如何加密传输数据。

我们将使用一套非常流行的加密器,其安全性被互联网巨头(如CloudFlare)批准,它不允许使用MD5加密(自1996年以来被称为不安全,但尽管如此,其使用至今仍然很普遍)。

打开以下配置文件:

1sudo nano /etc/nginx/nginx.conf

将此行添加到 ssl_prefer_server_ciphers 上;

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

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

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

1sudo nginx -t

步骤6:提高关键交换的安全性

建立安全连接的第一步是服务器和客户端之间的私钥交换,问题在于,到目前为止,它们之间的连接没有加密,这意味着数据的传输可以被任何第三方看到,这就是为什么我们需要Diffie–Hellman–Merkle算法。

默认情况下, Nginx 使用 1028 位 DHE (Ephemeral Diffie-Hellman) 密钥,这是相对容易解密的。

要做到这一点,请发出以下命令:

1sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

<$>[注] 请记住,我们应该在与我们的SSL证书相同的文件夹中生成DH参数。 在本教程中,证书位于 /etc/nginx/ssl/。原因在于 Nginx 始终在证书文件夹中寻找用户提供的DHE密钥,并使用它如果存在。

文件路径之后的变量(在我们的情况下是「2048」)指定了密钥的长度. 具有 2048 位长的密钥是足够安全的和 Mozilla 基金会推荐,但如果你正在寻找更多的加密,你可以将其更改为「4096」。

生成过程将需要大约5分钟。

一旦完成,请重新打开默认的 Nginx 配置文件:

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

服务器块内的新行上,定义您自定义的 DHE 密钥的位置:

1[label /etc/nginx/sites-available/default]
2ssl_dhparam  /etc/nginx/ssl/dhparam.pem;

步骤 7 – 重定向所有 HTTP 请求到 HTTPS

由于我们对仅通过 HTTPS 提供内容感兴趣,所以我们应该告诉 Nginx 如果服务器收到 HTTP 请求,它应该怎么做。

在我们的文件底部,我们将创建一个新的服务器块来重定向所有HTTP请求到HTTPS(请确保用您的实际域名更换服务器名称):

1[label /etc/nginx/sites-available/default]
2server {
3       listen 80;
4       listen    [::]:80;
5       server_name example.com;
6       return 301 https://$server_name$request_uri;
7}

保存文件,然后退出配置文件。

检查语法错误的配置:

1sudo nginx -t

步骤 8 – 重新加载 Nginx

因为我们在每次更改时检查了语法错误,您应该准备重新启动 Nginx 并测试您的更改。

要总结一下,忽略了评论的行,您的配置文件现在应该看起来像这样:

 1[label /etc/nginx/sites-available/default]
 2server {
 3        listen 443 ssl http2 default_server;
 4        listen [::]:443 ssl http2 default_server;
 5
 6        root /var/www/html;
 7
 8        index index.html index.htm index.nginx-debian.html;
 9
10        server_name example.com;
11
12        location / {
13                try_files $uri $uri/ =404;
14        }
15
16        ssl_certificate /etc/nginx/ssl/example.com.crt;
17        ssl_certificate_key /etc/nginx/ssl/example.com.key;
18        ssl_dhparam /etc/nginx/ssl/dhparam.pem;
19}
20
21server {
22       listen 80;
23       listen    [::]:80;
24       server_name example.com;
25       return 301 https://$server_name$request_uri;
26}

要执行这些更改,请重新启动 Nginx 服务器。

1sudo systemctl restart nginx

步骤9:检查变更

打开您的网页浏览器并导航到您的域名(代替example.com以您的实际域名):

1example.com

现在,让我们检查一下 HTTP/2 是否正在工作:打开 Chrome 开发工具(View -> Developer Tools)并重新加载页面(View -> Reload This Page)。

现在,您应该在为您的网站提供HTTP/2内容的新列中看到h2(即HTTP/2)。

Chrome Developer Tools HTTP/2 check

此时,我们的服务器已经准备好通过HTTP/2协议提供内容,但我们仍然需要做一些事情来准备服务器用于生产。

步骤 10 – 优化 Nginx 以获得最佳性能

在此步骤中,我们将调整主要的 Nginx 配置文件,以获得最佳的性能和安全性。

首先,让我们打开nginx.conf,在控制台中键入以下内容:

1sudo nano /etc/nginx/nginx.conf

允许连接凭证缓存

与 HTTP 相比,HTTPS 需要较长的时间来建立服务器和用户之间的初始连接。 为了最大限度地减少页面加载速度的差异,我们将启用连接凭证的缓存。

要启用会话缓存,请在你的nginx.conf文件的http块的末尾添加这些行:

1[label /etc/nginx/nginx.conf]
2ssl_session_cache shared:SSL:5m;
3ssl_session_timeout 1h;

「ssl_session_cache」指定将包含会话信息的缓存大小,其中1 MB可以存储大约4000个会话的信息,默认值为5 MB对大多数用户来说是足够的,但如果你期望真正的大量流量,你可以相应地增加这个值。

ssl_session_timeout 限制了特定会话存储在缓存中的时间. 此值不应该太大(超过一个小时),但设置值太低也毫无意义。

HTTP 严格运输安全(HSTS)

虽然我们已经在我们的 Nginx 配置文件中将所有常规 HTTP 请求重定向到 HTTPS,但我们还应该启用 HTTP 严格运输安全,以避免首先进行这些重定向。

如果浏览器找到一个HSTS标题,它不会尝试通过正常的HTTP再次连接到服务器在给定的时间段. 无论什么,它只会使用加密的HTTPS连接来交换数据。

在「nginx.conf」中添加此行:

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

max-age是以秒数设置的。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 restart nginx

结论

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

Published At
Categories with 技术
comments powered by Disqus