# 配置段(容器)
[配置文件](#calibre_link-255)中指令的作用范围可能是整个服务器,也可能是特定的目录、文件、主机、URL。本文阐述如何使用配置段(容器)以及`.htaccess`文件来改变配置指令的作用范围。
## 配置段(容器)的类型
相关模块
* `core`
* `mod_version`
* `mod_proxy`
相关指令
* `<Directory>`
* `<DirectoryMatch>`
* `<Files>`
* `<FilesMatch>`
* `<IfDefine>`
* `<IfModule>`
* `<IfVersion>`
* `<Location>`
* `<LocationMatch>`
* `<Proxy>`
* `<ProxyMatch>`
* `<VirtualHost>`
容器有两种基本类型。大多数容器是针对各个请求的,包含于其中的指令仅对与该容器匹配的请求起作用,而容器`<IfDefine>`、`<IfModule>`、`<IfVersion>`仅在启动和重新启动中起作用,如果在启动时指定的条件成立,则其中的指令对所有的请求都有效,否则将被忽略。
`<IfDefine>`容器中的指令只有在`httpd`命令行中设定了特定的参数后才有效。下例中,只有在服务器用 `httpd -DClosedForNow` 方式启动时,所有的请求才会被重定向到另一个站点:
```
<IfDefine ClosedForNow>
Redirect / http://otherserver.example.com/
</IfDefine>
```
`<IfModule>`容器很相似,但是其中的指令只有当服务器启用特定的模块时才有效(或是被静态地编译进了服务器,或是被动态装载进了服务器),注意,配置文件中该模块的装载指令`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>`都可以在条件前加一个"!"以实现条件的否定,而且都可以嵌套以实现更复杂的配置。
## 文件系统和网络空间
最常用的配置段是针对文件系统和网络空间特定位置的配置段。首先必须理解文件系统和网络空间这两个概念的区别,文件系统是指操作系统所看见的磁盘视图,比如,在Unix文件系统中,Apache会被默认安装到`/usr/local/apache2` ,在Windows文件系统中,Apache会被默认安装到`"C:/Program Files/Apache Group/Apache2"`(注意:Apache始终用正斜杠而不是反斜杠作为路径的分隔符,即使是在Windows中)。相反,网络空间是网站被web服务器发送以及被客户在浏览器中所看到的视图。所以网络空间中的路径`/dir/` 在Apache采用默认安装路径的情况下对应于Unix文件系统中的路径`/usr/local/apache2/htdocs/dir/` 。由于网页可以从数据库或其他地方动态生成,因此,网络空间无须直接映射到文件系统。
### 文件系统容器
`<Directory>`和`<Files>`指令与其相应的[正则表达式](#calibre_link-67 "see glossary")版本(`<DirectoryMatch>`和`<FilesMatch>`)一起作用于文件系统的特定部分。`<Directory>`配置段中的指令作用于指定的文件系统目录及其所有子目录,[.htaccess文件](#calibre_link-222)可以达到同样的效果。下例中,`/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>
```
### 网络空间容器
`<Location>`指令与其相应的[正则表达式](#calibre_link-67 "see glossary")版本(`<LocationMatch>`)一起作用于网络空间的特定部分。下例中的配置会拒绝对任何以"`/private`"开头的URL路径的访问,比如:`http://yoursite.example.com/private`、`http://yoursite.example.com/private123`、`http://yoursite.example.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>
```
### 通配符和正则表达式
`<Directory>`、`<Files>`、`<Location>`指令可以使用与C标准库中的`fnmatch`类似的shell风格的通配符。"*"匹配任何字符串,"?"匹配任何单个的字符,"[_seq_]"匹配_seq_序列中的任何字符,符号"/"不被任何通配符所匹配,所以必须显式地使用。
如果需要更复杂的匹配,这些容器都有一个对应的正则版本:`<DirectoryMatch>`、`<FilesMatch>`、`<LocationMatch>` ,可以使用与Perl兼容的[正则表达式](#calibre_link-67 "see glossary"),以提供更复杂的匹配。但是还必须注意下面[配置段的合并](#calibre_link-452)部分关于使用正则表达式会如何作用于配置指令的内容。
下例使用非正则表达式的通配符来改变所有用户目录的配置:
```
<Directory /home/*/public_html>
Options Indexes
</Directory>
```
下例使用正则表达式一次性拒绝对多种图形文件的访问:
```
<FilesMatch \.(?i:gif|jpe?g|png)$>
Order allow,deny
Deny from all
</FilesMatch>
```
### 什么情况下用什么
选择使用文件系统容器还是使用网络空间容器其实很简单。当指令应该作用于文件系统时,总是用`<Directory>`或`<Files>`;而当指令作用于不存在于文件系统的对象时,就用`<Location>`,比如一个由数据库生成的网页。
绝对不要试图用`<Location>`去限制对文件系统中的对象的访问,因为许多不同的网络空间路径可能会映射到同一个文件系统目录,从而导致你的访问限制被突破。比如:
```
<Location /dir/>
Order allow,deny
Deny from all
</Location>
```
上述配置对`http://yoursite.example.com/dir/` 请求的确起作用。但是设想在一个不区分大小写的文件系统中,这个访问限制会被`http://yoursite.example.com/DIR/` 请求轻易突破。而`<Directory>`指令才会真正作用于对这个位置的任何形式的请求。但是有一个例外,就是Unix文件系统中的符号连接(软连接),符号连接可以使同一个目录出现在文件系统中的多个位置。`<Directory>`指令将不重设路径名而直接追踪符号连接,因此,对于安全要求最高的,应该用`Options`指令禁止对符号连接的追踪。
不要认为使用大小写敏感的文件系统就无所谓了,因为有很多方法可以将不同的网络空间路径映射到同一个文件系统路径,所以,应当尽可能使用文件系统容器。但是也有一个例外,就是把访问限制放在`<Location />`配置段中可以很安全地作用于除了某些特定URL以外的所有URL。
## 虚拟主机
`<VirtualHost>`容器作用于特定的虚拟主机,为同一个机器上具有不同配置的多个主机提供支持。详见[虚拟主机文档](#calibre_link-36)。
## 代理
`<Proxy>`和`<ProxyMatch>`容器中的指令仅作用于通过`mod_proxy`代理服务器访问的、与指定URL匹配的站点。下例中的配置会拒绝通过代理服务器访问`cnn.com`站点。
```
<Proxy http://cnn.com/*>
Order allow,deny
Deny from all
</Proxy>
```
## 允许使用哪些指令?
查阅指令的[作用域](#calibre_link-20),就可以知道哪些指令可以出现在哪些配置段中。从语法上看,允许在`<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>`容器的位置。
后面的段覆盖前面的相应的段。
### 技术说明
其实,在名称翻译阶段(即用`Aliases`和`DocumentRoots`来映射URL到文件系统)之前,会有一个`<Location>`/`<LocationMatch>`的序列被处理,而在名称翻译结束后,这个序列的处理结果则被完全抛弃。
### 一些例子
这是一个演示合并顺序的例子。如果这些指令都起作用,则会按 A > B > C > D >E 的顺序依次生效。
```
<Location />
E
</Location>
<Files f.html>
D
</Files>
<VirtualHost *>
<Directory /a/b>
B
</Directory>
</VirtualHost>
<DirectoryMatch "^.*b$">
C
</DirectoryMatch>
<Directory /a/b>
A
</Directory>
```
在下面这个更具体的例子中,无论在`<Directory>`段中加了多少访问限制,由于`<Location>`段将会被最后处理,从而会允许不加限制的对服务器的访问,可见合并的顺序是很重要的,千万小心!
```
<Location />
Order deny,allow
Allow from all
</Location>
# 这个<Directory>段将不会实际生效
<Directory />
Order allow,deny
Allow from all
Deny from badguy.example.com
</Directory>
```
- Apache HTTP Server Version 2.2 文档 [最后更新:2006年3月21日]
- 版本说明
- 从1.3升级到2.0
- 从2.0升级到2.2
- Apache 2.2 新特性概述
- Apache 2.0 新特性概述
- The Apache License, Version 2.0
- 参考手册
- 编译与安装
- 启动Apache
- 停止和重启
- 配置文件
- 配置段(容器)
- 缓冲指南
- 服务器全局配置
- 日志文件
- 从URL到文件系统的映射
- 安全方面的提示
- 动态共享对象(DSO)支持
- 内容协商
- 自定义错误响应
- 地址和端口的绑定(Binding)
- 多路处理模块
- Apache的环境变量
- Apache处理器的使用
- 过滤器(Filter)
- suEXEC支持
- 性能方面的提示
- URL重写指南
- Apache虚拟主机文档
- 基于主机名的虚拟主机
- 基于IP地址的虚拟主机
- 大批量虚拟主机的动态配置
- 虚拟主机示例
- 深入研究虚拟主机的匹配
- 文件描述符限制
- 关于DNS和Apache
- 常见问题
- 经常问到的问题
- Apache的SSL/TLS加密
- SSL/TLS高强度加密:绪论
- SSL/TLS高强度加密:兼容性
- SSL/TLS高强度加密:如何...?
- SSL/TLS Strong Encryption: FAQ
- 如何.../指南
- 认证、授权、访问控制
- CGI动态页面
- 服务器端包含入门
- .htaccess文件
- 用户网站目录
- 针对特定平台的说明
- 在Microsoft Windows中使用Apache
- 在Microsoft Windows上编译Apache
- Using Apache With Novell NetWare
- Running a High-Performance Web Server on HPUX
- The Apache EBCDIC Port
- 服务器和支持程序
- httpd - Apache超文本传输协议服务器
- ab - Apache HTTP服务器性能测试工具
- apachectl - Apache HTTP服务器控制接口
- apxs - Apache 扩展工具
- configure - 配置源代码树
- dbmmanage - 管理DBM格式的用户认证文件
- htcacheclean - 清理磁盘缓冲区
- htdbm - 操作DBM密码数据库
- htdigest - 管理用于摘要认证的用户文件
- httxt2dbm - 生成RewriteMap指令使用的dbm文件
- htpasswd - 管理用于基本认证的用户文件
- logresolve - 解析Apache日志中的IP地址为主机名
- rotatelogs - 滚动Apache日志的管道日志程序
- suexec - 在执行外部程序之前切换用户
- 其他程序
- 杂项文档
- 与Apache相关的标准
- Apache模块
- 描述模块的术语
- 描述指令的术语
- Apache核心(Core)特性
- Apache MPM 公共指令
- Apache MPM beos
- Apache MPM event
- Apache MPM netware
- Apache MPM os2
- Apache MPM prefork
- Apache MPM winnt
- Apache MPM worker
- Apache模块 mod_actions
- Apache模块 mod_alias
- Apache模块 mod_asis
- Apache模块 mod_auth_basic
- Apache模块 mod_auth_digest
- Apache模块 mod_authn_alias
- Apache模块 mod_authn_anon
- Apache模块 mod_authn_dbd
- Apache模块 mod_authn_dbm
- Apache模块 mod_authn_default
- Apache模块 mod_authn_file
- Apache模块 mod_authnz_ldap
- Apache模块 mod_authz_dbm
- Apache模块 mod_authz_default
- Apache模块 mod_authz_groupfile
- Apache模块 mod_authz_host
- Apache模块 mod_authz_owner
- Apache模块 mod_authz_user
- Apache模块 mod_autoindex
- Apache模块 mod_cache
- Apache模块 mod_cern_meta
- Apache模块 mod_cgi
- Apache模块 mod_cgid
- Apache模块 mod_charset_lite
- Apache模块 mod_dav
- Apache模块 mod_dav_fs
- Apache模块 mod_dav_lock
- Apache模块 mod_dbd
- Apache模块 mod_deflate
- Apache模块 mod_dir
- Apache模块 mod_disk_cache
- Apache模块 mod_dumpio
- Apache模块 mod_echo
- Apache模块 mod_env
- Apache模块 mod_example
- Apache模块 mod_expires
- Apache模块 mod_ext_filter
- Apache模块 mod_file_cache
- Apache模块 mod_filter
- Apache模块 mod_headers
- Apache模块 mod_ident
- Apache模块 mod_imagemap
- Apache模块 mod_include
- Apache模块 mod_info
- Apache模块 mod_isapi
- Apache模块 mod_ldap
- Apache模块 mod_log_config
- Apache模块 mod_log_forensic
- Apache模块 mod_logio
- Apache模块 mod_mem_cache
- Apache模块 mod_mime
- Apache模块 mod_mime_magic
- Apache模块 mod_negotiation
- Apache模块 mod_nw_ssl
- Apache模块 mod_proxy
- Apache模块 mod_proxy_ajp
- Apache模块 mod_proxy_balancer
- Apache模块 mod_proxy_connect
- Apache模块 mod_proxy_ftp
- Apache模块 mod_proxy_http
- Apache模块 mod_rewrite
- Apache模块 mod_setenvif
- Apache模块 mod_so
- Apache模块 mod_speling
- Apache模块 mod_ssl
- Apache模块 mod_status
- Apache模块 mod_suexec
- Apache模块 mod_unique_id
- Apache模块 mod_userdir
- Apache模块 mod_usertrack
- Apache模块 mod_version
- Apache模块 mod_vhost_alias
- Developer Documentation for Apache 2.0
- Apache 1.3 API notes
- Debugging Memory Allocation in APR
- Documenting Apache 2.0
- Apache 2.0 Hook Functions
- Converting Modules from Apache 1.3 to Apache 2.0
- Request Processing in Apache 2.0
- How filters work in Apache 2.0
- Apache 2.0 Thread Safety Issues
- 词汇和索引
- 词汇表
- 指令索引
- 指令速查
- 模块索引
- 站点导航