# 配置段(容器)
[配置文件](#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
- 詞匯和索引
- 詞匯表
- 指令索引
- 指令速查
- 模塊索引
- 站點導航