Nginx重寫功能和反向代理的用法詳解
一、重寫功能rewrite
1. ngx_http_rewrite_module模塊指令
1.1 if 指令
用于條件匹配判斷,并根據(jù)條件判斷結(jié)果選擇不同的Nginx配置,可以配置在server或location塊中進(jìn)行配置,Nginx的if語法僅能使用if做單次判斷,不支持使用if else或者if elif這樣的多重判斷,用法如下:
if (條件匹配) { action }
使用正則表達(dá)式對變量進(jìn)行匹配,匹配成功時if指令認(rèn)為條件為true,否則認(rèn)為false,變量與表達(dá)式之間使用以下符號鏈接:
= #比較變量和字符串是否相等,相等時if指令認(rèn)為該條件為true,反之為false != #比較變量和字符串是否不相等,不相等時if指令認(rèn)為條件為true,反之為false ~ #區(qū)分大小寫字符,可以通過正則表達(dá)式匹配,滿足匹配條件為真,不滿足匹配條件為假 !~ #區(qū)分大小寫字符,判斷是否匹配,不滿足匹配條件為真,滿足匹配條件為假 ~* #不區(qū)分大小寫字符,可以通過正則表達(dá)式匹配,滿足匹配條件為真,不滿足匹配條件為假 !~* #不區(qū)分大小字符,判斷是否匹配,滿足匹配條件為假,不滿足匹配條件為真 -f 和 !-f #判斷請求的文件是否存在和是否不存在 -d 和 !-d #判斷請求的目錄是否存在和是否不存在 -x 和 !-x #判斷文件是否可執(zhí)行和是否不可執(zhí)行 -e 和 !-e #判斷請求的文件或目錄是否存在和是否不存在(包括文件,目錄,軟鏈接) #注意: #如果$變量的值為空字符串或0,則if指令認(rèn)為該條件為false,其他條件為true。 #nginx 1.0.1之前$變量的值如果以0開頭的任意字符串會返回false
示例:
① 修改子配置文件
[root@localhost conf.d]# vim pc.conf server { listen 80; root /data/; location / { if ( $scheme = http ) { #如果請求協(xié)議是http echo "if------->$scheme"; #則打印協(xié)議 } } } [root@localhost conf.d]# nginx -t [root@localhost conf.d]# nginx -s reload
② 訪問頁面
[root@localhost ~]# curl 192.168.190.102 if------->http
1.2 return 指令
return用于完成對請求的處理,并直接向客戶端返回響應(yīng)狀態(tài)碼,比如:可以指定重定向URL(對于特殊重定向狀態(tài)碼,301/302等) 或者是指定提示文本內(nèi)容(對于特殊狀態(tài)碼403/500等),處于此指令后的所有配置都將不被執(zhí)行,return可以在server、if 和 location塊進(jìn)行配置。
語法格式:
www.pc.com/test/ 404 return code; #返回給客戶端指定的HTTP狀態(tài)碼 return code [text]; #返回給客戶端的狀態(tài)碼及響應(yīng)報文的實體內(nèi)容,可以調(diào)用變量,其中text如果有空格,需要用單或雙引號 return code url; #返回給客戶端的URL地址
示例:
① 修改子配置文件
[root@localhost conf.d]# vim pc.conf server { listen 80; root /data/; location / { if (!-e $request_filename) { #如果訪問的頁面不存在 return 302 /index.html; #返回302,跳轉(zhuǎn)至主頁面 } } } [root@localhost conf.d]# nginx -t [root@localhost conf.d]# nginx -s reload
② 訪問不存在頁面,查看是否可以跳轉(zhuǎn)
[root@localhost ~]# curl 192.168.190.102/x <html> <head><title>302 Found</title></head> <body> <center><h1>302 Found</h1></center> <hr><center>nginx/1.18.0</center> </body> </html> [root@localhost ~]# curl 192.168.190.102/x -L welcome #-vL選項可以查看詳情信息
③ 當(dāng)然也可以跳轉(zhuǎn)至百度
return 302 http://www.baidu.com;
http狀態(tài)碼301和302區(qū)別?
301:永久重定向,讀取過一次就會將此條配置緩存在我們的客戶端,即使nginx服務(wù)器宕機(jī),在緩存時間內(nèi)還是可以跳轉(zhuǎn)
302:臨時重定向,不會有緩存在客戶端,每次跳轉(zhuǎn)需要nginx服務(wù)器解析,一旦服務(wù)器宕機(jī)就無法跳轉(zhuǎn)
302狀態(tài)碼宕機(jī)服務(wù)器查看詳情:
301狀態(tài)碼宕機(jī)服務(wù)器查看詳情:
server { listen 80; root /data/; location /test { default_type text/plain; return 301 /index.html; } }
1.3 set 指令
指定key并給其定義一個變量,變量可以調(diào)用Nginx內(nèi)置變量賦值給key,另外set定義格式為set $key value,value可以是text, variables和兩者的組合。
語法格式:
Syntax: set $variable value; Default: — Context: server, location, if
示例:
① 修改配置文件
server { listen 80; location / { set $name yun; echo $name; set $my_port $server_port; #將內(nèi)置變量定義給自定義變量 echo $my_port; } }
② 訪問頁面
[root@localhost ~]# curl 192.168.190.102 yun 80
1.4 break 指令
用于中斷當(dāng)前相同作用域(location)中的其他Nginx配置,與該指令處于同一作用域的Nginx配置中,位于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模塊中指令就不再執(zhí)行,Nginx服務(wù)器在根據(jù)配置處理請求的過程中遇到該指令的時候,回到上一層作用域繼續(xù)向下讀取配置,該指令可以在server塊和locationif塊中使用。
注意:如果break指令在location塊中后續(xù)指令還會繼續(xù)執(zhí)行只是不執(zhí)行 ngx_http_rewrite_module 模塊的指令,其它指令還會執(zhí)行。
2. rewrite 指令
通過正則表達(dá)式的匹配來改變URI,可以同時存在一個或多個指令,按照順序依次對URI進(jìn)行匹配,rewrite主要是針對用戶請求的URL或者是URI做具體處理。
rewrite可以配置在 server、location、if。語法格式:
rewrite可以配置在 server、location、if 語法格式 : rewrite regex replacement(www.baidu.com) [flag]; 正則匹配原始訪問url 替代的url鏈接 標(biāo)志 ()premanent301 redirect302 break last
rewrite將用戶請求的URI基于regex所描述的模式進(jìn)行檢查,匹配到時將其替換為表達(dá)式指定的新的URI。
注意:如果在同一級配置塊中存在多個rewrite規(guī)則,那么會自下而下逐個檢查;被某條件規(guī)則替換完成后,會重新一輪的替換檢查,隱含有循環(huán)機(jī)制,但不超過10次;如果超過,提示500響應(yīng)碼,[flag]所表示的標(biāo)志位用于控制此循環(huán)機(jī)制如果替換后的URL是以http://或https://開頭,則替換結(jié)果會直接以重定向返回給客戶端, 即永久重定向301。
正則表達(dá)式格式:
. #匹配除換行符以外的任意字符
\w #匹配字母或數(shù)字或下劃線或漢字
\s #匹配任意的空白符
\d #匹配數(shù)字 [0-9]
\b #匹配單詞的開始或結(jié)束
^ #匹配字付串的開始
$ #匹配字符串的結(jié)束
* #匹配重復(fù)零次或更多次
+ #匹配重復(fù)一次或更多次
? #匹配重復(fù)零次或一次
(n) #匹配重復(fù)n次
{n,} #匹配重復(fù)n次或更多次
{n,m} #匹配重復(fù)n到m次
*? #匹配重復(fù)任意次,但盡可能少重復(fù)
+? #匹配重復(fù)1次或更多次,但盡可能少重復(fù)
?? #匹配重復(fù)0次或1次,但盡可能少重復(fù)
{n,m}? #匹配重復(fù)n到m次,但盡可能少重復(fù)
{n,}? #匹配重復(fù)n次以上,但盡可能少重復(fù)
\W #匹配任意不是字母,數(shù)字,下劃線,漢字的字符
\S #匹配任意不是空白符的字符
\D #匹配任意非數(shù)字的字符
\B #匹配不是單詞開頭或結(jié)束的位置
[^x] #匹配除了x以外的任意字符
[^kgc] #匹配除了kgc 這幾個字母以外的任意字符
示例:
訪問 bj 跳轉(zhuǎn)到 beijing
① 修改配置文件
server { listen 80; server_name www.pc.com; root /data/; location /bj { rewrite ^/bj/(.*) /beijing/$1 permanent; } }
② 新建對應(yīng)文件夾及頁面文件
[root@localhost ~]# mkdir /data/beijing [root@localhost ~]# echo beijing nihao > /data/beijing/index.html
③ 訪問頁面bj
[root@localhost ~]# curl 192.168.190.102/bj/ -L beijing nihao #可以跳轉(zhuǎn)
整個網(wǎng)站重寫:
① 配置文件
server { listen 80; server_name www.pc.com; root /data/; location / { rewrite / http://www.baidu.com permanent; #如果訪問根就跳轉(zhuǎn)到百度 } }
② 訪問根查看是否跳轉(zhuǎn)百度
實戰(zhàn)案例:http轉(zhuǎn)https
① 配置文件
server { listen 80; listen 443 ssl; root /data/; ssl_certificate /data/ssl/www.kgc.com.crt; ssl_certificate_key /data/ssl/www.kgc.com.key; ssl_session_cache shared:sslcache:20m; ssl_session_timeout 10m; location / { if ( $scheme = http ) { #如果請求協(xié)議是http rewrite /(.*) https://$host/$1 permanent; #重寫成https } } }
② 訪問頁面
last 與 break:
location /break { #訪問break rewrite .* /test break; #重寫到test } location /last { #訪問break rewrite .* /test last; #重寫到test } location /test { rewrite 403; #last返回403,因為last會多次匹配 }
說明:
- redirect;302:臨時重定向,重寫完成后以臨時重定向方式直接返回重寫后生成的新URL給客戶端,由客戶端重新發(fā)起請求;使用相對路徑,或者h(yuǎn)ttp://或https://開頭,狀態(tài)碼:302
- permanent;301:重寫完成后以永久重定向方式直接返回重寫后生成的新URL給客戶端,由客戶端重新發(fā)起請求,狀態(tài)碼:301
- break:重寫完成后,停止對當(dāng)前URL在當(dāng)前l(fā)ocation中后續(xù)的其它重寫操作,而后直接跳轉(zhuǎn)至重寫規(guī)則配置塊之后的其它配置;結(jié)束循環(huán),建議在location中使用,適用于一個URL一次重寫
- last:重寫完成后,停止對當(dāng)前URI在當(dāng)前l(fā)ocation中后續(xù)的其它重寫操作,而后對新的URL啟動新一輪重寫檢查,不建議在location中使用。適用于一個URL多次重寫,要注意避免出現(xiàn)超過十次以及URL重寫后返回錯誤的給用戶301
其他示例:
案例1:更換目錄訪問方式,目錄轉(zhuǎn)化為對象存儲形式
要求:
/20200106/static->/static?id=20200106
/20200123/image ->/image?id=20200123
方法:
rewrite ^/(\d+)/(.+)/ /$2?id=$1 break;
\d+:一個以上數(shù)字;.+:一個以上的字符
案例2:多目錄轉(zhuǎn)換訪問方式
要求:
www.lucky.com/images/20200106/1.jpg => www.lucky.com/index.do?name=images&dir=20200106=&fi1e=1.jpg
規(guī)則配置:
if($host ~* (.*)\.lucky\.com) {
rewrite ^/(.*)/(\d+)/(.*)$ /index.do?name=$1&dir=$2&file=$3 last;}
3. 防盜鏈
防盜鏈基于客戶端攜帶的referer實現(xiàn),referer是記錄打開一個頁面之前記錄是從哪個頁面跳轉(zhuǎn)過來的標(biāo)記信息,如果別人只鏈接了自己網(wǎng)站圖片或某個單獨的資源,而不是打開了網(wǎng)站的整個頁面,這就是盜鏈,referer就是之前的那個網(wǎng)站域名,正常的referer信息有以下幾種:
- none:#請求報文首部沒有referer首部,比如用戶直接在瀏覽器輸入域名訪問web網(wǎng)站,就沒有referer信息。
- blocked:#請求報文有referer首部,但無有效值,比如為空。
- server_names:#referer首部中包含本主機(jī)名及即nginx 監(jiān)聽的server_name。
- arbitrary_string:#自定義指定字符串,但可使用*作通配符。示例: *.kgc.org www.kgc.*
- regular expression:#被指定的正則表達(dá)式模式匹配到的字符串,要使用~開頭,例如:~.*\.kgc\.com
3.1 實現(xiàn)盜鏈
① 被盜端添加文件a.jpg
[root@localhost data]# ls a.jpg beijing favicon.ico index.html ssl
② 盜取端開啟httpd服務(wù),添加web前端配置
[root@localhost ~]# cd /var/www/html/ <html> <body> <h1>ni hao </h1> <img src="http://192.168.190.102/a.jpg"/> #這里如果寫域名,需要修改hosts配置添加域名解析 </body> </html> [root@localhost html]# systemctl restart httpd
③ 訪問盜取端地址,可以直接獲得被盜端圖片
3.2 實現(xiàn)防盜鏈
① 配置文件
server{ listen 80; server_name www.pc.com; root /data; location ~* \.(jpg|gif|swf)$ { root /data/nginx/pc; valid_referers none blocked *.pc.com pc.com; if ( $invalid_referer ) { rewrite ^/ http://www.pc.com/error.png; } } }
② 再次訪問盜取端地址
③ 無法盜取圖片,狀態(tài)碼403
4. 實用網(wǎng)址
https://www.digitalocean.com/community/tools/nginx #自動生成nginx配置文件 https://github.com/agile6v/awesome-nginx/ #第三方模塊 https://www.runoob.com/lua/lua-tutorial.html #lua幫助 https://666666.dev/#/ #it人工具箱
二、反向代理
1. 概述
Nginx 反向代理是一種網(wǎng)絡(luò)通信方式,它允許 Nginx 服務(wù)器代表客戶端向其他服務(wù)器發(fā)送請求,并將收到的響應(yīng)返回給客戶端。這種代理方式隱藏了真實的服務(wù)器信息,提供了負(fù)載均衡、安全性和性能優(yōu)化等好處。
2. 相關(guān)概念
正向反向代理區(qū)別:
- 正向代理:代理客戶端去訪問服務(wù)器
- 反向代理:代理的是服務(wù)器
同構(gòu)代理和異構(gòu)代理:
- 同構(gòu)代理:客戶到至代理端和代理端至服務(wù)端使用請求協(xié)議一致
- 異構(gòu)代理:客戶到至代理端和代理端至服務(wù)端使用請求協(xié)議不一致
3. 反向代理模塊
ngx_http_proxy_module: #將客戶端的請求以http協(xié)議轉(zhuǎn)發(fā)至指定服務(wù)器進(jìn)行處理 ngx_http_upstream_module #用于定義為proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服務(wù)器分組 ngx_stream_proxy_module:#將客戶端的請求以tcp協(xié)議轉(zhuǎn)發(fā)至指定服務(wù)器處理 ngx_http_fastcgi_module:#將客戶端對php的請求以fastcgi協(xié)議轉(zhuǎn)發(fā)至指定服務(wù)器助理 ngx_http_uwsgi_module: #將客戶端對Python的請求以uwsgi協(xié)議轉(zhuǎn)發(fā)至指定服務(wù)器處理
4. 參數(shù)配置
proxy_pass; #用來設(shè)置將客戶端請求轉(zhuǎn)發(fā)給的后端服務(wù)器的主機(jī),可以是主機(jī)名(將轉(zhuǎn)發(fā)至后端服務(wù)做為主機(jī)頭首部)、IP 地址:端口的方式 #也可以代理到預(yù)先設(shè)置的主機(jī)群組,需要模塊ngx_http_upstream_module支持
5. 示例
5.1 反向代理單臺web服務(wù)器,實現(xiàn)單臺反向代理。
客戶端:192.168.190.101,服務(wù)器:192.168.190.100;代理服務(wù)器:192.168.190.102
① 代理服務(wù)器配置文件
server{ listen 80; server_name www.pc.com; root /data; location / { proxy_pass http://192.168.190.100; #訪問本機(jī)的根等于訪問指定地址 } }
② 客戶端開啟httpd服務(wù)
[root@localhost html]# cat index.html <html> <body> <h1>ni hao </h1> </body> </html>
③ 客戶端訪問代理服務(wù)器
[root@localhost ~]# curl 192.168.190.102 <html> <body> <h1>ni hao </h1> </body> </html>
在真實服務(wù)器上做防火墻規(guī)則:
丟棄:
① 服務(wù)端添加防火墻規(guī)則
iptables -A INPUT -s 192.168.190.102 -j DROP #客戶端再次訪問會出現(xiàn)504網(wǎng)關(guān)超時(有可能只是處理時間久,服務(wù)器不一定掛了),時間較長1分鐘,沒有定義代理超時時間
② 客戶端訪問代理服務(wù)器
[root@localhost ~]# curl 192.168.190.102 -I HTTP/1.1 504 Gateway Time-out Server: nginx/1.18.0 Date: Mon, 26 Feb 2024 10:50:47 GMT Content-Type: text/html Content-Length: 167 Connection: keep-alive #提示504超時
拒絕:
① 服務(wù)器修改防火墻規(guī)則
[root@localhost html]# iptables -R INPUT 1 -s 192.168.190.102 -j REJECT #客戶端再次訪問,會出現(xiàn)502,一般出現(xiàn)502代表后端真實服務(wù)器掛了
② 客戶端訪問代理服務(wù)器
[root@localhost ~]# curl 192.168.190.102 -I HTTP/1.1 502 Bad Gateway Server: nginx/1.18.0 Date: Mon, 26 Feb 2024 10:55:15 GMT Content-Type: text/html Content-Length: 157 Connection: keep-alive
針對某個uri 進(jìn)行訪問:
要求:將用戶對域www.pc.com的請求轉(zhuǎn)發(fā)給后端服務(wù)器處理
① 代理端配置文件
server{ listen 80; server_name www.pc.com; root /data; location ~* /api { #只要包含api的都替換成192.168.190.100 proxy_pass http://192.168.190.100; } } http://192.168.91.101 不加/ 是將location上的url追加在后面 http://192.168.91.101/ 加上/ 是將1ocation上的url替換后proxy配置里的連接
5.2 指定location實現(xiàn)反向代理動靜分離
環(huán)境:動態(tài)服務(wù)器7-0:192.168.190.100;靜態(tài)服務(wù)器7-1:192.168.190.101;代理服務(wù)器:192.168.190.102;客戶端:192.168.190.103
① 兩臺服務(wù)器分別開啟httpd服務(wù),新建對應(yīng)web文件
192.168.190.100 7-0: [root@localhost ~]# cd /var/www/html/ [root@localhost html]# mkdir api [root@localhost html]# echo dongtai 7-0 > api/index.html 192.1681.190.101 7-1: [root@localhost ~]# cd /var/www/html/ [root@localhost html]# echo jingtai 7-1 > index.html [root@localhost html]# ls a.jpg index.html
② 代理服務(wù)器配置文件
server { listen 80; server_name www.pc.com; root /data; location ~* /api { proxy_pass http://192.168.190.100; #訪問代理的api的url就跳轉(zhuǎn)到http://192.168.190.100/api/index.html } location ~* \.(jpg|jpeg|png|gif|bmp)$ { proxy_pass http://192.168.190.101; #訪問以這些結(jié)尾的文件,代理地址/a.jpg,那么就去http://192.168.190.101/a.jpg } }
訪問192.168.190.102/a.jpg轉(zhuǎn)到訪問192.168.190.101/a.jpg:
6. 緩存功能
緩存功能可以加速訪問,如果沒有緩存關(guān)閉后端服務(wù)器后,圖片將無法訪問,緩存功能默認(rèn)關(guān)閉,需要開啟。
相關(guān)選項:
proxy_cache zone_name | off; 默認(rèn)off #指明調(diào)用的緩存,或關(guān)閉緩存機(jī)制;Context:http, server, location #zone_name 表示緩存的名稱.需要由proxy_cache_path事先定義
操作示例:為代理服務(wù)器開啟緩存功能
① 主配置文件的http模塊中添加配置
[root@localhost ~]# vim /apps/nginx/conf/nginx.conf proxy_cache_path /data/nginx/proyxcache levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g; #開啟緩存 緩存路徑 生成文件夾比例是3級 從內(nèi)存中借調(diào)20M專門存放緩存 有效期120秒 最大存儲空間為1g [root@localhost ~]# mkdir /data/nginx/ [root@localhost ~]# nginx -t
② 子配置文件添加配置
[root@localhost ~]# vim /apps/nginx/conf.d/pc.conf server { listen 80; server_name www.pc.com; root /data/; proxy_cache proxycache; proxy_cache_key $request_uri; #對指定的數(shù)據(jù)進(jìn)行MD5的運(yùn)算做為緩存的key #proxy_cache_key $host$uri$is_args$args; proxy_cache_valid 200 302 301 10m; #指定的狀態(tài)碼返回的數(shù)據(jù)緩存多長時間 proxy_cache_valid any 5m; #除指定的狀態(tài)碼返回的數(shù)據(jù)以外的緩存多長時間,必須設(shè)置,否則不會緩存 location ~* /api { proxy_pass http://192.168.190.100; } location ~* \.(jpg|jpeg|png|gif|bmp)$ { proxy_pass http://192.168.190.101; } } [root@localhost ~]# nginx -t [root@localhost ~]# nginx -s reload
③ 訪問代理端
④ 查看緩存內(nèi)容
[root@localhost proyxcache]# tree /data/nginx/proyxcache/ /data/nginx/proyxcache/ └── a └── 2 └── 4 └── 9dd678f60ef22cf1fc31474b6abac42a 3 directories, 1 file
⑤ 關(guān)閉服務(wù)端,再次訪問
7. 自定義添加響應(yīng)報文頭部信息
① 添加子配置
server { listen 80; server_name www.pc.com; root /data/; proxy_cache proxycache; proxy_cache_key $request_uri; #proxy_cache_key $host$uri$is_args$args; proxy_cache_valid 200 302 301 10m; proxy_cache_valid any 5m; add_header ip $server_addr; #當(dāng)前nginx主機(jī)ip add_header status $upstream_cache_status; #是否緩存命中,hit命中,miss未命中 add_header name $server_name; #客戶端訪問的FQDN location ~* /api { proxy_pass http://192.168.190.100; } location ~* \.(jpg|jpeg|png|gif|bmp)$ { proxy_pass http://192.168.190.101; } }
② 查看新增頭部字段信息
[root@localhost html]# curl 192.168.190.102/a.jpg -I HTTP/1.1 200 OK Server: nginx/1.18.0 Date: Tue, 27 Feb 2024 07:16:10 GMT Content-Type: image/jpeg Content-Length: 62447 Connection: keep-alive Last-Modified: Mon, 26 Feb 2024 15:46:56 GMT ETag: "f3ef-6124ad1bd7c00" ip: 192.168.190.102 status: HIT name: www.pc.com Accept-Ranges: bytes
以上就是Nginx重寫功能和反向代理的用法詳解的詳細(xì)內(nèi)容,更多關(guān)于Nginx重寫功能和反向代理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
深入探究Nginx體系化之虛擬主機(jī)分類及配置實現(xiàn)
Nginx,這款備受推崇的高性能 Web 服務(wù)器,以其強(qiáng)大的性能和靈活的配置而廣受歡迎,在實際應(yīng)用中,虛擬主機(jī)是一項重要的功能,允許我們在單個服務(wù)器上托管多個網(wǎng)站,本文將深入探討 Nginx 虛擬主機(jī)的分類和配置實現(xiàn),幫助您構(gòu)建一個高效多站點托管平臺2023-08-08解決httpd占用80端口導(dǎo)致Nginx啟動失敗報錯的解決辦法
今天在建自己小網(wǎng)站時啟動Nginx時,發(fā)現(xiàn)其報下列錯誤,意思是因為80端口被占用導(dǎo)致Nginx啟動失敗,所以本文小編給大家介紹介紹如何解決解決httpd占用80端口導(dǎo)致Nginx啟動不成功報nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)2023-11-11