介绍
NGINX是一个快速可靠的开源 Web 服务器,它因其低的内存足迹,高可扩展性,易于配置,以及对绝大多数不同的协议的支持而获得了普及。
支持的协议之一是相对较新的HTTP/2,该协议于2015年5月发布,HTTP/2的主要优点是其对内容丰富的网站的高传输速度。
本教程将帮助您设置具有 HTTP/2 支持的快速和安全的 Nginx 服务器。
前提条件
在我们开始之前,我们需要一些东西:
- Ubuntu 16.04 Droplet
- 非 root 用户具有 sudo 特权(查看 初始服务器设置与 Ubuntu 16.04 详细信息.)
- 完全注册的域名. 您可以在 Namecheap 购买一个,或者在 Freenom免费获得一个。
- 确保您的域名已配置为指向您的 Droplet。 查看 本教程 如果您需要帮助
- SSL 证书。 生成自签证书, 从 Let's Encrypt 获得免费的证书,或 [从另一个提供商
如果你有上面列出的所有东西,你已经准备好了。
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)。
此时,我们的服务器已经准备好通过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并对您的服务器进行测试。