nginx(二):進階配置介紹–rewrite用法,壓縮,https虛擬主機等

cutemsyu發表於2017-01-06

1、nginx基本狀態資訊頁面

配置示例:

location  /basic_status {
                            stub_status;
                        }

頁面展示含義:

Active connections: 291 
server accepts handled requests
    16630948 16630948 31070465 
Reading: 6 Writing: 179 Waiting: 106     

Active connections: 活動狀態的連線數;
accepts:已經接受的客戶端請求的總數;
handled:已經處理完成的客戶端請求的總數;
requests:客戶端發來的總的請求數;
Reading:處於讀取客戶端請求報文首部的連線的連線數;
Writing:處於向客戶端傳送響應報文過程中的連線數;
Waiting:處於等待客戶端發出請求的空閒連線數;

2、記錄請求日誌

指令:

  1. log_format
    作用域: http
  2. access_log
    作用域: http, server, location, if in location, limit_except
  3. open_log_file_cache
    作用域: http, server, location

2.1 log_format

在http區域定製日誌格式
用法:log_format name string …;
name指定一個格式名稱,string可以使用nginx核心模組及其它模組內嵌的變數指定格式。

2.2 access_log

可在每個server中,或location中指定一個日誌存放路徑
用法:

access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;

指定日誌存放路徑path,格式format,緩衝區大小buffer,也可啟用壓縮日誌,指定壓縮級別gzip

2.3 open_log_file_cache

定義一個快取儲存活躍的日誌檔案描述符資料
用法:

open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;

max:快取的最大檔案描述符數量;
min_users:在inactive指定的時長內訪問大於等於此值方可被當作活動項;
inactive:非活動時長;
valid:驗證快取中各快取項是否為活動項的時間間隔;
配置示例:

log_format combined `$remote_addr - $remote_user [$time_local] `
                       `"$request" $status $bytes_sent `
                       `"$http_referer" "$http_user_agent" "$gzip_ratio"`;

access_log /var/logs/nginx-access.log combined buffer=32k;
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;

3、rewrite重寫

將使用者請求的URI基於regex所描述的模式進行檢查,而後完成替換;
URL重寫是一個非常有用的功能,如果一個網站在改進的過程中結構發生變化,無需客戶端更改已儲存訪問地址仍可正常訪問;提升網站安全性,如放盜鏈行為。

3.1 rewrite


syntax: rewrite regex replacement [flag]
Context:    server, location, if

將使用者請求的URI基於regex所描述的模式匹配檢查,匹配到時將其替換成replacement指定的新URI;
rewrite指令在同一級配置塊中存在多條rewrite規則,會按照順序自上而下逐一執行;被某一規則替換完成後,重新開始新一輪檢查,因此本身具有迴圈機制,flag所表示的標誌位可控制迴圈機制;如果replacement是以http://或其他協議開頭的字串,則直接以重定向方式返回給客戶端;
另外,rewrite指令接收到的URI是不包含host地址的,例如http://cutemsyu.com/articles/…,不包含”cutemsyu.com” ,在寫regex規則時應當注意。

[flag] 可用標識如下:

  • last:停止在當前區域繼續處理,將重寫的新URI在各location中重新處理;
  • break:將此處重寫的URI在本塊中繼續處理,但新的URI不會轉向其他location中處理;
  • redirect:將重寫的URI直接返回給客戶端,狀態程式碼為302,表示臨時重定向。用在replacement不以”http://”或”https://”開頭的情況下;
  • permanent:將重寫的URI直接返回給客戶端,狀態碼為301,指明為永久重定向。

Example:

#flag 是last的一個例子
server {
    ...
    rewrite ^(/download/.*)/media/(.*)..*$ $1/mp3/$2.mp3 last;
    rewrite ^(/download/.*)/audio/(.*)..*$ $1/mp3/$2.ra  last;
    return  403;
    ...
}

#如果上面的rewrite規則寫在location中,則應該使用break標識,防止死迴圈,如果迴圈超過10此,返回500錯誤碼
location /download/ {
    rewrite ^(/download/.*)/media/(.*)..*$ $1/mp3/$2.mp3 break;
    rewrite ^(/download/.*)/audio/(.*)..*$ $1/mp3/$2.ra  break;
    return  403;
}

3.2 return


syntax: return code [text];
        return code URL;
        return URL;
context: server, location, if

停止處理並返回一個狀態碼給客戶端。

3.3 if 指令


syntax: if (condition) { ... }
context: server, location

引入一個新的配置上下文,滿足條件時執行配置塊中的指令
condition為判斷條件,支援三種設定方法:

  • 變數名,如果變數值為空字串或者以0開頭的任意字串,則表示條件為false
  • 使用比較符判斷變數與字串的邏輯關係
  • 判斷檔案或目錄存在情況

其中 比較操作符有:

  • =
  • !=
  • ~ 模式匹配,區分字元大小寫
  • ~* 模式匹配,不區分字元大小寫
  • !~:模式不匹配,區分字元大小寫
  • !~*:模式不匹配,不區分字元大小寫

檔案及目錄存在性判斷:

  • -e, !-e 檢查一個檔案,目錄,或軟連結是否存在
  • -f, !-f 檢查一個檔案是否存在
  • -d, !-d 檢查一個目錄是否存在
  • -x, !-x 檢查一個檔案是否可執行

Example:

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
}

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;  
}

if ($request_method = POST) {
    return 405;
}

if ($slow) {
    limit_rate 10k;
}

if ($invalid_referer) {
    return 403;
}

3.4 rewrite的應用

3.4.1 域名跳轉

Example:

#訪問video.cutemsyu.com 跳轉至v.cutemsyu.com
server {
    listen 80;
    server_name video.cutemsyu.com;
    rewrite ^(.*) http://v.cutemsyu.com$1 ;
    ...
}

3.4.2 rewrite uri中引數

預設情況下nginx進行rewrite後都會自動新增舊地址中引數部分,在replacement末尾新增”?”即可遮蔽舊地址中的引數
Example:

   ##原來的訪問的url為http://cutemsyu.com/article/nature/index.php?id=22341
   rewrite ^/article/nature/(.*) http://cutemsyu.com/article/natrue.html permanent
   重寫之後訪問的URL為http://cutemsyu.com/article/nature.html?id=22341
   也就是說原有的引數部分它會自動補上
   rewrite ^/article/nature/(.*) http://cutemsyu.com/article/natrue.html? permanent
   重寫之後的URL為http://cutemsyu.com/article/nature.html,沒有原來的引數部分
    

3.4.3 防盜鏈

通常為了加快客戶端訪問資源響應時間,伺服器不會一次性將全部資源響應給客戶端,首先傳回網頁的文字內容,當客戶端解析文字內容中的圖片、視訊等資源時會再次向伺服器發起請求。當某個站點將圖片連結指向其他伺服器,給其他伺服器造成負擔,這就是非法的盜鏈行為。我們在搭建服務站點時要有意識防範盜鏈行為。
http協議頭部中referer頭域表示訪問當前資源的源地址,根據referer中的源地址URL來判斷是否來自本站,如非本站的地址,採取阻斷措施防止盜鏈。


syntax: valid_referers none | blocked | server_names | string ...;
context: server,location;

valid_referers 指令根據規則檢測頭域中referer中值是否合法,如果非法內嵌變數 $invalid_referer 值為1.
引數含義:

  • none,表示檢測referer為空的情況
  • blocked,表示檢測referer的值被防火牆或者代理伺服器刪除的情況,通常referer的值不以http://或https:// 開頭
  • server_names,referer的值應該被包含在server_name中
  • string,定義字串形式。

    1. 開始或尾部帶有萬用字元*
    2. 正規表示式,以~引導,匹配http://後面的內容

Example:

#如果發現盜鏈,重寫連結為指定的表示禁止盜用的圖片
server {
    listen 80;
    server_name v.cutemsyu.com;
    location ~* ^.+.(gif|jpg|png|flv|mp4|swf)$ {
        valid_referers none blocked server_names *.cutemsyu.com ~.google.
        if ($invalid_referer) {
            rewrite ^/ http://v.cutemsyu.com/images/forbbiden.jpg
        }
    }
}

4、gzip壓縮

壓縮文字資料,提升網路響應速度,作為靜態伺服器使用很有必要開啟,壓縮文字將節省大量頻寬,同時提升響應速度。但是如果作為反向代理伺服器則需要考慮,壓縮功能是否應該由後端伺服器承擔,以此減輕前端伺服器CPU壓力。

4.1 ngx_http_gzip_module

該模組功能是對指定型別資料使用gzip方法壓縮
作用域Context: http, server, location

  1. gzip on |off;

此模組gzip功能啟用或禁用

  1. gzip_types mime-types … ;

壓縮過濾器,僅對指定的MIME型別進行壓縮處理

  1. gzip_comp_level level;

設定壓縮級別1-9,預設值為1壓縮速率最快,壓縮比最低

  1. gzip_min_length length;

啟用壓縮功能的響應報文大小閾值,小於該置不進行壓縮。防止有些小資料壓縮之後更大的情況,推薦值為1024

  1. gzip_buffers number size;

壓縮資料使用緩衝區大小,size預設為記憶體分頁大小

  1. gzip_disable regex;

舊版本的瀏覽器對於gzip功能支援不完善,對於該指令配置的正則資訊與瀏覽器型別匹配,匹配成功的響應不進行壓縮處理

  1. gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any …;

nginx作為反向代理伺服器接收後端伺服器響應結果壓縮控制

4.2 ngx_http_gunzip_module

解壓模組,該模組對於不支援壓縮功能的瀏覽器請求,響應結果如果被壓縮則將其解壓後返回給客戶端。適用於某些以gzip方式壓縮過儲存的資料。
作用域Context: http, server, location
提示該模組不是預設編譯內容,編譯選項–with-http_gunzip_module

  1. gunzip on |off ;
    是否開啟該模組功能

    1. gunzip buffers number size;

用於解壓資料使用的緩衝區空間配置

4.3 ngx_http_gzip_static_module

靜態壓縮模組,該模組允許傳送預壓縮資料,如果客戶端請求的資料已被壓縮過,且客戶端支援gzip壓縮,則直接返回壓縮資料。
作用域Context: http, server, location
提示該模組不是預設編譯內容,編譯選項–with-http_gzip_static_module

  1. gzip_static on | off ;
    是否開啟該模組
  2. gzip_disable regex;
    對於適配瀏覽器型別禁止gzip功能

4.4 配置示例

gzip on;
gzip_comp_level 3;
gzip_types text/html text/css text/xml text/plain application/javascript;
gzip_min_length 1024;
gzip_disable "MISE [4-6].";
gzip_buffers 8 16K;
gunzip on;         #支援自動解壓功能

5、ssl模組

HTTP協議屬於明文協議,通過抓包就可獲取一些隱私資料。HTTPS經由超文字傳輸協議HTTP通訊,但是資料包由SSL/TLS 安全協議加密,實現加密資料與認證功能。
ngx_http_ssl_module 該模組指令定義https相關設定:證照檔案,私鑰檔案,ssl會話快取等內容。
作用域Context: http, server

5.1 指令介紹

 1. ssl on | off;
 設定虛擬主機是否啟用HTTPS協議
 2. ssl_certificate file;
 指定當前虛擬主機使用的PEM格式的證照檔案
 3. ssl_certificate_key file;
 指定當前虛擬主機上與其證照相匹配的私鑰檔案
 4. ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
 支援ssl協議版本,預設為後三個
 5. ssl_session_cache off | none | [builtin[:size]] [ shared:name:size ];
 ssl會話快取設定。
 builtin[:size] --使用OpenSSL內建的快取,此快取為每worker私有。容易產生記憶體碎片不推薦。
 shared:name:size --worker之間共享的快取區域,size單位為bytes,1MB可儲存4000個會話;name為共享快取區域名稱,多個虛擬主機可使用同一個共享快取區。
 6. ssl_session_timeout time;
 客戶端可重複使用會話引數的超時時長。預設5分鐘

Example:

server {
                listen 443 ssl;
                server_name www.cutemsyu.com;
                root /website/ssl/htdocs;
                ssl on;
                ssl_certificate /etc/nginx/ssl/nginx.crt;
                ssl_certificate_key /etc/nginx/ssl/nginx.key;
                ssl_session_cache shared:sslcache:15m;
                ssl_session_timeout 3m;
            }

5.2 基於域名的HTTPS虛擬主機

值得考慮的一個問題是如何實現多個HTTPS虛擬主機監聽在同一IP地址上。
情況一:每個虛擬主機使用各自的證照檔案,如下

server {
    listen          443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
    ...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
    ...
}

如此配置的話,客戶端訪問這兩個站點建立SSL會話時收到的都是預設主機的證照檔案。該問題是由於SSL協議造成的,SSL連結在客戶端傳送HTTP請求之前建立起來的,然而nginx並不知道所請求的服務主機名,因此返回預設伺服器證照檔案。
解決方法一:
多個HTTPS虛擬主機使用同一證照檔案和私鑰檔案,證照和私鑰配置指令在http級別設定,server共享其配置

ssl_certificate     common.crt;
ssl_certificate_key common.key;

server {
    listen          443 ssl;
    server_name     www.example.com;
    ...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
    ...
}

解決辦法二:
更通用的辦法是使用TLS Server Name Indication extension技術,即SNI。SNI允許在客戶端建立SSL會話時傳遞請求伺服器名稱,這樣伺服器就會知道該傳送哪個虛擬主機下的證照檔案。該技術需要瀏覽器支援,一般主流瀏覽器都已支援

  • Opera 8.0;
  • MSIE 7.0 (but only on Windows Vista or higher);
  • Firefox 2.0 and other browsers using Mozilla Platform rv:1.8.1;
  • Safari 3.2.1 (Windows version supports SNI on Vista or higher);
  • and Chrome (Windows version supports SNI on Vista or higher, too)

同時確保nginx支援SNI功能:

$ nginx -V
...
TLS SNI support enabled
...

本篇文章到此結束,下篇總結nginx反向代理,fastcgi模組,感謝關注!

相關文章