📄 rewriteguide.html
字号:
}
&print_http_headers_multipart_end;
exit(0);
##EOF##
</pre></div>
</dd>
</dl>
<h3>大型虚拟主机</h3>
<dl>
<dt>说明:</dt>
<dd>
<p>Apache的<code class="directive"><a href="../mod/core.html#<virtualhost>"><VirtualHost></a></code>功能很强,在有几十个虚拟主机的情况下运行得很好,但是如果你是ISP,需要提供几百个虚拟主机,那么这就不是一个最佳的选择了。</p>
</dd>
<dt>方案:</dt>
<dd>
<p>为此,需要用<dfn>代理吞吐(Proxy Throughput)</dfn>功能(flag <code>[P]</code>)映射远程页面甚至整个远程网络区域到自己的名称空间:</p>
<div class="example"><pre>
##
## vhost.map
##
www.vhost1.dom:80 /path/to/docroot/vhost1
www.vhost2.dom:80 /path/to/docroot/vhost2
:
www.vhostN.dom:80 /path/to/docroot/vhostN
</pre></div>
<div class="example"><pre>
##
## httpd.conf
##
:
# use the canonical hostname on redirects, etc.
UseCanonicalName on
:
# add the virtual host in front of the CLF-format
CustomLog /path/to/access_log "%{VHOST}e %h %l %u %t \"%r\" %>s %b"
:
# enable the rewriting engine in the main server
RewriteEngine on
# define two maps: one for fixing the URL and one which defines
# the available virtual hosts with their corresponding
# DocumentRoot.
RewriteMap lowercase int:tolower
RewriteMap vhost txt:/path/to/vhost.map
# Now do the actual virtual host mapping
# via a huge and complicated single rule:
#
# 1. make sure we don't map for common locations
RewriteCond %{REQUEST_URL} !^/commonurl1/.*
RewriteCond %{REQUEST_URL} !^/commonurl2/.*
:
RewriteCond %{REQUEST_URL} !^/commonurlN/.*
#
# 2. make sure we have a Host header, because
# currently our approach only supports
# virtual hosting through this header
RewriteCond %{HTTP_HOST} !^$
#
# 3. lowercase the hostname
RewriteCond ${lowercase:%{HTTP_HOST}|NONE} ^(.+)$
#
# 4. lookup this hostname in vhost.map and
# remember it only when it is a path
# (and not "NONE" from above)
RewriteCond ${vhost:%1} ^(/.*)$
#
# 5. finally we can map the URL to its docroot location
# and remember the virtual host for logging puposes
RewriteRule ^/(.*)$ %1/$1 [E=VHOST:${lowercase:%{HTTP_HOST}}]
:
</pre></div>
</dd>
</dl>
</div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="access" id="access">对访问的限制</a></h2>
<h3>阻止Robots</h3>
<dl>
<dt>说明:</dt>
<dd>
<p>如何阻止一个完全匿名的robot取得特定网络区域的页面?一个<code>/robots.txt</code>文件可以包含若干"robot排除协议"的行,但不足以阻止此类robot。</p>
</dd>
<dt>方案:</dt>
<dd>
<p>可以用一个规则集以拒绝对网络区域<code>/~quux/foo/arc/</code>(对一个很深的目录区域进行列表可能会使服务器产生很大的负载)的访问。还必须确保仅阻止特定的robot,就是说,仅仅阻止robot访问主机是不够的,这样会同时也阻止了用户访问该主机。为此,就需要对HTTP头的User-Agent信息作匹配。</p>
<div class="example"><pre>
RewriteCond %{HTTP_USER_AGENT} ^<strong>NameOfBadRobot</strong>.*
RewriteCond %{REMOTE_ADDR} ^<strong>123\.45\.67\.[8-9]</strong>$
RewriteRule ^<strong>/~quux/foo/arc/</strong>.+ - [<strong>F</strong>]
</pre></div>
</dd>
</dl>
<h3>阻止内嵌的图片</h3>
<dl>
<dt>说明:</dt>
<dd>
<p>假设,<code>http://www.quux-corp.de/~quux/</code>有一些内嵌图片的页面,这些图片很好,所以就有人用超链连到他们自己的页面中了。由于这样徒然增加了我们的服务器的流量,因此,我们不愿意这种事情发生。</p>
</dd>
<dt>方案:</dt>
<dd>
<p>虽然,我们不能100%地保护这些图片不被写入别人的页面,但至少可以对发出HTTP Referer头的浏览器加以限制。</p>
<div class="example"><pre>
RewriteCond %{HTTP_REFERER} <strong>!^$</strong>
RewriteCond %{HTTP_REFERER} !^http://www.quux-corp.de/~quux/.*$ [NC]
RewriteRule <strong>.*\.gif$</strong> - [F]
</pre></div>
<div class="example"><pre>
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !.*/foo-with-gif\.html$
RewriteRule <strong>^inlined-in-foo\.gif$</strong> - [F]
</pre></div>
</dd>
</dl>
<h3>对主机的拒绝</h3>
<dl>
<dt>说明:</dt>
<dd>
<p>如何拒绝一批外部列表中的主机对我们服务器的使用?</p>
</dd>
<dt>方案:</dt>
<dd>
<div class="example"><pre>
RewriteEngine on
RewriteMap hosts-deny txt:/path/to/hosts.deny
RewriteCond ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
RewriteCond ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
RewriteRule ^/.* - [F]
</pre></div>
</dd>
</dl>
<h3>对代理的拒绝</h3>
<dl>
<dt>说明:</dt>
<dd>
<p>如何拒绝某个主机或者来自特定主机的用户使用Apache代理?</p>
</dd>
<dt>方案:</dt>
<dd>
<p>首先,要确保Apache web服务器在编译时配置文件中<code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>在<code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>的下面!使它在<code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code>之前被调用。然后,如下拒绝某个主机...</p>
<div class="example"><pre>
RewriteCond %{REMOTE_HOST} <strong>^badhost\.mydomain\.com$</strong>
RewriteRule !^http://[^/.]\.mydomain.com.* - [F]
</pre></div>
<p>...如下拒绝user@host-dependent:</p>
<div class="example"><pre>
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} <strong>^badguy@badhost\.mydomain\.com$</strong>
RewriteRule !^http://[^/.]\.mydomain.com.* - [F]
</pre></div>
</dd>
</dl>
<h3>特殊的认证</h3>
<dl>
<dt>说明:</dt>
<dd>
<p>有时候,会需要一种非常特殊的认证,即对一组明确指定的用户,允许其访问,而没有(在使用<code class="module"><a href="../mod/mod_access.html">mod_access</a></code>的基本认证方法时可能会出现的)任何提示。</p>
</dd>
<dt>方案:</dt>
<dd>
<p>可是使用一个重写条件列表来排除所有的朋友:</p>
<div class="example"><pre>
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} <strong>!^friend1@client1.quux-corp\.com$</strong>
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} <strong>!^friend2</strong>@client2.quux-corp\.com$
RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} <strong>!^friend3</strong>@client3.quux-corp\.com$
RewriteRule ^/~quux/only-for-friends/ - [F]
</pre></div>
</dd>
</dl>
<h3>基于提交者(Referer)的反射器</h3>
<dl>
<dt>说明:</dt>
<dd>
<p>如何配置一个基于HTTP头"Referer"的反射器以反射到任意数量的提交页面?</p>
</dd>
<dt>方案:</dt>
<dd>
<p>使用这个很巧妙的规则集...</p>
<div class="example"><pre>
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]
</pre></div>
<p>... 并结合对应的重写映射地图:</p>
<div class="example"><pre>
##
## deflector.map
##
http://www.badguys.com/bad/index.html -
http://www.badguys.com/bad/index2.html -
http://www.badguys.com/bad/index3.html http://somewhere.com/
</pre></div>
<p>它可以自动将请求(在映射地图中指定了"<code>-</code>"值的时候)反射回其提交页面,或者(在映射地图中URL有第二个参数时)反射到一个特定的URL。</p>
</dd>
</dl>
</div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="section">
<h2><a name="other" id="other">其他</a></h2>
<h3>外部重写引擎</h3>
<dl>
<dt>说明:</dt>
<dd>
<p>一个常见的问题是如何解决似乎无法用<code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>解决的FOO/BAR/QUUX/之类的问题?</p>
</dd>
<dt>方案:</dt>
<dd>
<p>可以使用一个与<code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>功能相同的外部<code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code>程序,一旦它在Apache启动时被执行,则从<code>STDIN</code>接收被请求的URL ,并将处理过(通常是重写过的)的URL(以相同顺序)在<code>STDOUT</code>输出。</p>
<div class="example"><pre>
RewriteEngine on
RewriteMap quux-map <strong>prg:</strong>/path/to/map.quux.pl
RewriteRule ^/~quux/(.*)$ /~quux/<strong>${quux-map:$1}</strong>
</pre></div>
<div class="example"><pre>
#!/path/to/perl
# disable buffered I/O which would lead
# to deadloops for the Apache server
$| = 1;
# read URLs one per line from stdin and
# generate substitution URL on stdout
while (<>) {
s|^foo/|bar/|;
print $_;
}
</pre></div>
<p>这是一个作演示的例子,只是把所有的URL <code>/~quux/foo/...</code> 重写为 <code>/~quux/bar/...</code> ,而事实上,可以把它修改以获得任何你需要的功能。但是要注意,虽然一般用户都可以<strong>使用</strong>,可是只有系统管理员才可以<strong>定义</strong>这样的地图。</p>
</dd>
</dl>
</div>
</div>
<div id="footer">
<p class="apache">本文允许自由使用、分发、转载,但必须保留译者署名;详见:<a href="../translator_announcement.html#announcement">译者声明</a>。</p>
<p class="menu"><a href="../mod/index.html">模块索引</a> | <a href="../mod/directives.html">指令索引</a> | <a href="../faq/index.html">常见问题</a> | <a href="../glossary.html">词汇表</a> | <a href="../sitemap.html">站点导航</a></p></div>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -