目錄
一、正向代理和反向代理
1.1 正向代理概述
1.1.1 什么是正向代理
1.1.2 正向代理的作用
1.1.3 正向代理的基本格式
1.2 反向代理概述
1.2.1 什么是反向代理
1.2.2 反向代理可實現的功能
1.2.3 反向代理的可用模塊
二、配置反向代理
2.1 反向代理配置參數
2.1.1 proxy_pass
2.1.2 其他參數
三、配置實戰
3.1 反向代理單臺web服務器
3.2 指定主機實現反向代理動靜分離
3.3 緩存功能
3.4 實現反向代理客戶端IP透傳
3.4.1 基本原理
3.4.2 一級代理?編輯
3.4.3 多級代理
3.5 實現反向代理負載均衡
3.5.1 基本原理
3.5.2 常見配置參數
3.5.2 調度算法
3.5.2.1 輪詢(Round Robin)
3.5.2.2 輪詢權值(Weighted Round Robin)
3.5.2.3 ip_hash (source hash)
3.5.2.4 fair(第三方)
3.5.2.5 url_hash(第三方)
3.5.2.6 least_conn(最小連接數)
3.5.2.7 最少響應時間(Least Time)
3.6 實戰
3.6.1 使用輪詢算法實現負載均衡
3.6.2 使用加權輪詢算法實現負載均衡
四、 Nginx配置跨域 CORS
4.1 跨域的定義
4.2 同源的定義
4.3 不同源的限制
4.4 Nginx 解決跨域的原理
4.5 案例
五、Nginx防盜鏈設置
5.1 什么是盜鏈
5.2 Referer解析
5.3 配置防盜鏈案例
5.4 測試
一、正向代理和反向代理
1.1 正向代理概述
1.1.1 什么是正向代理
正向代理代理的是客戶端
正向代理是一個位于客戶端和目標服務器之間的代理服務器(中間服務器)。為了從目標服務器取得內容,客戶端向代理服務器發送一個請求,并且指定目標服務器,之后代理向目標服務器轉發請求,將獲得的內容返回給客戶端
1.1.2 正向代理的作用
-
為在防火墻內的局域網客戶端提供訪問Internet的途徑
-
可以使用緩沖特性減少網絡使用率
-
訪問受地理位置限制的網絡
-
使用代理后會隱藏真實的IP地址
1.1.3 正向代理的基本格式
server {listen 192.164.65.100:80;server_name ....;#客戶端訪問的域名
?location / {proxy_pass http://目標服務器地址;}}
1.2 反向代理概述
1.2.1 什么是反向代理
反向代理代理的是服務端
反向代理:(reverse proxy),指的是代理外網用戶的請求到內部的指定的服務器,并將數據返回給用戶的一種方式 客戶端不直接與后端服務器進行通信,而是與反向代理服務器進行通信,隱藏了后端服務器的 IP 地址
1.2.2 反向代理可實現的功能
反向代理的主要作用是提供負載均衡和高可用性。
負載均衡:Nginx可以將傳入的請求分發給多個后端服務器,以平衡服務器的負載,提高系統性能和可靠性。
緩存功能:Nginx可以緩存靜態文件或動態頁面,減輕服務器的負載,提高響應速度。
動靜分離:將動態生成的內容(如 PHP、Python、Node.js 等)和靜態資源(如 HTML、CSS、JavaScript、圖片、視頻等)分別存放在不同的服務器或路徑上。
多站點代理:Nginx可以代理多個域名或虛擬主機,將不同的請求轉發到不同的后端服務器上,實現多個站點的共享端口。
1.2.3 反向代理的可用模塊
ngx_http_proxy_module: #將客戶端的請求以http協議轉發至指定服務器進行處理
?
ngx_http_upstream_module #用于定義為proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服務器分組
?
ngx_stream_proxy_module:#將客戶端的請求以tcp協議轉發至指定服務器處理
?
ngx_http_fastcgi_module:#將客戶端對php的請求以fastcgi協議轉發至指定服務器助理
?
ngx_http_uwsgi_module: #將客戶端對Python的請求以uwsgi協議轉發至指定服務器處理
二、配置反向代理
#官方文檔:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
2.1 反向代理配置參數
2.1.1 proxy_pass
proxy_pass 地址:端口的方式 ; ?
#用來設置將客戶端請求轉發給的后端服務器的主機,可以是主機名(將轉發至后端服務做為主機頭首部)、IP
#也可以代理到預先設置的主機群組,需要模塊ngx_http_upstream_module支持
proxy_pass http://10.0.0.18:8080;
#8080后面無uri,即無 / 符號,需要將location后面url 附加到proxy_pass指定的url后面,此行為類似于root
#proxy_pass指定的uri不帶斜線將訪問的/web,等于訪問后端服務器
?
proxy_pass http://10.0.0.18:8080/; ?
#8080后面有uri,即有 / 符號,相當于置換,即訪問/web時實際返回proxy_pass后面uri內容.此行為類似于alias
#proxy_pass指定的uri帶斜線,等于訪問后端服務器的http://10.0.0.18:8080/index.html 內容返回給客戶端
#如果location定義其uri時使用了正則表達式模式(包括~,~*,但不包括^~),則proxy_pass之后必須不能使用uri; 即不能有/ ,用戶請求時傳遞的uri將直接附加至后端服務器之后
2.1.2 其他參數
proxy_hide_header field;
#用于nginx作為反向代理的時候,在返回給客戶端http響應時,隱藏后端服務器相應頭部的信息,可以設置proxy_hide_header field;
?
proxy_pass_header field;
#默認nginx在響應報文中不傳遞后端服務器的首部字段Date, Server, X-Pad, X-Accel等參數,如果要傳遞的話則要使用 proxy_pass_header field聲明將后端服務器返回的值傳遞給客戶端
?
#field 首部字段大小不敏感
#示例:透傳后端服務器的Server和Date首部給客戶端,同時不再響應報中顯示前端服務器的Server字段
proxy_pass_header Server;
proxy_pass_header Date;
?
?
proxy_pass_request_body on | off;
#是否向后端服務器發送HTTP實體部分,可以設置在http,server或location塊,默認即為開啟
?
?
proxy_pass_request_headers on | off;
#是否將客戶端的請求頭部轉發給后端服務器,可以設置在http,server或location塊,默認即為開啟
三、配置實戰
3.1 反向代理單臺web服務器
所需配置
#代理服務器
vim /apps/nginx/conf.d/pc.conf
#編輯子配置文件
server{listen 192.164.65.100:80;server_name www.pc.com;root ? /apps/nginx/html/pc;location / {proxy_pass http://192.164.65.101;
}
?
}
nginx -t
nginx -s reload
#重新加載
#真實服務端
yum install ? httpd ?-y #安裝服務
?
cd /var/www/html
echo ? "Hi~" > index.html #主頁內容
?
systemctl start httpd #開啟服務
?
vim /etc/hosts
#添加地址映射
?
192.164.65.100 www.pc.com
#客戶機
?
vim /etc/hosts
192.164.65.100 www.pc.com
測試
客戶機訪問代理服務器curl 192.164.65.100
3.2 指定主機實現反向代理動靜分離
因為nginx無法處理動態資源,所以要動靜分離。
所需配置
#代理服務器
?
vim /apps/nginx/conf.d/pc.conf
#編輯子配置文件
?location /api {proxy_pass http://192.164.65.101;
}
?location /static {proxy_pass http://192.164.65.103;
}
nginx -t
nginx -s reload
#重新加載
#動態資源服務器
?
#關閉防火墻和selinux
systemctl stop firewalld
setenforce 0
?
#安裝nginx服務
yum install -y epel-release
yum install nginx -y
systemctl start nginx
?
#創建動態資源目錄
cd /usr/share/nginx/html
?
mkdir api
echo this is api > ./api/index.html
#靜態資源服務器
?
#關閉防火墻和selinux
systemctl stop firewalld
setenforce 0
?
#安裝服務
yum install -y epel-release
yum install nginx -y
systemctl start nginx
?
#創建靜態資源目錄
cd /usr/share/nginx/html
mkdir static
echo this is static > ./static/index.html
測試
#客戶機
#關閉防火墻和selinux
systemctl stop firewalld
setenforce 0
?
#動態資源
curl 192.164.65.100/api -L
?
#靜態資源
curl 192.164.65.100/static -L
?
3.3 緩存功能
反向代理可以緩存靜態資源。
當客戶端再次請求訪問相同資源時,反向代理可以直接返回緩存中的響應,無需二次請求,減少對后端服務器的請求壓力,并加快響應速度。
proxy_cache zone_name on | off; 默認off
#指明調用的緩存,或關閉緩存機制;Context:http, server, location
#zone_name 表示緩存的名稱.需要由proxy_cache_path事先定義
proxy_cache_key string;
#緩存中用于“鍵”的內容,默認值:proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time;
#定義對特定響應碼的響應內容的緩存時長,定義在http{...}中示例:proxy_cache_valid 200 302 10m;proxy_cache_valid 404 1m;proxy_cache_path;
#定義可用于proxy功能的緩存;Context:http ? 必須放在http語句中
proxy_cache_path path [levels=levels] [use_temp_path=on|off]
keys_zone=zone_name:size [inactive=time] [max_size=size] [manager_files=number]
[manager_sleep=time] [manager_threshold=time] [loader_files=number]
[loader_sleep=time] [loader_threshold=time] [purger=on|off]
[purger_files=number] [purger_sleep=time] [purger_threshold=time];
?
?
#示例:在http配置定義緩存信息proxy_cache_path /var/cache/nginx/proxy_cache #定義緩存保存路徑,proxy_cache會自動創建levels=1:2:2 #定義緩存目錄結構層次,1:2:2可以生成2^4x2^8x2^8=2^20=1048576個目錄keys_zone=proxycache:20m #指內存中緩存的大小,主要用于存放key和metadata(如:使用次數),一般1M可存放8000個左右的keyinactive=120s ?#緩存有效時間 ?max_size=10g; #最大磁盤占用空間,磁盤存入文件內容的緩存空間最大值#調用緩存功能,需要定義在相應的配置段,如server{...};或者location等
proxy_cache proxycache;
proxy_cache_key $request_uri; #對指定的數據進行MD5的運算做為緩存的key
proxy_cache_valid 200 302 301 10m; #指定的狀態碼返回的數據緩存多長時間
proxy_cache_valid any 1m; ? #除指定的狀態碼返回的數據以外的緩存多長時間,必須設置,否則不會緩存
?
?
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默認是off
#在被代理的后端服務器出現哪種情況下,可直接使用過期的緩存響應客戶端
?
#示例
proxy_cache_use_stale error http_502 http_503;
?
?
proxy_cache_methods GET | HEAD | POST ...;
#對哪些客戶端請求方法對應的響應進行緩存,GET和HEAD方法總是被緩存
proxy_cache_path /data/nginx/proyxcache ? levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;
?
?
#http 語句
#1:1:1 16個二進制 ? ? 2^16/2^16/2^16 ? ? ? 2^48
?
?
server {listen 80;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;server_name www.kgc.com;root /data/nginx/pc;location / {root /data/nginx/pc;}location /api {proxy_pass http://192.164.91.101:9527;}location ~* \.(jpg|png|gif|html)$ {proxy_pass http://192.164.91.102;}
}
清理緩存
方法1: rm -rf 緩存目錄
方法2: 第三方擴展模塊ngx_cache_purge
3.4 實現反向代理客戶端IP透傳
3.4.1 基本原理
反向代理客戶端IP透傳是指在使用反向代理服務器時,將客戶端的真實IP地址傳遞給后端服務器。
這可以通過一些特定的 如X-Forwarded-For
等HTTP 頭字段來實現 頭字段。
當請求經過反向代理服務器時,代理服務器會將客戶端的真實IP地址添加到 XFF 頭字段中,然后轉發給后端服務器。
后臺服務端開啟main日志格式調用!!!
3.4.2 一級代理
所需配置
#代理服務器
?
vim /apps/nginx/conf.d/pc.conf
#編輯子配置文件
server{listen 192.164.65.100:80;server_name www.pc.com;root ? /apps/nginx/html/pc;location / {proxy_pass http://192.164.65.101;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
?
}
?
######
`$proxy_add_x_forwarded_for` 是一個 nginx 變量,用于獲取客戶端的真實 IP 地址并將其添加到請求中的 `X-Forwarded-For` 頭字段中,后端服務器可以通過檢查該頭字段來獲取請求的真實客戶端 IP 地址。
#后端服務器
?
#關閉防火墻和selinux
systemctl stop firewalld
setenforce 0
?
#安裝服務
yum install -y epel-release #依賴
yum install nginx -y
systemctl start nginx
測試
#客戶端
curl 192.164.65.100
#后端服務器
cat /var/log/nginx/access.log |tail -f -n2
3.4.3 多級代理
所需配置
#一級代理服務器
?
#編輯子配置文件
vim /apps/nginx/conf.d/pc.conf
#反向代理指向二級代理服務器的IP
?
nginx -t
nginx -s reload
#重新加載
#yum安裝nginx
yum install -y epel-release
yum install nginx -y
?
systemctl start nginx
?
vi /etc/nginx/nginx.conf
#編輯主配置文件
?
server {
location / {
proxy_pass http://192.164.65.102;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
?
systemctl restart nginx
#重新加載
#后端服務器
?
#關閉防火墻和selinux
systemctl stop firewalld
setenforce 0
?
#安裝nginx服務
yum install -y epel-release
yum install nginx -y
systemctl start nginx
測試
#客戶端,訪問代理服務器
curl 192.164.2.100
#后端服務器,查看日志
cat /var/log/nginx/access.log | tail -n -1
3.5 實現反向代理負載均衡
Nginx 可以基于ngx_http_upstream_module
模塊提供服務器分組轉發、權重分配、狀態監測、調度算法等高級功能
#官方文檔:
https://nginx.org/en/docs/http/ngx_http_up
3.5.1 基本原理
NGINX的負載均衡原理是基于反向代理和事件驅動的機制。
當客戶端發送請求時,NGINX作為反向代理服務器接收請求,并根據配置的負載均衡算法
將請求轉發到后端的多個服務器上,實現負載均衡。
3.5.2 常見配置參數
server address [parameters];
#配置一個后端web服務器,配置在upstream內,至少要有一個server服務器配置。
#server支持的parameters如下:
?
weight=number #設置權重,默認為1,實現類似于LVS中的WRR,WLC等
?
max_conns=number ?#給當前后端server設置最大活動鏈接數,默認為0表示沒有限制
?
max_fails=number ?#后端服務器的下線條件,當客戶端訪問時,對本次調度選中的后端服務器連續進行檢測多少次,如果都失敗就標記為不可用,默認為1次,當客戶端訪問時,才會利用TCP觸發對探測后端服務器健康性檢查,而非周期性的探測
?
fail_timeout=time #后端服務器的上線條件,對已經檢測到處于不可用的后端服務器,每隔此時間間隔再次進行檢測是否恢復可用,如果發現可用,則將后端服務器參與調度,默認為10秒
?
sorry server ? #自己不能轉自己
down ? ?#標記為down狀態
resolve #當server定義的是主機名的時候,當A記錄發生變化會自動應用新IP而不用重啟Nginx
backup ?#設置為備份服務器,當所有后端服務器不可用時,才會啟用此備用服務器
?
upstream backend {server backend1.example.com;server backend2.example.com backup;server backend3.example.com;
}
3.5.2 調度算法
3.5.2.1 輪詢(Round Robin)
每個請求按時間順序逐一分配到不同的后端服務,如果后端某臺服務器死機,自動剔除故障系統,使用戶訪問不受影響。
#示例
upstream bakend { ?server 192.164.65.1; ? ?server 192.164.65.2; ?
}
3.5.2.2 輪詢權值(Weighted Round Robin)
weight的值越大分配到的訪問概率越高,主要用于后端每臺服務器性能不均衡的情況下。或者僅僅為在主從的情況下設置不同的權值,達到合理有效的地利用主機資源。
指定輪詢幾率,weight和訪問比率成正比,用于后端服務器性能不均的情況。
#示例
upstream bakend { ?server 192.164.65.1 weight=10; ?server 192.164.65.2 weight=20; ?
}
3.5.2.3 ip_hash (source hash)
每個請求按訪問IP的哈希結果分配,使來自同一個IP的訪客固定訪問一臺后端服務器,并且可以有效解決動態網頁存在的session共享問題。
每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個后端服務器,可以解決session的問題。
#示例
upstream bakend { ?ip_hash; ?server 192.164.65.1:88; ?server 192.164.65.2:80; ?
}
3.5.2.4 fair(第三方)
比 weight、ip_hash更加智能的負載均衡算法,fair算法可以根據頁面大小和加載時間長短智能地進行負載均衡,也就是根據后端服務器的響應時間 來分配請求,響應時間短的優先分配。
Nginx本身不支持fair,如果需要這種調度算法,則必須安裝upstream_fair
模塊。
按后端服務器的響應時間來分配請求,響應時間短的優先分配。
upstream backend { ?server 192.164.0.67:88; ?server 192.164.0.67:80; ?fair; ?
}
3.5.2.5 url_hash(第三方)
按訪問的URL的哈希結果來分配請求,使每個URL定向到一臺后端服務器,可以進一步提高后端緩存服務器的效率。
Nginx本身不支持url_hash,如果需要這種調度算法,則必須安裝Nginx的hash軟件包。
按訪問url的hash結果來分配請求,使每個url定向到同一個后端服務器,后端服務器為緩存時比較有效。
upstream backend { ?server 192.164.65.1:88; ?server 192.164.65.2:80; ?hash $request_uri; ?hash_method crc32; ?
}
?
#注:在upstream中加入hash語句,server語句中不能寫入weight等其他的參數,hash_method是使用的hash算法。
3.5.2.6 least_conn(最小連接數)
根據后端服務器的連接狀況進行分配客戶請求,連接最少的服務器將被有限分配客戶端請求。
#示例upstream backend {least_conn;server backend1.example.com;server backend2.example.com;}
3.5.2.7 最少響應時間(Least Time)
根據服務器的響應時間進行選擇,將請求分配給響應時間最短的服務器。
3.6 實戰
要啟用負載均衡,需要在Nginx主配置文件中添加一個upstream塊
來定義后端服務器的列表。
然后,在相應的location塊
中使用proxy_pass
指令指定負載均衡的上游服務器。
3.6.1 使用輪詢算法實現負載均衡
所需配置
#代理服務器
?
vim /apps/nginx/conf/nginx.conf
#編輯主配置文件
?
upstream group1{server 192.164.65.102;server 192.164.65.103;}
vim /apps/nginx/conf.d/pc.com
#修改子配置文件
#修改location部分,加入pass_proxy http://group1;
?
nginx -t
nginx -s reload
#重新加載
測試
#修改102、103主頁文件
vi /usr/share/nginx/html/index.html
#轉到客戶端
curl 192.164.65.100 ? #x2
3.6.2 使用加權輪詢算法實現負載均衡
所需配置
#代理服務器
?
#修改主配置文件
vim /apps/nginx/conf/nginx.conf
?
upstream group1{server 192.164.65.102 weight=2;server 192.164.65.103 weight=3;
}
nginx -t
nginx -s reload
#重新加載
測試
#轉到客戶端
curl 192.164.65.100 ? #x2
四、 Nginx配置跨域 CORS
4.1 跨域的定義
同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互。這是一個用于隔離潛在惡意文件的重要安全機制。通常不允許不同源間的讀操作。
4.2 同源的定義
如果兩個頁面的協議,端口(如果有指定)和域名都相同,則兩個頁面具有相同的源。
與 URL http://store.company.com/dir/page.html 的源進行對比的示例:
-
http://store.company.com/dir2/other.html 同源
-
https://store.company.com/secure.html 不同源,協議不同
-
http://store.company.com:81/dir/etc.html 不同源,端口不同
-
http://news.company.com/dir/other.html 不同源,主機不同
4.3 不同源的限制
-
Web 數據層面,同源策略限制了不同源的站點讀取當前站點的 Cookie 、 IndexDB 、 LocalStorage 等數據;
-
DOM 層面,同源策略限制了來自不同源的 JavaScript 腳本對當前 DOM 對象讀和寫的操作;
-
網絡層面,同源策略限制了通過 XMLHttpRequest 等方式將站點的數據發送給不同源的站點。
4.4 Nginx 解決跨域的原理
瀏覽器的同源策略限制了跨域請求,但當使用 Nginx 作為代理服務器時,瀏覽器發送的請求實際上是發送到與前端頁面同源的 Nginx 服務器。然后 Nginx 將請求轉發到真正的目標服務器,目標服務器返回的響應再通過 Nginx 返回給瀏覽器。從瀏覽器的角度看,它只與同源的 Nginx 服務器進行交互,從而繞過了 CORS 限制
4.5 案例
前端 server 的域名為:fe.server.com
后端服務的域名為:dev.server.com
現在在 fe.server.com 對 dev.server.com 發起請求一定會出現跨域。
現在我們只需要啟動一個 Nginx 服務器,將 server_name 設置為 fe.server.com 然后設置相應的 location 以攔截前端需要跨域的請求,最后將請求代理回 dev.server.com 。
如下面的配置:
server {listen ? ? ? ?80;server_name fe.server.com;location / {proxy_pass dev.server.com;proxy_set_cookie_domain target-domain.com your-domain.com;proxy_set_header Host target-domain.com;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# 可選的配置,用于處理響應頭proxy_set_header Access-Control - Allow - Origin http://fe.server.com;proxy_set_header Access-Control - Allow - Methods GET,POST,PUT,DELETE;proxy_set_header Access-Control - Allow - Headers Content - Type,Authorization;}
}
?
配置解析:
-
proxy_set_header
-
Host backend - domain.com:設置轉發請求的Host頭信息。這是因為后端服務器可能會根據Host頭來區分不同的虛擬主機或服務,所以需要將正確的Host信息傳遞給后端服務器,使其能夠正確處理請求。
-
X-Real-IP $remote_addr和X-Forwarded-For $proxy_add_x_forwarded_for:這兩個指令用于傳遞客戶端的真實 IP 地址。$remote_addr是 Nginx 記錄的客戶端 IP 地址,$proxy_add_x_forwarded_for是一個包含了客戶端 IP 以及中間代理服務器 IP(如果有的話)的變量。這樣后端服務器可以獲取到正確的客戶端 IP 信息,用于日志記錄、訪問控制等目的。
-
Origin http://frontend - domain.com:這是關鍵的一個設置,用于在轉發請求時,將Origin頭信息設置為前端頁面的域名。后端服務器在收到這個請求時,會認為請求來自于同源的http://frontend - domain.com,從而避免了 CORS 限制。這樣后端服務器就可以正常處理請求并返回響應,響應會通過 Nginx 再返回給瀏覽器。
-
proxy_set_header Access-Control - Allow - Origin
這個指令用于在 Nginx 作為代理服務器返回響應時,設置Access - Control - Allow - Origin響應頭。通過將其設置為前端頁面的域名(http://frontend - domain.com),瀏覽器會認為這個響應是來自同源的服務器,從而允許前端 JavaScript 代碼訪問這個響應,有效地繞過了 CORS 限制。
-
proxy_set_header Access-Control - Allow - Methods
用于設置Access - Control - Allow - Methods響應頭,指定允許的 HTTP 請求方法。在這里列舉了GET、POST、PUT和DELETE,表示后端服務器允許前端通過這些方法進行跨域請求。可以根據實際的后端 API 支持的方法進行調整。
-
proxy_set_header Access-Control - Allow - Headers
設置Access - Control - Allow - Headers響應頭,指定允許的請求頭。Content - Type頭通常用于指定請求或響應的內容類型,如application/json或text/plain等;Authorization頭用于傳遞認證信息,如令牌或用戶名 / 密碼等。這確保了前端在跨域請求中可以發送這些必要的請求頭,并且后端會認可這些請求頭。
-
這樣可以完美繞過瀏覽器的同源策略:fe.server.com 訪問 Nginx 的 fe.server.com 屬于同源訪問,而 Nginx 對服務端轉發的請求不會觸發瀏覽器的同源策略。
五、Nginx防盜鏈設置
5.1 什么是盜鏈
-
在實際生產過程中,我們線上的圖片等靜態資源,經常會被其他網站盜用,他們發大財的同時,成本確實我們在買單,下面來說下,如何杜絕這種行為。
-
應該說只要是靜態資源都是可以防盜鏈的,只需要在Server字段加上幾行代碼即可。眾所周知網站出名了后,會有各種刁民來找茬的,最常見的就是爬你網站的東西。
-
關于防盜鏈這里不得不提一下網頁的加載順序是先加載HTML相關的內容,然后解析HTML的內容,那些需要加載圖片,那些需要加載文件,是逐步加載的,所以可以在加載靜態資源的時候做防盜鏈的操作,例如:在加載圖片的時候直接跳轉去其他鏈接,或者直接返回404,403等錯誤代碼,拒絕它的請求。
如何區分哪些是不正常的用戶?
-
HTTP Referer是Header的一部分,當瀏覽器向Web服務器發送請求的時候,一般會帶上Referer,告訴服務器我是從哪個頁面鏈接過來的,服務器借此可以獲得一些信息用于處理,例如防止未經允許的網站盜鏈圖片、文件等。因此HTTP Referer頭信息是可以通過程序來偽裝生成的,所以通過Referer信息防盜鏈并非100%可靠,但是,它能夠限制大部分的盜鏈情況.
-
比如在www.google.com 里有一個 www.baidu.com 鏈接,那么點擊這個www.baidu.com ,它的header 信息里就有:Referer=http://www.google.com
5.2 Referer解析
-
HTTP 協議中有一個用來表示“頁面或資源”來源的“請求頭”,這個請求頭叫做 Referer --> Referer是表示請求是從哪個網址發出的防盜鏈功能基于HTTP協議支持的 Referer 機制,通過Referer跟蹤來源,對來源進行識別和判斷
5.3 配置防盜鏈案例
為了模擬盜鏈,讓192.168.166.9為網站服務站點,192.168.166.10訪問192.168.166.9進行盜鏈。
修改Nginx的字符集以支持中文:
charset utf-8;
修改 192.168.166.10 Nginx 默認訪問文件:<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>產生盜鏈</title>
</head>
<body><a href='http://192.168.166.9/photos/1.png'>站點</a>
</body>
</html>
此時在瀏覽器輸入192.168.166.10,可以正常訪問192.168.166.9站點的圖片資源。
如果不想被盜鏈,則對192.168.166.9站點服務修改Nginx配置文件,防盜鏈的配置可以在任意的 location 模塊下設置,不能在 server 下,不想讓別人盜鏈哪個資源就在那個資源的 location 模塊下設置防盜鏈。
防盜鏈設置格式:
valid_referers none | blocked | server_names | strings ....;
-
--none:允許沒有http_refer的請求訪問資源,檢測 Referer 頭域不存在的情況,則可以訪問。
-
--blocked:檢測 Referer 頭域的值被防火墻或者代理服務器刪除或偽裝的情況。這種情況該頭域的值不以 “http://” 或 “https://” 開頭。允許不是http://開頭的,不帶協議的請求訪問資源。
-
--server_names :只允許指定ip/域名來的請求訪問資源(白名單)。可設置一個或多個 URL ,檢測 Referer 頭域的值是否是這些 URL 中的某一個。在生產環境中盡量使用域名,不使用ip。
舉例
valid_referers 192.168.44.101;
if ($invalid_referer) {
return 403;
}
192.168.166.9設置防盜鏈
server {listen 80;server_name localhost;location / {root ? /usr/local/nginx1273/html;index index.html index.htm;}location ~* \.(js|img|css|png)${valid_referers 192.168.166.9; #只允許192.168.166.9訪問靜態資源,其他人訪問則會返回403if ($invalid_referer){return 403;}root html;index index.html index.htm;}error_page 500 502 503 504 /50x.html;location =/50x.html {root html;}
}
5.4 測試
瀏覽器測試
用192.168.166.10去訪問,css等靜態資源返回403,獲取不到數據。
點擊”站點“,跳轉到192.168.166.9站點資源是顯示: