天天看點

輕松讓你的nginx伺服器支援HTTP2協定簡介HTTP1.1和HTTP2安裝最新的nginx開啟HTTP2支援添加SSL支援修改加密算法Diffie–Hellman對消息進行加密重定向所有的HTTP請求到HTTPS啟動nginx并測試總結

簡介

nginx是一個高效的web伺服器,因為其獨特的響應處理機制和低記憶體消耗,深得大家的喜愛,并且nginx可和多種協定配合使用,而HTTP2協定又是一個非常優秀的協定,如果将兩者結合起來會産生意想不到的效果,今天我們将會講解如何在nginx中配置HTTP2協定。

HTTP1.1和HTTP2

HTTP的全稱是Hypertext Transfer Protocol,是在1989年World Wide Web發展起來之後出現的标準協定,用來在WWW上傳輸資料。HTTP/1.1是1997年在原始的HTTP協定基礎上進行的補充和優化。

到了2015年,為了适應快速發送的web應用和現代浏覽器的需求,發展出了新的HTTP/2協定,主要在手機浏覽器、延時處理、圖像處理和視訊處理方面進行了優化。

相對于HTTP1.1來說,HTTP2有如下幾個優點:

  1. 使用多路複用技術,在同一個連接配接中可以并行處理多個請求。
  2. 可以壓縮HTTP頭,減少請求的大小。
  3. 資料傳輸格式是以二進制進行的,是以傳輸更加有效。
  4. 伺服器可以向用戶端推送資料,進而讓應用程式可以處理更加複雜的功能。
盡管HTTP2并不要求使用加密,但是對于現代浏覽器來說如Google Chrome 和 Mozilla Firefox預設HTTP2和HTTPS是一起使用的,是以如果你想配置HTTP2的話,還是需要同時配置SSL。

安裝最新的nginx

在寫本文的時候,nginx最新的版本是1.21.1。我們可以從nginx官網上下載下傳對應的編譯好的檔案,直接解壓即可運作。或者可以下載下傳它的源檔案,手動進行編譯安裝。

如果你是在mac環境,可以直接使用brew指令來進行安裝:

brew install nginx      

安裝完畢之後會告訴我們一些有用的資訊:

Docroot is: /usr/local/var/www
The default port has been set in /usr/local/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.
nginx will load all files in /usr/local/etc/nginx/servers/.
To have launchd start nginx now and restart at login:
  brew services start nginx
Or, if you don't want/need a background service you can just run:
  nginx      

這裡就不一一詳細講解了,感興趣的朋友可以自行探索。

開啟HTTP2支援

從上面可以知道,nginx預設的配置檔案是/usr/local/etc/nginx/nginx.conf,打開該檔案可以看到最後一行:

include servers/*;      

是以我們可以在servers中建立一個www.flydean.com.conf的檔案作為今天要開啟HTTP2支援的域名。

預設情況下,nginx監聽的端口是80,如下所示:

listen 80 default_server;
listen [::]:80 default_server;      

為什麼會有兩個listen呢?第一個listen指的是所有的IPv4連接配接,第二個listen指的是IPv6連接配接。

因為HTTP2需要開啟SSL支援,是以我們這裡将其修改為443,并且加上http2支援如下所示:

listen       443 ssl http2;
        server_name  www.flydean.com;      

上面的配置中我們還指定了server_name,這就是要通路的域名位址,這裡我們使用www.flydean.com。

添加SSL支援

要想添加SSL支援就需要添加證書,一種方式是購買或者在網上有一些免費的SSL證書可用,如果隻是在測試環境中的話,還可以生成自簽名證書。

這裡我們介紹一下如何生的自簽名證書。這裡我們使用openssl指令來完成這個工作。

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout selfsigned.key -out selfsigned.crt
Generating a RSA private key      

執行完成上面的指令,會要求你輸入一些證書的資訊如下:

Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:SH
Locality Name (eg, city) []:SH
Organization Name (eg, company) [Internet Widgits Pty Ltd]:flydean
Organizational Unit Name (eg, section) []:flydean
Common Name (e.g. server FQDN or YOUR name) []:127.0.0.1
Email Address []:[email protected]      

然後就生成了兩個檔案:selfsigned.crt和selfsigned.key。

這裡稍微講解一下自簽名證書生成的指令。

openssl是一個非常強大的密鑰生成工具,可以完成絕大多數的密鑰生成工作。

req表示的是這是一個X.509 certificate signing request (CSR)。

-x509表示我們希望生成的是一個自簽名的證書。

-nodes表示我們不需要對生成的密鑰進行密碼加密。

-days 365表示證書的有效期。

-newkey rsa:2048表示使用RSA算法同時生成證書和key,key的長度是2048。

-keyout:指定key的生成路徑。

-out:指定證書的生成路徑。

這裡即使是使用了SSL,為了保證安全,我們還可以使用一項叫做完美的向前保密的技術,這裡需要生成Diffie-Hellman group:

openssl dhparam -out dhparam.pem 2048      

這個指令會需要一些時間,生成之後,我們就可以開始nginx的SSL配置了。

ssl_certificate      ssl/selfsigned.crt;
        ssl_certificate_key  ssl/selfsigned.key;      

修改加密算法

我們知道已經存在很多加密算法,随着密碼學技術的發展,很多算法已經被證明是不安全的。是以這裡我們需要對預設的加密算法進行修改。

預設的算法是:

ssl_ciphers  HIGH:!aNULL:!MD5;      

我們将其修改為:

ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;      

Diffie–Hellman對消息進行加密

雖然我們使用private key配置了用戶端和伺服器端的加密連接配接,在建立連接配接之後,在ServerKeyExchange這一步,雙方還會詢問對資訊的加密方式來用來建構加密通道。

ServerKeyExchange的内容可能包含兩種形式:

  • 如果選擇的是RSA協定,那麼傳遞的就是RSA建構公鑰密碼的參數(E,N)。我們回想一下RSA中建構公鑰的公式:密文=明文^E\ mod\ N密文=明文E mod N, 隻要知道了E和N,那麼就知道了RSA的公鑰,這裡傳遞的就是E,N兩個數字。具體内容可以參考 RSA算法詳解
  • 如果選擇的是Diff-Hellman密鑰交換協定,那麼傳遞的就是密鑰交換的參數,具體内容可以參考 更加安全的密鑰生成方法Diffie-Hellman

這裡我們選擇使用Diffie–Hellman,還記得上一小節,我們建立的Diffie–Hellman檔案嗎?這裡直接使用即可。

預設情況下Nginx使用的是1028-bit DHE (Ephemeral Diffie-Hellman) key,這個比較容易被破解,是以需要使用我們自己生成的檔案。

ssl_dhparam  ssl/dhparam.pem;      

重定向所有的HTTP請求到HTTPS

預設情況下我們通路網站都是HTTP的,是以需要将HTTP請求重定向到HTTPS:

server {
       listen         80;
       listen    [::]:80;
       server_name    www.flydean.com;
       return         301 https://server_namerequest_uri;
}      

啟動nginx并測試

好了,到此為止所有的nginx配置都完成了,我們使用下面的指令測試nginx檔案和啟動:

nginx -t
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
nginx      

要通路網站,還需要配置一下host将 www.flydean.com 指到你的nginx server上。

然後就可以通路www.flydean.com了。

這裡可能會出現一個問題,如果你是自簽名的證書,在chrome預設的安全環境中會認為這個證書是無效的,還需要将該證書加入證書的信任鍊中。

怎麼看出這個網站到底使用的那種協定呢?

打開浏覽器的調試開關,到網絡的tab,點選通路的頁面,可以看到下面的内容:

可以看到版本是HTTP/2并且響應頭帶有X-Firefox-Spdy h2。

總結

好了,你已經可以配置一個完美的HTTPS并且支援HTTP2協定的網站了。恭喜!

本文已收錄于 http://www.flydean.com/01-nginx-http2/

最通俗的解讀,最深刻的幹貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!

歡迎關注我的公衆号:「程式那些事」,懂技術,更懂你!

繼續閱讀