以下内容摘自笔者编著的《网管员必读――网络应用》(第2版)一书:
3.2.2 Apache 2.2配置段和容器
“配置段”和“容器”都是用来指定配置文件的作用范围的。配置文件中指令的作用范围可能是整个服务器,也可能是特定的目录、文件、主机、
URL
。本节将要介绍的是如何使用配置段及
.htaccess
文件来改变配置指令的作用范围。
1.配置段和容器的类型
配置段的类型
包括在
core
、
mod_version
和
mod_proxy 3
个模块中
,
可以使用的指令包括
:
<Directory>
、
<DirectoryMatch>
、
<Files>
、
<FilesMatch>
、
<IfDefine>
、
<IfModule>
、
<IfVersion>
、
<Location>
、
<LocationMatch>
、
<Proxy>
、
<ProxyMatch>
和
<VirtualHost>
。这些指令都是配置段的容器。
容器有两种基本类型。大多数容器是针对各个请求的,包含于其中的指令仅对与该容器匹配的请求起作用,而容器
<IfDefine>
、
<IfModule>
、
<IfVersion>
仅在启动和重新启动时起作用,如果在启动时指定的条件成立,则其中的指令对所有的请求都有效,否则将被忽略。
<IfDefine>
容器中的指令只有在
httpd
命令行中设定了特定的参数后才有效。下面的示例中限定只有在服务器用
httpd -DClosedForNow
方式启动时,所有的请求才会被重定向到另一个站点:
<IfDefine ClosedForNow>
Redirect / [url]http://otherserver.example.com/[/url]
</IfDefine>
<IfModule>
容器与
<IfDefine>
很相似,但是其中的指令只有当服务器启用特定的模块时才有效(或是被静态地编译进了服务器,或是被动态装载进了服务器)。注意,配置文件中该模块的装载指令
LoadModule
行必须出现在此容器之前。这个容器应该仅用于无论特定模块是否安装,配置文件都能正常运转的场合;而不应该用于容器中的指令在任何情况下都必须生效的场合,因为它会抑制类似模块没找到之类的有用出错信息。
下面的示例中,指定
MimeMagicFiles
指令仅当
mod_mime_magic
模块启用时才有效。
<IfModule mod_mime_magic.c>
MimeMagicFile conf/magic
</IfModule>
<IfVersion>
指令与
<IfDefine>
和
<IfModule>
也很相似,但是其中的指令只有当正在执行的服务器版本与指定的版本要求相符时才有效。这个模块被设计用于测试套件,以及在一个存在多个不同
httpd
版本的大型网络中需要针对不同版本使用不同配置的情况。
<IfVersion >= 2.1>
#
仅在版本高于
2.1.0
的时候才生效
</IfVersion>
<IfDefine>
、
<IfModule>
、
<IfVersion>
都可以在条件前加一个“
!
”符号以实现条件的否定,而且都可以嵌套以实现更复杂的配置。
2.文件系统和网络空间
最常用的配置段是针对文件系统和网络空间特定位置的配置段。首先必须理解文件系统和网络空间这两个概念的区别:文件系统是指操作系统所看见的磁盘视图,比如,在
UNIX
系统中,
Apache
会被默认安装到“
/usr/local/apache 2.2 ” 目录下,在Windows
系统中,
Apache
会被默认安装到“
Program Files/Apache Software Foundation/Apache 2.2 ” 目录下。相反,网络空间是网站被Web
服务器发送及被客户在浏览器中所看到的视图。在
Windows
平台下,网络空间的默认安装路径为“
Program Files/Apache Software Foundation/Apache2.2/ htdocs
”。
由于网页可以从数据库或其他地方动态生成,因此,网络空间无须直接映射到文件系统中。
|
Apache
始终用正斜杠而不是反斜杠作为路径的分隔符,即使是在
Windows
平台中。
|
1)文件系统容器
<Directory>
和
<Files>
指令与其相应的
正则表达式
版本(
<DirectoryMatch>
和
<FilesMatch>
)一起作用于文件系统的特定部分。
<Directory>
配置段中的指令作用于指定的文件系统目录及其所有子目录,
.htaccess
文件可以达到同样的效果。在下面的示例中,
/var/web/dir1
及其所有子目录被允许进行目录索引。
<Directory /var/web/dir1>
Options +Indexes
</Directory>
<Files>
配置段中的指令作用于特定的文件名,而无论这个文件实际存在于哪个目录下。下面的示例中的配置指令如果出现在配置文件的主服务器段,则会拒绝对位于任何目录下的
private.html
的访问。
<Files private.html>
Order allow,deny
Deny from all
</Files>
<Files>
和
<Directory>
段的组合可以作用于文件系统中的特定文件。下面的示例中的配置会拒绝对
/var/web/dir1/private.html
、
/var/web/dir1/subdir2/private.html
、
/var/web/dir1/subdir3/ private.html
等任何
/var/web/dir1/
目录下的
private.html
的访问。
<Directory /var/web/dir1>
<Files private.html>
Order allow,deny
Deny from all
</Files>
</Directory>
2)网络空间容器
<Location>
指令与其相应的正则表达式版本(
<LocationMatch>
)一起作用于网络空间的特定部分。下面的示例中的配置会拒绝对任何以“
/private
”开头的
URL
路径的访问,如
[url]http://yoursite.example.com/private[/url]
、
[url]http://yoursite.example.com/private123[/url]
、
[url]http://yoursite.example.[/url] com/private/dir/file.html
等所有以“
/private
”开头的
URL
路径。
<Location /private>
Order Allow,Deny
Deny from all
</Location>
<Location>
指令与文件系统无关,下面的示例演示了如何将特定的
URL
映射到
Apache
内部的处理器
mod_status
中,而并不要求文件系统中确实存在
server-status
文件。
<Location /server-status>
SetHandler server-status
</Location>
3)通配符和正则表达式
<Directory>
、
<Files>
、
<Location>
指令可以使用与
C
标准库中的
fnmatch
类似的
shell
风格的通配符
。“
*
”匹配任何字符串
,“
?
”匹配任何单个的字符
,“
[seq]
”匹配
seq
序列中的任何字符
,“
/
”符号不被任何通配符所匹配,所以必须显式地使用。
如果需要更复杂的匹配,这些容器都有一个对应的正则版本
:
<
DirectoryMatch>
、
<FilesMatch>
、
<LocationMatch>
,可以使用与
Perl
兼容的
正则表达式
,以提供更复杂的匹配。下面的示例使用非正则表达式的通配符来改变所有用户目录的配置。
<Directory /home/*/public_html>
Options Indexes
</Directory>
下例是使用正则表达式一次性拒绝对多种图形文件的访问。
<FilesMatch \.
(
?i:gif|jpe?g|png
)
$>
Order allow,deny
Deny from all
</FilesMatch>
4)选择文件系统容器,还是网络空间容器
选择使用文件系统容器,还是使用网络空间容器其实很简单。当指令作用于文件系统时,总是用
<Directory>
或
<Files>
;而当指令作用于不存在于文件系统中的对象时,就用
<Location>
,比如一个由数据库生成的网页。一定不要试图用
<Location>
去限制对文件系统中的对象的访问,因为许多不同的网络空间路径可能会映射到同一个文件系统目录,从而导致访问限制被突破。比如
:
<Location /dir/>
Order allow,deny
Deny from all
</Location>
上述配置对
[url]http://yoursite.example.com/dir/[/url]
请求的确起作用。但是,设想在一个不区分大小写的文件系统中,这个访问限制会被
[url]http://yoursite.example.com/DIR/[/url]
请求轻易突破。而
<Directory>
指令才会真正作用于对这个位置的任何形式的请求。但是,有一个例外,就是
UNIX
文件系统中的符号连接(软连接),符号连接可以使同一个目录出现在文件系统中的多个位置。
<Directory>
指令将不重设路径名而直接追踪符号连接,因此,对于安全要求最高的,应该用
Options
指令禁止对符号连接的追踪。
同时,也不要认为使用大小写敏感的文件系统就无所谓了,因为有很多方法可以将不同的网络空间路径映射到同一个文件系统路径中,所以,应当尽可能使用文件系统容器。但是也有一个例外,就是把访问限制放在
<Location />
配置段中可以很安全地作用于除了某些特定
URL
以外的所有
URL
。
3.虚拟主机
“虚拟主机”是指在一个机器上运行多个网站(比如,
[url]www.company1.com[/url]
和
[url]www.company2.com[/url]
)。如果每个网站拥有不同的
IP
地址,则虚拟主机可以是“基于
IP
”的;如果只有一个
IP
地址,也可以是“基于主机名”的,其实现对最终用户是透明的。这一点,其实在介绍
IIS
网站架设中也有类似的说明,那就是网站的标识,它既可以基于
IP
地址,也可以基于“主机头值”(也就是域名),还可以基于端口。
Apache
是率先支持基于
IP
的虚拟主机的服务器之一。
1.1
及其更新版本同时支持基于
IP
和基于主机名的虚拟主机。虚拟主机中所用的容器就是
<VirtualHost>
,它作用于特定的虚拟主机,为同一个机器上具有不同配置的多个主机提供支持。
有关虚拟主机的配置方法将在本章后面具体介绍。
4.代理
<Proxy>
和
<ProxyMatch>
容器中的指令仅作用于通过
mod_proxy
代理服务器访问的、与指定
URL
匹配的站点。下面的示例中的配置会拒绝通过代理服务器访问
cnn.com
站点。
<Proxy [url]http://cnn.com/[/url]*>
Order allow,deny
Deny from all
</Proxy>
5.总结
以上介绍了几种类型的容器及所用的指令,查阅指令的作用域,就可以知道哪些指令可以出现在哪些配置段中。从语法上看,允许在
<Directory>
段中使用的指令当然也可以在
<DirectoryMatch>
、
<Files>
、
<FilesMatch>
、
<Location>
、
<LocationMatch>
、
<Proxy>
、
<ProxyMatch>
段中使用,但也有例外:
AllowOverride
指令只能出现在
<Directory>
段中。
Options
(参数选项)中的
FollowSymLinks
和
SymLinksIfOwnerMatch
只能出现在
<Directory>
段或者
.htaccess
文件中。
Options
指令不能用于
<Files>
和
<FilesMatch>
段。
除了各自的应用范围不同之外,它们之间有些配置段还是可以合并
的。
配置段会按非常特别的顺序依次生效,由于这会对配置指令的处理结果产生重大影响,因此理解它的流程非常重要。
合并的顺序如下。
(
1
)
<Directory>
(除了正则表达式)和
.htaccess
同时处理(如果允许的话,
.htaccess
的设置会覆盖
<Directory>
的设置
);
(
2
)
<DirectoryMatch>
(和
<Directory ~>
);
(
3
)
<Files>
和
<FilesMatch>
同时处理;
(
4
)
<Location>
和
<LocationMatch>
同时处理。
除了
<Directory>
,每个组都按它们在配置文件中出现的顺序被依次处理,而
<Directory>
(上面的第
1
组),会按顺序由短到长被依次处理。例如:
<Directory /var/web/dir>
会先于
<Directory /var/web/dir/subdir>
被处理。如果有多个指向同一个目录的
<Directory>
段,则按它们在配置文件中的顺序被依次处理。用
Include
指令包含进来的配置被视为按原样插入到
Include
指令的位置。
位于
<VirtualHost>
容器中的配置段在外部对应的段处理完毕以后再处理,这样就允许虚拟主机覆盖主服务器的设置。
当请求是由
mod_proxy
处理的时候,
<Proxy>
容器将会在处理顺序中取代
<Directory>
容器的位置。也就是说,后面的段覆盖前面的相应的段。