如何為Nginx 配置防盜鏈功能?
- 2019 年 12 月 6 日
- 筆記
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 防盜鏈。