Nginx高階功能詳解

leikj發表於2024-06-28

一、重寫功能

Nginx伺服器利用 ngx_http_rewrite_module 模組解析和處理rewrite請求。

官方文件:nginx.org/en/docs/htt…

用於實現URL的重寫,URL的重寫是非常有用的功能,比如它可以在我們改變網站結構之後,不需要客戶端修改原來的書籤,也無需其他網站修改我們的連結,就可以設定為自動訪問,另外還可以在一定程度上提高網站的安全性。

  1. if 指令

if指令可以配置在server或location塊中
if指令用於條件匹配判斷,並根據條件判斷結果選擇不同的Nginx配置
Nginx的if語法僅能使用if做單次判斷,不支援使用if else或者if elif這樣的多重判斷
使用正規表示式對變數進行匹配,匹配成功時if指令認為條件為true,否則認為false

用法:

點選檢視程式碼
if (條件匹配) {   
 action
}

示例:
點選檢視程式碼
[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf  //編輯子配置檔案

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

location /test {
     index index.html;            //定義網站的預設首頁
     default_type text/html;      //指定解析當前內容的型別
   if  ( $scheme = https ) {      //新增if指令
   echo "if -----> $scheme";
   }
 }
}

[root@node1 ~]#  nginx -s reload  //重新載入

瀏覽器驗證 https://192.168.204.10/test

  1. return 指令
  • return用於完成對請求的處理,並直接向客戶端返回響應狀態碼
  • return可以在server、location塊和 if 進行配置
  • 處於此指令後的所有配置都將不被執行

語法格式:

點選檢視程式碼
Syntax:	return code [text];  //返回給客戶端的狀態碼及響應報文的實體內容
           return code URL;    //返回給客戶端的URL地址
           return URL; 
Default:	—
Context:	server, location, if

示例:
點選檢視程式碼
[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

  location /test {
     index index.html;
     default_type text/html;
     return 666 "hello";     //如果訪問192.168.204.10/test 就返回666錯誤程式碼,頁面顯示hello
  }
}

[root@node1 ~]#  nginx -s reload     //重新載入        

[root@node2 ~]#  curl 192.168.204.10/test
hello
[root@node2 ~]#  curl 192.168.204.10/test -I
HTTP/1.1 666    //錯誤程式碼666
Server: nginx
..........

示例2:301

點選檢視程式碼
[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

  location /test {
     index index.html;
     default_type text/html;
     return 301 http://www.baidu.com/;     //如果訪問192.168.204.10/test 就返回301並跳轉到百度
  }
}

[root@node1 ~]#  nginx -s reload     //重新載入        

示例3:302

點選檢視程式碼
[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

  location /test {
     index index.html;
     default_type text/html;
     return 302 index.html;     //如果訪問192.168.204.10/test 就返回302並顯示/data/html/index.html內容
  }
}

[root@node1 ~]#  nginx -s reload     //重新載入        

狀態碼 301 和 302

狀態碼 含義 區別
301 永久重定向 伺服器不需要每次向客戶提供新的url,客戶訪問過後會記錄在自己的快取中,即使nginx伺服器當機,客戶在一定時間內也可以繼續跳轉
302 臨時重定向 沒有快取,伺服器斷開無法重定向
  1. set 指令
  • set定義格式為set $key value
  • 指定key並給其定義一個變數,變數可以呼叫Nginx內建變數賦值給key
  • value可以是text, variables和兩者的組合
    語法格式:
點選檢視程式碼
Syntax:	set $variable value;
Default:	—
Context:	server, location, if

示例:
點選檢視程式碼
[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

  location /test {
     index index.html;
     default_type text/html;
set $name kgc;               //新增set指令
echo $name;
set $my_port $server_port;
echo $my_port;
}
}

[root@node1 ~]#  nginx -s reload   //重新載入

[root@node2 ~]#  curl 192.168.204.10/test   //驗證
kgc
80

  1. break 指令

用於中斷 當前相同作用域(location)中的其他Nginx配置,與該指令處於同一作用域的Nginx配置中,位於它前面的配置生效,位於後面的 ngx_http_rewrite_module 模組中指令就不再執行。

語法格式:

點選檢視程式碼
Syntax:	break;
Default:	—
Context:	server, location, if

示例:
點選檢視程式碼
[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

  location /test {
     index index.html;
     default_type text/html;
set $name kgc;
echo $name;
break;          //新增 break 指令
set $my_port $server_port;
echo $my_port;
echo $host;
}
}

[root@node1 ~]#  nginx -s reload   //重新載入

[root@node2 ~]#  curl 192.168.204.10/test    //驗證
kgc
                //break指令下的set指令不執行
192.168.204.10

break下如果出現同屬於rewrite模組的指令(if、return、set、rewrite等),那麼break後的指令將不再執行。
  1. rewrite 指令

透過正規表示式的匹配來改變URI,可以同時存在一個或多個指令,按照順序依次對URI進行匹配,rewrite主要是針對使用者請求的URL或者是URI做具體處理

語法格式:

點選檢視程式碼
Syntax:	rewrite regex replacement [flag];
Default:	—
Context:	server, location, if

//正則匹配原始訪問url    替代你想讓客戶訪問的     標誌 ()premanent301   redirect302  break  last

flag 說明:

型別 flag 區別
跳轉型 redirect 臨時重定向302
permanent 永久重定向301
代理型 break 是立即終止匹配 使用該url進行匹配
last 停止本location中的匹配,開啟新一輪的location匹配
  • 跳轉型指由客戶端瀏覽器重新對新地址進行請求
  • 代理型是在WEB伺服器內部實現跳轉
  • break 和 last 是為了防止死迴圈使用的

示例1

實驗效果:訪問 bj 等於訪問 beijing

點選檢視程式碼
[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf  

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

 location /bj {      
 root /data/;   //注意!url為bj時訪問此目錄下的頁面,但是重寫後url變為beijing,就不再生效
 rewrite ^/bj/(.*)   /beijing/$1   permanent;   //新增rewrite指令,$1代表後項引用
 }
}

[root@node1 ~]#  cd html
[root@node1 html]#  mkdir beijing        //建立目錄
[root@node1 html]#  echo /data/beijing/ > beijing/index.html   //生成頁面


[root@node1 data]#  nginx -t         //檢查格式
[root@node1 data]#  nginx -s reload  //重新載入

瀏覽器訪問192.168.204.10/bj/    //注意bj後面要加/,不然會報錯404
等於訪問192.168.204.10/beijing/

示例2
實驗效果:整個網頁跳轉 ,www.pc.com 跳轉到 www.m.com

點選檢視程式碼
[root@node1 html]#  vim /apps/nginx/conf.d/pc.conf

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

 location / {
 rewrite  /  http://www.m.com  permanent;   //重寫
 }
}


server  {
listen 80;
server_name  www.m.com;
root /opt;
}

[root@node1 html]#  cd /opt
[root@node1 opt]#  echo "/opt/wo shi m.com" > index.html   //生成頁面
[root@node1 opt]#  nginx -s reload   //重新載入

真機 在C:\Windows\System32\drivers\etc下編輯hosts檔案,新增域名

瀏覽器訪問192.168.204.10/  會跳轉到www.m.com

示例3
實驗效果:http 轉 https

點選檢視程式碼
[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf 

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

   location / {
   if  ( $scheme = http ) {
   rewrite ^/(.*)$ https://www.pc.com/$1 permanent;  //重寫
   }
  }
}

[root@node1 ~]#  nginx -s reload   //重新載入

瀏覽器輸入http://www.pc.com
會跳轉為  https://www.pc.com

  1. 防盜鏈
    防盜鏈基於客戶端攜帶的referer實現,referer是記錄開啟一個頁面之前記錄是從哪個頁面跳轉過來的標記資訊,如果別人只連結了自己網站圖片或某個單獨的資源,而不是開啟了網站的整個頁面,這就是盜鏈,referer就是之前的那個網站域名,正常的referer資訊有以下幾種:
  • none:請求報文首部沒有referer首部,比如使用者直接在瀏覽器輸入域名訪問web網站,就沒有referer資訊。
  • blocked:請求報文有referer首部,但無有效值,比如為空。
  • server_names:referer首部中包含本主機名及即nginx 監聽的server_name。
  • arbitrary_string:自定義指定字串,但可使用 * 作萬用字元。示例:.kgc.org 或 www.kgc.
  • regular expression:被指定的正規表示式模式匹配到的字串,要使用 ~ 開頭,例如:~.*.kgc.com

實現盜鏈
7-1:192.168.204.10
7-2:192.168.204.20

7-1上傳一張圖片;

點選檢視程式碼
[root@node1 ~]#  cd /data/html
[root@node1 html]#  rz   //上傳一張圖片

[root@node1 html]#  ls
about  beijing  download  index.html  passwd.html  xhr.jpg  //圖片上傳成功

7-2安裝nginx,自定義頁面;
點選檢視程式碼
[root@node2 ~]#  yum install epel-release.noarch -y
[root@node2 ~]#  yum install nginx               //yum安裝nginx
[root@node2 ~]#  systemctl start nginx           //開啟服務
[root@node2 nginx]#  cd /usr/share/nginx/html/   //切換目錄
[root@node2 html]#  ls
404.html  50x.html  en-US  icons  img  nginx-logo.png  poweredby.png

[root@node2 html]#  vim index.html    //生成頁面

<html>
<body>
<h1>this is Bob  </h1>
<img src="http://192.168.204.10/xhr.jpg"/>     //指明圖片的源位置
</body>
</html>

[root@node2 html]#  systemctl restart nginx    //重啟服務

瀏覽器輸入7-2的ip地址 192.168.204.20 ;
7-2中實際並不存在xhr.jpg這張圖片,但由於進行了盜鏈設定,可以直接使用7-2的ip地址訪問7-1內的圖片。

實現防盜鏈

Nginx防盜鏈主要是透過對請求的Referer頭部欄位進行檢查,如果請求不是從合法的來源(比如自己的網站)來的,Nginx會返回一個錯誤碼,通常是403 Forbidden。

  1. 編輯7-1的配置檔案;
點選檢視程式碼
rerfer你從哪裡跳轉過來的
設定有效值 來確定是否允許訪問我站點上的圖片

[root@node1 html]#  vim /apps/nginx/conf.d/pc.conf    //設定防盜鏈

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

    location ~* \.(jpg|gif|swf|jpeg|bmp)$ {       //開啟正則,匹配不區分大小寫,以.jpg或.gif或.swf結尾的檔案
    valid_referers none blocked *.pc.com pc.com;  //設定信任的網站,可以正常使用圖片。合法的refer:空、無效值或.pc.com結尾或pc.com
        if ( $invalid_referer ) {                 //如果為非法值,就返回403
       #rewrite ^/ http://www.pc.com/error.png;   //準備一個錯誤圖片返回
        return   403;
        }
    }
}

[root@node1 html]#  nginx -t           //檢查格式
[root@node1 html]#  nginx -s reload    //重新載入

2. 驗證:瀏覽器輸入7-2的ip192.168.204.20進行驗證;未顯示圖片,防盜鏈設定成功。

相關文章