<-
Apache > HTTP 服务器 > 文档 > 版本 2.5 > Rewrite

使用 mod_rewrite 控制访问

可用语言:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

本文档是 mod_rewrite 参考文档的补充。它描述了如何使用 mod_rewrite 来控制对各种资源的访问,以及其他相关技术。 其中包括许多 mod_rewrite 的常见用法示例, 以及每个示例工作原理的详细描述。

请注意,这些示例中的许多不会在你的特定服务器配置中直接生效, 因此理解它们非常重要,而不仅仅是将示例复制粘贴到你的配置中。

参见

top

禁止图片"盗链"

描述:

以下技术禁止其他站点将你的图片内联到他们的页面中。 这种做法通常被称为"盗链",会导致你的带宽被用来为他人的站点提供内容。

解决方案:

此技术依赖于 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>
top

阻止机器人

描述:

在本配置方案中,我们讨论如何阻止来自特定机器人或用户代理的持续请求。

机器人排除标准定义了一个文件 /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 请求头即可。如果你遭受持续攻击, 应考虑在更高层级(如防火墙)进行阻止。

top

拒绝列表中的主机

描述:

我们希望维护一个主机列表,类似于 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
##
## 注意!这是一个映射文件,不是列表,即使我们将其作为列表使用。
## mod_rewrite 将其解析为键/值对,因此每个条目
## 至少必须存在一个虚拟值 "-"。
##

193.102.180.41 -
bsdti1.sdm.de -
192.76.162.40 -

讨论:

第二个 RewriteCond 假设你已启用 HostNameLookups, 以便客户端 IP 地址会被解析。如果未启用, 你应该删除第二个 RewriteCond,并从第一个 RewriteCond 中删除 [OR] 标志。

top

基于 Referer 的转向器

描述:

根据请求来源的 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]

映射文件列出了每个 referer 的重定向目标, 或者如果我们只想重定向回他们的来源地,则在映射中放置 "-":

##
##  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/

可用语言:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn