簡介
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有如下幾個優點:
- 使用多路複用技術,在同一個連線中可以並行處理多個請求。
- 可以壓縮HTTP頭,減少請求的大小。
- 資料傳輸格式是以二進位制進行的,所以傳輸更加有效。
- 伺服器可以向客戶端推送資料,從而讓應用程式可以處理更加複雜的功能。
儘管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 []:flydean@163.com
然後就生成了兩個檔案: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和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_name$request_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/
最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!