Nginx上部署HTTPS + HTTP2

  Nginx上部署HTTPS依賴OpenSSL庫和包含文件,即須先安裝好libssl-dev(或者OpenSSL),且ln -s /usr/lib/x86_64-linux-gnu/libssl.so  /usr/lib/,而後在編譯配置Nginx時要指定--with-http_ssl_module和--with-http_v2_module。另外,若要在本地運行openssl命令,要安裝OpenSSL包,本人用的OpenSSL-1.0.2g。注:本文采用Ubuntu 16.04上的操做實例html

  下圖展現了數字證書(HTTPS中使用的由CA簽名的公鑰證書)的簽名和驗證原理:linux

 

 

 

  • TLS保障信息傳輸安全:對於每一次新的對話(鏈接握手階段。這裏講的對話不是HTTP中涉及的應用層對話,而是TLS對話),客戶端和服務端都會協商一個對話密鑰和對稱加密算法(瞭解更多可參考「加密套件」「四次握手」相關內容)用來加解密信息,這樣就避免非對稱加解密耗時過長,運算速度更快;而Public/Private密鑰對只用於"pre-master key"的加解密。特別地,在鏈接斷開後,舊對話的恢復(兩種實現方法:session ID和session ticket)不屬於創建新的對話,無需協商一個新的對話密鑰和對稱加密算法。

 

  • HTTP2:HTTP2 基於SPDY設計,支持HTTPS。但HTTP2與SPDY不一樣的是,不強制使用 HTTPS,但目前尚未瀏覽器支持;HTTP2 消息頭的壓縮算法採用 HPACK ,而非 SPDY 採用的 DELEFT。HTTP2基本兼容HTTP1.x的語義,只是改變了HTTP1.x的傳輸方式,在鏈接中是否使用HTTP2是經過協議協商(NPN、ALPN或Upgrade頭)來決定的。HTTP2擁有許多新特性:
  1. 二進制協議:HTTP2.0協議採用二進制格式,實現方便且健壯;HTTP1.x採用的是文本格式
  2. 頭部壓縮:HTTP/1.x 每次請求,都會攜帶大量冗餘頭信息,浪費了不少帶寬資源,頭壓縮可以很好的解決該問題
  3. 多路複用:多個請求和響應經過一個 TCP 鏈接併發完成,還支持請求優先級劃分和流控制
  4. Server Push:服務端能夠主動把 JS 和 CSS 文件推送給客戶端,而不須要客戶端先解析 HTML 再發送這些請求。當客戶端須要的時候,它們已經在客戶端了

  下圖是HTTP2 Frame 格式:RFC7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)
nginx

  

  

 

  • Nginx上部署HTTPS + HTTP2
  1. 自簽發證書:開發測試環境下能夠在其餘機器上去生成證書,而後再將所生成server.crt和server.key複製一份至Nginx的/usr/local/nginx/conf下便可
    $ cd /usr/local/nginx/conf
    $ openssl genrsa -des3 -out server.key 1024 #建議:2048
    $ openssl req -new -key server.key -out server.csr #證書籤名請求(CSR)
    $ cp server.key server.key.org
    $ openssl rsa -in server.key.org -out server.key
    $ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt #證書籤名
  2. 修改配置文件nginx.conf爲減小CPU負載,建議只運行一個工做進程,而且開啓keep-alive。另外,version 0.6.7以上的Nginx ssl_certificate和ssl_certificate_key的默認關聯目錄爲nginx.conf所在的目錄,默認文件名都爲cert.pem
    worker_processes 1;
    server {
    
        server_name YOUR_DOMAINNAME_HERE;
        listen 443 ssl http2;# http2 is available only since OpenSSL version 1.0.2
        listen 80;
        if ($scheme = http) {
                #rewrite ^(.*)$ https://$server_name$1 permanent;
    return 301 https://$server_name$request_uri;
    } ssl_certificate server.crt; ssl_certificate_key server.key; keepalive_timeout 70; }

     

  3. 重啓NginxHTTPS在Nginx上的部署至此已近完畢,而後就能夠經過https://YOUR_DOMAINNAME_HERE來訪問了。因爲本例中採用自簽發證書(不一樣於CA自簽名的Root證書),在Chrome下將看到如圖警告信息,代表該證書不受信任。瀏覽器在默認狀況下內置了一些CA機構的Root證書,這些證書受到絕對信任。

     

  另外,本人在Chromium 58.0.3029.110 和 Firefox 53.0.3 下均證明了HTTP2被成功啓用:算法

  

 

  • 私鑰保護:私鑰是重要的財產,儘量限制能接觸到私鑰的人
  1. 在一臺可信的計算機上生成私鑰和CSR(Certificate Signing Requests)。有一些CA會爲你生成密鑰和CSR,但這樣作明顯不妥
  2. 受密碼保護的密鑰能夠阻止在備份系統中被截獲
  3. 在發現被截獲後,撤回老的證書,生成新的密鑰和證書
  4. 每一年更新證書,老是使用最新的私鑰

 

  • 部署證書鏈:證書鏈(Certificate Chain)包括信任錨(CA 證書)和簽名證書,是由一系列 CA 證書發出的證書序列,最終以根 CA 證書結束;Web 瀏覽器已預先配置了一組瀏覽器自動信任的根 CA 證書,來自其餘證書受權機構的全部證書都必須附帶證書鏈,以檢驗這些證書的有效性。在不少部署場景中,單一的服務器證書顯得不足,而多個證書則須要創建一個信任鏈。一個常見的問題是正確的配置了服務器證書但卻搞忘了包含其餘所須要的證書。此外,雖然其餘證書一般有很長的有效期,但它們也會過時,若是它們過時就會影響整個鏈條。一個無效證書鏈會致使服務器證書失效和客戶端瀏覽器報警告,這個問題有時候不是那麼容易被檢測到,由於有些瀏覽器能夠本身重構一個完整的信任鏈而有些則不行。關於Nginx上部署證書鏈:
    if you have a chain certificate file (sometimes called an intermediate certificate)
    you don't specify it separately like you do in Apache. Instead you need to add the 
    information from the chain cert to the end of your main certificate file. This can be done 
    by typing "cat chain.crt >> mysite.com.crt" on the command line. Once that is done you
    won't use the chain cert file for anything else, you just point Nginx to the main certificate file

   下圖展現了證書鏈的工做原理:瀏覽器

      

 

  1. ssl開啓HTTPS

    syntax:ssl [on|off]安全

    default:ssl off服務器

    context:main, serversession

  2. ssl_certificate證書文件,默認證書和密鑰都位於cert.pem中,該文件還能夠包含其餘證書。自version 0.6.7起,ssl_certificate的默認關聯目錄爲nginx.conf所在的目錄。

    syntax:ssl_certificate file併發

    default:ssl_certificate cert.pempost

    context:main, server 

  3. ssl_certificate_key:證書密鑰文件,默認密鑰位於cert.pem中。自version 0.6.7起,ssl_certificate_key的默認關聯目錄爲nginx.conf所在的目錄。

    syntax:ssl_certificate_key file

    default:ssl_certificate_key cert.pem

    context:main, server

  4. ssl_client_certificate:Indicates file with certificates CA in PEM format, utilized for checking the client certificates.

    syntax:ssl_client_certificate file

    default:none

    context:main, server

  5. ssl_dhparamIndicates file with Diffie-Hellman parameters in PEM format, utilized for negotiating TLS session keys.

    syntax: ssl_dhparam file

    default: none

    context: main, server 

  6. ssl_ciphers:Directive describes the permitted ciphers. Ciphers are assigned in the formats supported by OpenSSL.

    syntax: ssl_ciphers file

    default: ssl_ciphers ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP

    context: main, server

    ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;

    Complete list can be looked with the following command:

    openssl ciphers

     

  7. ssl_prefer_server_ciphers:Requires protocols SSLv3 and TLSv1 server ciphers be preferred over the client's ciphers.

    syntax: ssl_prefer_server_ciphers [on|off]

    default: ssl_prefer_server_ciphers off

    context: main, server

  8. ssl_protocols:Directive enables the protocols indicated. TLS v1.0以上的版本是比較安全的,最好是棄用SSLv3如下的版本,SSLv2如下堅定不用

    syntax: ssl_protocols [SSLv2] [SSLv3] [TLSv1]

    default: ssl_protocols SSLv2 SSLv3 TLSv1

    context: main, server

  9. ssl_session_cache:The directive sets the types and sizes of caches to store the SSL sessions.

    syntax:ssl_session_cache off|none|builtin:size and/or shared:name:size

    default:ssl_session_cache off

    context:main, server

    ssl_session_cache builtin:1000 shared:SSL:10m;

     

  10. ssl_session_timeout:Assigns the time during which the client can repeatedly use the parameters of the session, which is stored in the cache.

    syntax:ssl_session_timeout time

    default:ssl_session_timeout 5m

    context:main, server

 

 

  • 參考
  1. 圖解SSL/TLS協議:http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html
  2. SSL/TLS協議運行機制的概述http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
  3. SSL/TLS部署最佳實踐http://www.techug.com/post/ssl-tls.html
  4. RFC7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)https://tools.ietf.org/html/rfc7540
  5. HTTP/2 的協議協商機制https://imququ.com/post/protocol-negotiation-in-http2.html
  6. Nginx HttpSSLhttp://www.nginx.cn/doc/optional/ssl.html
相關文章
相關標籤/搜索