1. 程式人生 > >Nginx 部分 (四) -SSL設定及效能優化、CORS配置

Nginx 部分 (四) -SSL設定及效能優化、CORS配置

在看過基礎概念與效能管理後,SSL設定也隨之到來,儘管可能準備的不盡人意,但是儘量使得內容足以解惑。

SSL 和 TLS

SSL(Socket Secure Layer 縮寫)是一種通過 HTTP 提供安全連線的協議。

SSL 1.0 由 Netscape 開發,但由於嚴重的安全漏洞從未公開發布過。SSL 2.0 於 1995 年釋出,它存在一些問題,導致了最終的 SSL 3.0 在 1996 年釋出。

TLS(Transport Layer Security 縮寫)的第一個版本是作為 SSL 3.0 的升級版而編寫的。之後 TLS 1.1 和 1.2 出來了。現在,就在不久之後,TLS 1.3 即將推出(這確實值得期待),並且已經被一些瀏覽器所支援。

從技術上講,SSL 和 TLS 是不同的(因為每個協議都描述了協議的不同版本),但其中使用的許多名稱是可以互換的。

基本 SSL/TLS 配置

為了處理 HTTPS 流量,你需要具有 SSL/TLS 證書。你可以通過使用 Let’s encrypt 以生成免費的證書。

當你擁有證書之後,你可以通過以下的方式輕易切換至 HTTPS:

  • 開始監聽埠 443(當你輸入 https://sample.co 時瀏覽器將使用的預設埠)
  • 提供證書及其金鑰
server {
  listen 443 ssl default_server;
  listen [::]:443 ssl default_server;
 
  ssl_certificate /etc/nginx/ssl/netguru.crt;
  ssl_certificate_key /etc/nginx/ssl/netguru.key;
}

我們也想通過調整配置實現:

  • 僅使用 TLS 協議。由於眾所周知的漏洞,所有的 SSL 版本都將不再使用

  • 使用預定義的安全的伺服器密碼(類似於協議的情況 – 那些日子只有少數密碼被認為是安全的)


 設定總在變化,時不時更新總是好的

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:!MD5;
ssl_prefer_server_ciphers on;
 
server {
  listen 443 ssl default_server;
  listen [::]:443 ssl default_server;
 
  ssl_certificate /etc/nginx/ssl/netguru.crt;
  ssl_certificate_key /etc/nginx/ssl/netguru.key;
}

TLS 會話恢復

使用 HTTPS,在 TCP 之上需要增加 TLS 握手。這大大增加了此前實際資料傳輸的時間。假設你從華沙請求 /image.jpg,並接入到柏林最近的伺服器:

為了在 TLS 握手期間節省一個 roundtrip 時間,以及生成新金鑰的計算開銷,我們可以重用在第一個請求期間生成的會話引數。客戶端和伺服器可以將會話引數儲存在會話 ID 金鑰的後面。在接下來的 TLS 握手過程中,客戶端可以傳送會話 ID,如果伺服器在快取中仍然有正確的條目,那麼會重用前一個會話所生成的引數。

server {
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1h;#超時時間
}

OCSP Stapling

SSL 證書可以隨時撤銷。瀏覽器為了知道給定的證書是否不再有效,需要通過線上證書狀態協議 (Online Certificate Status Protocol ,OCSP) 執行額外的查詢。無需使用者執行指定的 OCSP 查詢,我們可以在伺服器上執行此操作,快取其結果,並在 TLS 握手期間為客戶端提供 OCSP 響應。它被稱為OCSP stapling

server {
  ssl_stapling on;
  ssl_stapling_verify on;                               # verify OCSP response
  ssl_trusted_certificate /etc/nginx/ssl/lemonfrog.pem; # tell nginx location of all intermediate certificates,自己證書的位置
 
  resolver 8.8.8.8 8.8.4.4 valid=86400s;                # resolution of the OCSP responder hostname
  resolver_timeout 5s;
}

Security headers

有一些標頭確實值得調整以提供更高的安全性。有關更多關於標頭及其詳細資訊,你絕對應該檢視OWASP 專案之安全標頭。

HTTP Strict-Transport-Security(HSTS)

簡稱 HSTS,強制使用者代理在向源傳送請求時使用 HTTPS。

語法如下:
Strict-Transport-Security: <max-age=>[; includeSubDomains][; preload]
Strict-Transport-Security: <max-age=>[; includeSubDomains][; preload]
示例: add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
  • max-age是必選引數,是一個以秒為單位的數值,它代表著HSTS Header的過期時間,通常設定為1年,即31536000秒。
  • includeSubDomains是可選引數,如果包含它,則意味著當前域名及其子域名均開啟HSTS保護。
  • preload是可選引數,只有當你申請將自己的域名加入到瀏覽器內建列表的時候才需要使用到它。關於瀏覽器內建列表,點選上面超連結進入並配置。

X-Frame-Options

表示瀏覽器是否需要在一幀、一個 iframe 或一個物件標籤中渲染頁面

	add_header X-Frame-Options DENY;

(1)DENY --- 表示該頁面不允許在 frame 中展示,即便是在相同域名的頁面中巢狀也不允許。

(2)SAMEORIGIN --- 表示該頁面可以在相同域名頁面的 frame 中展示。

(3)ALLOW-FROM https://example.com/ --- 表示該頁面可以在指定來源的 frame 中展示。


X-Content-Type-Options

此選項將阻止瀏覽器在判斷檔案型別時嗅探檔案。檔案將會按照 Content-Type 頭中宣告的格式轉譯。

add_header X-Content-Type-Options nosniff;

如果伺服器傳送響應頭 “X-Content-Type-Options: nosniff”,則 script 和 styleSheet 元素會拒絕包含錯誤的 MIME 型別的響應。這是一種安全功能,有助於防止基於 MIME

型別混淆的攻擊。

Server tokens

另一個很好的做法是在 HTTP 響應頭欄位中隱藏有關 Web 伺服器的資訊:不然會出現:

Server : nginx/1.18.2

我們需要如下去隱藏版本號以防安全

server_tokens off;

CORS配置

 專案中額外需要配置跨站請求,先了解一下配置屬性意義:

  • Access-Control-Allow-Origin(必含):允許的域名,只能填萬用字元或者單域名
  • Access-Control-Allow-Methods(必含):允許跨域請求的 http 方法
  • Access-Control-Allow-Headers返回支援的 http 請求頭
  • Access-Control-Allow-Credentials(可選):標誌著當前請求是否包含 cookies 資訊,布林值。只有一個可選值:true,如果不包含 cookies,請略去該項,而不是填 false。這一項與XmlHttpRequest2 物件當中的 withCredentials 屬性應保持一致,即 withCredentials 為true時該項也為 true;withCredentials為false時,省略該項不寫。反之則導致請求失敗。
  • Access-Control-Max-Age(可選):以秒為單位的快取時間,用於快取預檢請求。
如下填入nginx配置即可,個性化根據個人而已稍作修改
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
            add_header Access-Control-Allow-Credentials 'true';
            add_header Access-Control-Allow-Headers 'Accept, Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
            if ($request_method = 'OPTIONS') {
               add_header 'Access-Control-Allow-Origin' *;
               add_header 'Access-Control-Max-Age' 1728000;
               add_header 'Access-Control-Allow-Credentials' 'true';
               add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PUT, OPTIONS';
               add_header 'Access-Control-Allow-Headers' 'Accept, Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
               add_header 'Content-Type' 'text/plain charset=UTF-8';
               add_header 'Content-Length' 0;
               return 204;
           }