使用 mod_rewrite 控制访问

本文描述了如何使用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/

上一篇: Apache URL重写 下一篇: Apache认证和授权