簡介
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 []:[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/最通俗的解讀,最深刻的幹貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!
歡迎關注我的公衆号:「程式那些事」,懂技術,更懂你!