On this page
使用 mod_rewrite 控制访问
本文档是对mod_rewrite reference documentation的补充。它描述了如何使用mod_rewrite来控制对各种资源的访问以及其他相关技术。这包括 mod_rewrite 常用用法的许多示例,包括每种用法的详细说明。
Warning
请注意,这些示例中的许多示例在您的特定服务器配置中都不会起作用,因此,理解它们,而不只是将示例剪切并粘贴到您的配置中,这一点很重要。
禁止图片“热链接”
Description:
- 以下技术禁止在其他网站上进行其他操作,包括在页面中内嵌图像。这种做法通常称为“热链接”,导致您的带宽被用于为其他人的站点提供内容。
Solution:
- 此技术依赖于
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]
在这些技术中,后两种趋于最有效地使人们停止热链接您的图像,因为他们根本看不到他们期望看到的图像。
Discussion:
- 如果您只想拒绝对该资源的访问,而不是将该请求重定向到其他位置,则无需使用 mod_rewrite 即可完成此操作:
SetEnvIf Referer "example\.com" localreferer
<FilesMatch "\.(jpg|png|gif)$">
Require env localreferer
</FilesMatch>
封锁机器人
Description:
- 在本食谱中,我们讨论如何阻止来自特定机器人或用户代理的持久性请求。
机械手排除的标准定义了一个文件/robots.txt
,该文件指定您希望排除机械手的网站部分。但是,某些机械手不遵守这些文件。
请注意,有一些方法不使用 mod_rewrite。还要注意,可以很容易地规避依赖 Client 端USER_AGENT
字符串的任何技术,因为可以更改该字符串。
Solution:
- 我们使用规则集指定要保护的目录,并使用 Client 端
USER_AGENT
识别恶意或持久性机器人。
- 我们使用规则集指定要保护的目录,并使用 Client 端
在此示例中,我们从位置/secret/files
阻止了名为NameOfBadRobot
的机器人。如果尝试仅从特定来源阻止该用户代理,则也可以指定 IP 地址范围。
RewriteCond "%{HTTP_USER_AGENT}" "^NameOfBadRobot"
RewriteCond "%{REMOTE_ADDR}" "=123\.45\.67\.[8-9]"
RewriteRule "^/secret/files/" "-" [F]
Discussion:
- 无需为此使用 mod_rewrite,您可以使用替代方法来完成相同的目的,如下所示:
SetEnvIfNoCase User-Agent "^NameOfBadRobot" goaway
<Location "/secret/files">
<RequireAll>
Require all granted
Require not env goaway
</RequireAll>
</Location>
如上所述,通过简单地修改USER_AGENT
请求 Headers,可以轻松地绕过此技术。如果遇到持续攻击,则应考虑在较高级别(例如在防火墙上)将其阻止。
拒绝拒绝列表中的主机
Description:
- 我们希望维护一个主机列表,而不是
hosts.deny
,并阻止这些主机访问我们的服务器。
- 我们希望维护一个主机列表,而不是
Solution:
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 ## ## 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 -
Discussion:
第二个 RewriteCond 假定您已打开 HostNameLookups,以便将解析 Client 端 IP 地址。如果不是这种情况,则应删除第二个 RewriteCond,并从第一个 RewriteCond 中删除
[OR]
标志。
Referer-based Deflector
Description:
- 根据请求来自的引荐来源重定向请求,每个引荐来源具有不同的目标。
Solution:
- 以下规则集使用 Map 文件将每个 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]
Map 文件列出了每个引荐来源网址的重定向目标,或者,如果我们仅希望重定向回它们的来源,则在 Map 中放置一个“-”:
##
## 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/