本教程的先前版本由Sergey Zhukaev编写 。
介绍
Nginx是一个快速可靠的开源Web服务器。 由于其低内存占用,高可扩展性,易于配置以及对各种协议的支持,它获得了普及。
HTTP / 2是超文本传输协议的新版本,它在Web上用于将页面从服务器传递到浏览器。 HTTP / 2是近二十年来HTTP的第一次重大更新:1999年,当网页通常只是一个带有内联CSS样式表的HTML文件时,HTTP1.1被引入公众。 互联网从那时起发生了翻天覆地的变化,现在我们面临着HTTP 1.1的限制 - 协议限制了大多数现代网站的潜在传输速度,因为它将部分页面下载到队列中(前一部分必须在下载之前完全下载)下一部分开始),平均现代网页需要下载大约100个请求(每个请求是图片,js文件,css文件等)。
HTTP / 2解决了这个问题,因为它带来了一些根本性的变化:
- 所有请求都是并行下载的,而不是队列中的
- HTTP标头已压缩
- 页面传输为二进制文件,而不是文本文件,这样更有效
- 即使没有用户的请求,服务器也可以“推送”数据,从而提高具有高延迟的用户的速度
尽管HTTP / 2不需要加密,但两个最流行的浏览器谷歌Chrome和Mozilla Firefox的开发人员表示,出于安全考虑,他们仅支持HTTPS连接的HTTP / 2。 因此,如果您决定设置具有HTTP / 2支持的服务器,则还必须使用HTTPS保护它们。
本教程将帮助您设置具有HTTP / 2支持的快速安全的Nginx服务器。
先决条件
在我们开始之前,我们需要一些东西:
- 一个Ubuntu 18.04服务器按照Ubuntu 18.04初始服务器设置指南设置 ,包括一个sudo非root用户和防火墙。
- Nginx安装在您的服务器上,您可以按照如何在Ubuntu 18.04上安装Nginx来完成 。
- 配置为指向您的服务器的域名。 您可以在Namecheap上购买一个或在Freenom上免费获得一个。 您可以按照如何使用DigitalOcean设置主机名教程了解如何将域指向DigitalOcean Droplet。
- 为您的服务器配置的TLS / SSL证书。 你有三个选择:
- 你可以通过Ubuntu 18.04上的如何使用Let的加密来保护Nginx,从Let's Encrypt获得免费证书。
- 您还可以按照如何在Ubuntu 18.04中为Nginx创建自签名SSL证书来生成和配置自签名证书。
- 您可以从另一个提供商处购买一个,并按照如何在Ubuntu 18.04中为Nginx创建自签名SSL证书的第2步到6配置Nginx以使用它。
- Nginx配置为将流量从端口
80
重定向到端口443
,这应该由先前的先决条件覆盖。 - Nginx配置为使用2048位或更高的Ephemeral Diffie-Hellman(DHE)密钥,这也应该包含在之前的先决条件中。
第1步 - 启用HTTP / 2支持
如果您遵循Nginx安装教程中的服务器块设置步骤 ,则应在/etc/nginx/sites-available/ your_domain
为您的域设置服务器块,并且已正确设置server_name
指令。 我们将做的第一个更改是修改域的服务器块以使用HTTP / 2。
打开您的域的配置文件:
sudo nano /etc/nginx/sites-available/your_domain
在该文件中,找到与端口443
关联的listen
变量:
...
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
...
第一个用于IPv6连接。 第二个用于所有IPv4连接。 我们将为两者启用HTTP / 2。
修改每个listen
指令以包含http2
:
...
listen [::]:443 ssl http2 ipv6only=on;
listen 443 ssl http2;
...
这告诉Nginx在支持的浏览器中使用HTTP / 2。
保存配置文件并编辑文本编辑器。
每当您对Nginx配置文件进行更改时,都应检查配置是否存在语法错误,如下所示:
sudo nginx -t
如果语法没有错误,您将看到以下输出:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
接下来,我们将配置我们的服务器以使用更严格的密码列表。
第2步 - 删除旧的和不安全的密码套件
HTTP / 2有一个旧的和不安全的密码的黑名单 ,所以我们必须避免它们。 密码套件是加密算法,描述了如何加密传输的数据。
您将用于定义密码的方法取决于您为Nginx配置TLS / SSL证书的方式。
如果您使用Certbot获取证书,它还会创建文件/etc/letsencrypt/options-ssl-nginx.conf
,其中包含对HTTP / 2不够强大的密码。 不幸的是,修改此文件将阻止Certbot将来应用更新,因此我们只是告诉Nginx不要使用此文件,我们将指定我们自己的密码列表。
打开域的服务器块配置文件:
sudo nano /etc/nginx/sites-available/your_domain
找到包含options-ssl-nginx.conf
文件的行并将其注释掉:
# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot<^>
在该行下方,添加此行以定义允许的密码:
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
保存文件并退出编辑器。
如果您使用自签名证书或使用来自第三方的证书并根据先决条件对其进行配置, /etc/nginx/snippets/ssl-params.conf
在文本编辑器中打开文件/etc/nginx/snippets/ssl-params.conf
:
sudo nano /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;
...
修改它,使它看起来像这样:
...
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
保存文件并退出编辑器。
再次检查配置是否存在语法错误:
sudo nginx -t
如果您发现任何错误,请解决它们并再次测试。
一旦看到没有语法错误,请重新启动Nginx:
sudo systemctl reload nginx
重新启动服务器后,让我们验证它是否正常工作。
第3步 - 验证HTTP / 2是否已启用
让我们确保服务器正在运行并使用HTTP / 2。
使用curl
命令向您的站点发出请求并查看标题:
curl -I -L https://your_domain
您将看到以下输出:
OutputHTTP/1.1 301 Moved Permanently
Server: nginx/1.14.0 (Ubuntu)
Date: Fri, 06 Jul 2018 19:07:12 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://your_domain/
HTTP/2 200
server: nginx/1.14.0 (Ubuntu)
date: Fri, 06 Jul 2018 19:07:12 GMT
content-type: text/html
content-length: 16
last-modified: Fri, 06 Jul 2018 16:55:37 GMT
etag: "5b3f9f09-10"
accept-ranges: bytes
您还可以验证Google Chrome中是否正在使用HTTP / 2。 打开Chrome并导航至http:// your_domain
。 打开Chrome开发者工具( 查看 - > 开发人员 - > 开发人员工具 )并重新加载页面( 查看 - > 重新加载此页面 )。 导航到“ 网络”选项卡,右键单击以“ 名称”开头的表标题行,然后从弹出菜单中选择“ 协议”选项。
您将在新的Protocol列中看到h2
(代表HTTP / 2),表明HTTP / 2正在运行。
此时,您已准备好通过HTTP / 2协议提供内容。 让我们通过启用HSTS来提高安全性和性能。
第4步 - 启用HTTP严格传输安全性(HSTS)
即使您的HTTP请求重定向到HTTPS,您也可以启用HTTP严格传输安全性 (HSTS)以避免必须执行这些重定向。 如果浏览器找到HSTS标头,它将不会尝试在给定时间段内通过常规HTTP再次连接到服务器。 无论如何,它只使用加密的HTTPS连接交换数据。 此标头还可以保护我们免受协议降级攻击 。
在编辑器中打开Nginx配置文件:
sudo nano /etc/nginx/nginx.conf
将此行添加到文件以启用HSTS:
http {
...
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
add_header Strict-Transport-Security "max-age=15768000" always;
}
...
max-age
以秒为单位设置。 值15768000
相当于6个月。
默认情况下,此标头不会添加到子域请求中。 如果您有子域并希望HSTS应用于所有子域,则应在行尾添加includeSubDomains
变量,如下所示:
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
保存文件,然后退出编辑器。
再次检查配置是否存在语法错误:
sudo nginx -t
最后,重新启动Nginx服务器以应用更改。
sudo systemctl reload nginx
结论
您的Nginx服务器现在提供HTTP / 2页面。 如果您想测试SSL连接的强度,请访问Qualys SSL Lab并对您的服务器运行测试。 如果一切配置正确,您应该获得安全性的A +标记。