如何為Nginx 配置防盜鏈功能?

  • 2019 年 12 月 6 日
  • 筆記

開始之前
什麼是 referer 請求頭?

referer 請求頭包含了當前請求頁面的來源地址,即表示當前頁面是通過這個來源頁面里的鏈接進入的。

服務端一般使用referer 請求頭識別訪問來源,可能會以此進行統計分析、日誌記錄以及快取優化等。

利用 referer 防止盜鏈?

假設當一個 HTTP 請求頭的 referer 欄位中包含一些不正確(期望)的值

那麼可以使用 nginx 的 ngx_http_referer_module 模組,禁止這個請求訪問站點

也就是常說的 nginx 防盜鏈,不過需要注意的是,referer 請求頭是可以偽造的,因此這個模組並不能 100%的阻止這類請求。

防盜鏈功能主要由模組中的 valid_referers 指令與 $invalid_referer 變數配合使用,例如下面的配置,允許符合以下規則的請求訪問站點

  • 沒有 referer,直接在瀏覽器打開這個URI。
  • 帶有 referer,但是被修改過值(如proxy)不是以http(s)://開頭的字元串。
  • 帶有 referer, 值是以http(s)://開頭的字元串,並且匹配 valid_referers列表中的值。

操作步驟


1. nginx 配置文件

cat /etc/nginx/conf.d/default.conf    server {       #..其它配置項目省略       # 上傳圖片目錄      location ^~ /attachments {          alias /data/uploads/;          expires 180d;           valid_referers none blocked                                         *.demo.com demo.com                                         ~.demo.;         if ($invalid_referer) {              return 403;          }      }  }

2. 重啟 nginx

nginx -t && nginx reload

3. 驗證

4次請求,前3次為200,最後一次403 。

請求1,沒有帶`referer`資訊,相當於直接在瀏覽器打開這個URI,匹配參數 "None"。    請求2,雖然有帶`referer`資訊,但值不是以"http(s)://"開頭的字元串,匹配參數 "blocked"。    請求3,帶有正確主機名`referer`資訊,匹配參數 "server_names",這也是瀏覽器中正常請求。    請求4,帶有域外的主機名`referer`資訊,"表示這個請求是從百度頁面里的鏈接進入的",按照規則                     $invalid_referer 變數被設置為 1 ,最終伺服器返回 403狀態碼,完成防盜鏈。

valid_referers 指令

語法: valid_referers none|blocked|server_names string ...;  默認值: no  使用欄位: server, location  功能: 此指令在 referer頭的基礎上為 $invalid_referer 變數賦值,可以實現簡單的防盜鏈功能。  如果 valid_referers列表中沒有匹配Referer請求頭,$invalid_referer將被設置為1,否則為0(或空值)。
參數:  none      請求頭中不存在 Referer欄位('空值',比如直接在瀏覽器打開一個圖片URI)。  blocked      請求頭中存在 Referer欄位,但值不是以"http(s)://"開頭的字元串(被防火牆或代理伺服器修改刪除)。  server_names       Referer欄位包含伺服器名稱。  arbitrary string      定義伺服器名稱和可選 URI前綴,伺服器名稱的開頭或結尾可以有一個"*"。  regular expression      使用正則匹配,第一個符號為"~"。
示例:      valid_referers none blocked server_names                     *.example.com example.* www.example.org/galleries/                     ~.google.;        if ($invalid_referer) {          return 403;      }

參考

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referer

http://nginx.org/en/docs/http/ngx_http_referer_module.html

小結


最後來總結下文章中的知識點

  • referer 請求頭,用於識別訪問來源。
  • referer 請求頭可以偽造,不能做為唯一的判斷條件。
  • 藉助 ngx_http_referer_module 模組,實現簡單的 nginx 防盜鏈。