使用 mod_rewrite 控制存取

2019-10-16 22:02:08

本文描述了如何使用mod_rewrite來控制對各種資源的存取以及其他相關技術。這包括mod_rewrite常見用法的許多範例,包括每種方法的詳細說明。

禁止影象「盜鏈」

描述:
以下技術禁止其他網站的存取您的資源,包括您的網頁內嵌影象。這種做法通常被稱為「盜連結」,並導致您的頻寬用於為其他人的網站提供內容。

解決方案:
此技術依賴於HTTP_REFERER變數的值,該變數是可選的。因此,有些人可能會繞過這種限制。但是,大多數使用者將遇到失敗的請求,隨著時間的推移,該請求會導致影象從該其他站點中刪除。

有幾種方法可以處理這種情況。

在第一個範例中,如果請求沒有從我們網站上的頁面發起,我們就會拒絕該請求。出於此範例的目的,假設我們的網站是www.example.com

RewriteCond "%{HTTP_REFERER}" "!^$"
RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC]
RewriteRule "\.(gif|jpg|png)$"    "-"   [F,NC]

在第二個範例中,我們不是顯示請求失敗,而是顯示替代影象。

RewriteCond "%{HTTP_REFERER}" "!^$"
RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC]
RewriteRule "\.(gif|jpg|png)$"    "/images/go-away.png"   [R,NC]

在第三個範例中,將請求重定向到其他站點上的影象。

RewriteCond "%{HTTP_REFERER}" "!^$"
RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC]
RewriteRule "\.(gif|jpg|png)$" "http://other.example.com/image.gif"   [R,NC]

在這些技術中,最後兩種技術往往是讓人們停止盜連結影象的最有效方法,因為他們根本看不到他們期望看到的影象。

如果想拒絕存取資源,而不是將該請求重定向到其他地方,這可以在不使用mod_rewrite的情況下完成:

SetEnvIf Referer "example\.com" localreferer
<FilesMatch "\.(jpg|png|gif)$">
    Require env localreferer
</FilesMatch>

阻止機器人

描述:

在本文中,我們將討論如何阻止來自特定機器人或使用者代理的持久請求。

機器人排除標準定義了一個檔案/robots.txt,用於指定您希望排除機器人的網站部分。但是,有些機器人不尊重這些檔案。

請注意,有一些方法可以實現這一點,不需要使用mod_rewrite。另請注意,任何依賴用戶端USER_AGENT字串的技術都可以非常容易地避開,因為可以更改該字串。

解決辦法:
我們使用規則集來指定要保護的目錄,以及用戶端USER_AGENT,用於標識惡意或永續性機器人。

在此範例中,我們從位置/secret/files中阻止名為NameOfBadRobot的機器人。如果嘗試僅從特定源阻止該使用者代理,也可以指定IP地址範圍。

RewriteCond "%{HTTP_USER_AGENT}"   "^NameOfBadRobot"
RewriteCond "%{REMOTE_ADDR}"       "=123\.45\.67\.[8-9]"
RewriteRule "^/secret/files/"   "-"   [F]

可以使用替代方法完成相同的操作,而不是使用mod_rewrite,如下所示:

SetEnvIfNoCase User-Agent "^NameOfBadRobot" goaway
<Location "/secret/files">
    <RequireAll>
        Require all granted
        Require not env goaway
    </RequireAll>
</Location>

如上所述,通過簡單地修改USER_AGENT請求檔頭,這種技術很容易避免。如果遇到持續攻擊,則應考慮將其阻止在更高階別,例如防火牆。

拒絕黑名單中的主機

描述:
我們希望維護一個黑名單的主機,而不是像hosts.deny,並阻止這些主機存取我們的伺服器。

解決範例:

RewriteEngine on
RewriteMap    hosts-deny  "txt:/path/to/hosts.deny"
RewriteCond   "${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}" "!=NOT-FOUND" [OR]
RewriteCond   "${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}" "!=NOT-FOUND"
RewriteRule   "^"  "-"  [F]

檔案: hosts.deny

##
## hosts.deny
##
## ATTENTION! This is a map, not a list, even when we treat it as such.
## mod_rewrite parses it for key/value pairs, so at least a
## dummy value "-" must be present for each entry.
##

193.102.180.41 -
bsdti1.sdm.de -
192.76.162.40 -

第二個RewriteCond假定已開啟HostNameLookups,以便解析用戶端IP地址。如果不是這樣,應該刪除第二個RewriteCond,並從第一個RewriteCond中刪除[OR]標誌。

基於Referer的Deflector

描述:
根據請求來自的Referer重定向請求,每個Referer使用不同的目標。

解決辦法:
以下規則集使用對映檔案將每個Referer與重定向目標相關聯。

RewriteMap  deflector "txt:/path/to/deflector.map"

RewriteCond "%{HTTP_REFERER}" !=""
RewriteCond "${deflector:%{HTTP_REFERER}}" "=-"
RewriteRule "^" "%{HTTP_REFERER}" [R,L]

RewriteCond "%{HTTP_REFERER}" !=""
RewriteCond "${deflector:%{HTTP_REFERER}|NOT-FOUND}" "!=NOT-FOUND"
RewriteRule "^" "${deflector:%{HTTP_REFERER}}" [R,L]

對映檔案列出了每個參照者的重定向目標,或者如果只是希望重定向回到它們來源的位置,則在對映中放置 -

##
##  deflector.map
##

http://badguys.example.com/bad/index.html    -
http://badguys.example.com/bad/index2.html   -
http://badguys.example.com/bad/index3.html   http://somewhere.example.com/