016.Nginx HTTPS

一 HTTPS概述


1.1 HTTPS介紹


超文本傳輸安全協議HTTPS(Hypertext Transfer Protocol Secure)是超文本傳輸協議和SSL/TLS的組合,用以提供加密通訊及對網路伺服器身份的鑒定。


HTTPS也可以理解為HTTP over SSL,即HTTP連接建立在SSL安全連接之上。


HTTPS連接經常被用於萬維網上的交易支付和企業資訊系統中敏感資訊的傳輸。


注意:HTTPS與RFC 2660中定義的安全超文本傳輸協議(S-HTTP)不同。


1.2 SSL介紹


SSL(Secure Socket Layer)安全套接字層是一種數字證書,它使用ssl協議在瀏覽器和web server之間建立一條安全通道,數據資訊在client與server之間的安全傳輸。SSL使用證書來創建安全連接,通常有兩種驗證模式:




  • 僅客戶端驗證伺服器的證書,客戶端自己不提供證書;

  • 客戶端和伺服器都互相驗證對方的證書。


注意:編譯安裝的Nginx默認情況下ssl模組並未被安裝,如果要使用該模組則需要在編譯nginx時指定–with-http_ssl_module參數。


二 自簽名證書


2.1 自簽名證書


SSL需要使用TLS證書對通訊進行加密,通常可通過openssl工具生產自建證書。


2.2 openssl創建證書


  1 [root@nginx01 ~]# openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=ZheJiang/L=HangZhou/O=Xianghy/OU=Web Security/CN=tls.linuxds.com"


釋義:


-days 36500:證書有效期,100年;


-newkey rsa:2048:同時產生一個新證書和一個新的SSL key(加密強度為RSA 2048);


-keyout:SSL輸出文件名;


-out:證書生成文件名;


C:使用國際標準組織(ISO)國碼格式,填寫2個字母的國家代號,中國請填寫CN;


ST:省份,比如填ZheJiang;


L:城市,比如填寫HangZhou;


O:組織單位,比如填寫公司名稱的拼音;


OU:部門;


CN:配置 SSL 加密的網站地址。


提示:可自建泛域名的證書,如*.linuxds.com。


三 免費證書申請


3.1 騰訊雲申請


騰訊提供免費一年的SSL證書申請,具體操作略。


3.2 其他申請


免費證書也可通過://freessl.cn進行申請,具體操作略。


四 配置SSL


4.1 配置語法


  1 server {
  2     listen 443 ssl;				        #SSL 訪問埠號為 443
  3     server_name www.xxx.com;			#填寫綁定證書的域名
  4     ssl_certificate tls.crt;			#證書文件
  5     ssl_certificate_key tls.key;		        #私鑰文件
  6     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;	        #請按照以下協議配置
  7     ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;	#配置加密套件
  8     ssl_prefer_server_ciphers on;		        #依賴SSLv3和TLSv1協議的伺服器密碼將優先於客戶端密碼;
  9     ssl_session_timeout 5m;			        #會話過期時間;
 10     ssl_session_cache   shared:SSL:1m;		#儲存SSL會話的快取類型和大小;
 11 location / {
 12     root /web/www/website/dist;			#定義首頁索引文件的名稱
 13     index index.html;
 14 }


4.2 配置示例


  1 [root@nginx01 ~]# mkdir /usr/share/nginx/tls/
  2 [root@nginx01 ~]# echo '<h1>WebTLS</h1>' > /usr/share/nginx/tls/index.html


4.3 配置虛擬主機


  1 [root@nginx01 ~]# mkdir -p /etc/nginx/tls
  2 [root@nginx01 ~]# ll /etc/nginx/tls/
  3 total 8.0K
  4 -rw-r--r-- 1 root root 3.7K Jul  5 22:07 linuxds.crt
  5 -rw-r--r-- 1 root root 1.7K Jul  5 22:07 linuxds.key


  1 [root@nginx01 ~]# vi /etc/nginx/conf.d/tls.conf
  2 server {
  3     listen 443 ssl;
  4     server_name          tls.linuxds.com;
  5     root   /usr/share/nginx/tls/;
  6     access_log  /var/log/nginx/tls.access.log  main;
  7     error_log   /var/log/nginx/tls.error.log  warn;
  8     ssl_certificate      /etc/nginx/tls/linuxds.crt;
  9     ssl_certificate_key  /etc/nginx/tls/linuxds.key;
 10     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 11     ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
 12     ssl_prefer_server_ciphers on;
 13     ssl_session_timeout  5m;
 14     ssl_session_cache   shared:SSL:1m;
 15     location / {
 16         index  index.html index.htm;
 17     }
 18 }
 19 server
 20 {
 21     listen 80;
 22     server_name tls.linuxds.com;
 23     rewrite ^(.*) //$host$1 permanent;
 24 }


提示:如上http自動調整https也可如下寫法:


  1 server {
  2     listen 80;
  3     server_name tls.linuxds.com; 		#填寫綁定證書的域名
  4     return 301 //$host$request_uri;	#把http的域名請求轉成https
  5 }


  1 [root@nginx01 ~]# nginx -t -c /etc/nginx/nginx.conf	#檢查配置文件
  2 [root@nginx01 ~]# nginx -s reload			#重載配置文件


4.4 確認驗證


瀏覽器訪問://tls.linuxds.com,觀察是否自動調整至//tls.linuxds.com。


clipboard


參考官網://nginx.org/en/docs/http/configuring_https_servers.html。


五 HTTPS其他優化


5.1 優化CPU消耗


SSL 的運算需要消耗額外的 CPU 資源,一般多核處理器系統會運行多個工作進程(worker processes ),進程的數量不會少於可用的 CPU 核數。SSL 通訊過程中【握手】階段的運算最佔用 CPU 資源,通常有兩個方法可以減少每台客戶端的運算量:




  • 激活 keepalive 長連接,一個連接發送更多個請求;

  • 復用 SSL 會話參數,在並行並發的連接數中避免進行多次 SSL【握手】。


這些會話會存儲在一個 SSL 會話快取裡面,通過命令 ssl_session_cache 配置,可以使快取在機器間共享,然後利用客戶端在【握手【階段使用的 seesion id 去查詢服務端的 session cathe(如果服務端設置有的話),簡化【握手】階段。


1M 的會話快取大概包含 4000 個會話,默認的快取超時時間為 5 分鐘,可以通過使用ssl_session_timeout 命令設置快取超時時間。


示例:


  1 server
  2 {
  3 ……
  4     ssl_session_timeout  10m;				#配置會話超時時間
  5     ssl_session_cache   shared:SSL:10m;			#配置共享會話快取大小,視站點訪問情況設定
  6     keepalive_timeout   70;				#設置長連接
  7 ……
  8 }


5.2 使用HSTS優化安全性


HSTS:HTTP Strict Transport Security,HTTP嚴格傳輸安全。它允許一個 HTTPS 網站要求瀏覽器總是通過 HTTPS 來訪問,這使得攻擊者在用戶與伺服器通訊過程中攔截、篡改資訊以及冒充身份變得更為困難。


示例:


  1 server
  2 {
  3 ……
  4     add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
  5 ……
  6 }


釋義:


max-age:設置單位時間內強制使用 HTTPS 連接;


includeSubDomains:可選,所有子域同時生效;


preload:可選,非規範值,用於定義使用【HSTS 預載入列表】


always:可選,保證所有響應都發送此響應頭,包括各種內置錯誤響應。


瀏覽器在獲取該響應頭後,在 max-age 的時間內,如果遇到 HTTP 連接,就會通過 307 跳轉強制使用 HTTPS 進行連接,並忽略其它的跳轉設置(如 301 重定向跳轉)


5.3 提升演算法優化安全性


HTTPS 基礎配置採取的默認加密演算法是 SHA-1,這個演算法非常脆弱,安全性逐步降低,因此建議重要的 HTTPS 配置方案應該避免 SHA-1,可以使用 迪菲-赫爾曼密鑰交換(D-H,Diffie–Hellman key exchange)方案。




  1. 生產dhparam.pem文件


  1 [root@nginx01 ~]# cd /etc/nginx/tls
  2 [root@nginx01 tls]# openssl dhparam -out dhparam.pem 2048




  1. 配置Nginx採用的演算法


  1 [root@nginx01 tls~]# server
  2 {
  3 ……
  4     ssl_prefer_server_ciphers on;				#優先採取伺服器演算法
  5     ssl_dhparam /etc/nginx/tls/dhparam.pem;			#使用DH文件
  6     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  7     ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";	#定義演算法
  8 ……
  9 }


5.4 其他安全優化


通常Nginx要可以配合如下安全參數來提升安全性。


  1 {
  2 ……
  3     add_header X-Frame-Options DENY;			#減少點擊劫持
  4     add_header X-Content-Type-Options nosniff;		#禁止伺服器自動解析資源類型
  5     add_header X-Xss-Protection 1;				#防止XSS攻擊
  6 ……
  7 }


5.5 優化總結示例


使用相應優化後的配置如下:


  1 [root@nginx01 ~]# cd /etc/nginx/tls
  2 [root@nginx01 tls]# openssl dhparam -out dhparam.pem 2048


  1 [root@nginx01 tls]# vi /etc/nginx/conf.d/tls.conf
  2 server {
  3     listen 443 ssl;
  4     server_name          tls.linuxds.com;
  5     root   /usr/share/nginx/tls/;
  6     access_log  /var/log/nginx/tls.access.log  main;
  7     error_log   /var/log/nginx/tls.error.log  warn;
  8     ssl_certificate      /etc/nginx/tls/linuxds.crt;
  9     ssl_certificate_key  /etc/nginx/tls/linuxds.key;
 10     ssl_session_timeout  10m;				#配置會話超時時間
 11     ssl_session_cache    shared:SSL:10m;			#配置共享會話快取大小
 12     keepalive_timeout    70;				#配置長連接
 13     add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;								                #HSTS策略
 14     add_header X-Frame-Options DENY;			#減少點擊劫持
 15     add_header X-Content-Type-Options nosniff;		#禁止伺服器自動解析資源類型
 16     add_header X-Xss-Protection 1;				#防止XSS攻擊
 17     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 18     ssl_prefer_server_ciphers on;				#優先採取伺服器演算法
 19     ssl_dhparam /etc/nginx/tls/dhparam.pem;			#使用DH文件
 20     ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";	#定義演算法
 21     location / {
 22         index  index.html index.htm;
 23     }
 24 }
 25 server
 26 {
 27     listen 80;
 28     server_name tls.linuxds.com;
 29     rewrite ^(.*) //$host$1 permanent;
 30 }


  1 [root@nginx01 ~]# nginx -t -c /etc/nginx/nginx.conf	#檢查配置文件
  2 [root@nginx01 ~]# nginx -s reload			#重載配置文件


瀏覽器訪問://tls.linuxds.com,觀察響應頭資訊。


clipboard


參考://aotu.io/notes/2016/08/16/nginx-https/index.html。


//imququ.com/post/web-security-and-response-header.html