Apache HTTP Server 版本2.2
配置文件中指令的作用范圍可能是整個服務(wù)器,也可能是特定的目錄、文件、主機、URL。本文闡述如何使用配置段(容器)以及.htaccess
文件來改變配置指令的作用范圍。
相關(guān)模塊 | 相關(guān)指令 |
---|---|
容器有兩種基本類型。大多數(shù)容器是針對各個請求的,包含于其中的指令僅對與該容器匹配的請求起作用,而容器<IfDefine>
、<IfModule>
、<IfVersion>
僅在啟動和重新啟動中起作用,如果在啟動時指定的條件成立,則其中的指令對所有的請求都有效,否則將被忽略。
<IfDefine>
容器中的指令只有在httpd
命令行中設(shè)定了特定的參數(shù)后才有效。下例中,只有在服務(wù)器用 httpd -DClosedForNow
方式啟動時,所有的請求才會被重定向到另一個站點:
<IfDefine ClosedForNow>
Redirect / http://otherserver.example.com/
</IfDefine>
<IfModule>
容器很相似,但是其中的指令只有當服務(wù)器啟用特定的模塊時才有效(或是被靜態(tài)地編譯進了服務(wù)器,或是被動態(tài)裝載進了服務(wù)器),注意,配置文件中該模塊的裝載指令LoadModule
行必須在出現(xiàn)在此容器之前。這個容器應(yīng)該僅用于你希望無論特定模塊是否安裝,配置文件都能正常運轉(zhuǎn)的場合;而不應(yīng)該用于容器中的指令在任何情況下都必須生效的場合,因為它會抑制類似模塊沒找到之類的有用出錯信息。
下例中,MimeMagicFiles
指令僅當mod_mime_magic
模塊啟用時才有效。
<IfModule mod_mime_magic.c>
MimeMagicFile conf/magic
</IfModule>
<IfVersion>
指令與<IfDefine>
和<IfModule>
很相似,但是其中的指令只有當正在執(zhí)行的服務(wù)器版本與指定的版本要求相符時才有效。這個模塊被設(shè)計用于測試套件、以及在一個存在多個不同httpd版本的大型網(wǎng)絡(luò)中需要分別針對不同版本使用不同配置的情況。
<IfVersion >= 2.1>
# 僅在版本高于 2.1.0 的時候才生效
</IfVersion>
<IfDefine>
、<IfModule>
、<IfVersion>
都可以在條件前加一個"!"以實現(xiàn)條件的否定,而且都可以嵌套以實現(xiàn)更復(fù)雜的配置。
最常用的配置段是針對文件系統(tǒng)和網(wǎng)絡(luò)空間特定位置的配置段。首先必須理解文件系統(tǒng)和網(wǎng)絡(luò)空間這兩個概念的區(qū)別,文件系統(tǒng)是指操作系統(tǒng)所看見的磁盤視圖,比如,在Unix文件系統(tǒng)中,Apache會被默認安裝到/usr/local/apache2
,在Windows文件系統(tǒng)中,Apache會被默認安裝到"C:/Program Files/Apache Group/Apache2"
(注意:Apache始終用正斜杠而不是反斜杠作為路徑的分隔符,即使是在Windows中)。相反,網(wǎng)絡(luò)空間是網(wǎng)站被web服務(wù)器發(fā)送以及被客戶在瀏覽器中所看到的視圖。所以網(wǎng)絡(luò)空間中的路徑/dir/
在Apache采用默認安裝路徑的情況下對應(yīng)于Unix文件系統(tǒng)中的路徑/usr/local/apache2/htdocs/dir/
。由于網(wǎng)頁可以從數(shù)據(jù)庫或其他地方動態(tài)生成,因此,網(wǎng)絡(luò)空間無須直接映射到文件系統(tǒng)。
<Directory>
和<Files>
指令與其相應(yīng)的正則表達式版本(<DirectoryMatch>
和<FilesMatch>
)一起作用于文件系統(tǒng)的特定部分。<Directory>
配置段中的指令作用于指定的文件系統(tǒng)目錄及其所有子目錄,.htaccess文件可以達到同樣的效果。下例中,/var/web/dir1
及其所有子目錄被允許進行目錄索引。
<Directory /var/web/dir1>
Options +Indexes
</Directory>
<Files>
配置段中的指令作用于特定的文件名,而無論這個文件實際存在于哪個目錄。下例中的配置指令如果出現(xiàn)在配置文件的主服務(wù)器段,則會拒絕對位于任何目錄下的private.html
的訪問。
<Files private.html>
Order allow,deny
Deny from all
</Files>
<Files>
和<Directory>
段的組合可以作用于文件系統(tǒng)中的特定文件。下例中的配置會拒絕對 /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>
指令與其相應(yīng)的正則表達式版本(<LocationMatch>
)一起作用于網(wǎng)絡(luò)空間的特定部分。下例中的配置會拒絕對任何以"/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>
指令與文件系統(tǒng)無關(guān),下例演示了如何將特定的URL映射到Apache內(nèi)部的處理器mod_status
,而并不要求文件系統(tǒng)中確實存在server-status
文件。
<Location /server-status>
SetHandler server-status
</Location>
<Directory>
、<Files>
、<Location>
指令可以使用與C標準庫中的fnmatch
類似的shell風格的通配符。"*"匹配任何字符串,"?"匹配任何單個的字符,"[seq]"匹配seq序列中的任何字符,符號"/"不被任何通配符所匹配,所以必須顯式地使用。
如果需要更復(fù)雜的匹配,這些容器都有一個對應(yīng)的正則版本:<DirectoryMatch>
、<FilesMatch>
、<LocationMatch>
,可以使用與Perl兼容的正則表達式,以提供更復(fù)雜的匹配。但是還必須注意下面配置段的合并部分關(guān)于使用正則表達式會如何作用于配置指令的內(nèi)容。
下例使用非正則表達式的通配符來改變所有用戶目錄的配置:
<Directory /home/*/public_html>
Options Indexes
</Directory>
下例使用正則表達式一次性拒絕對多種圖形文件的訪問:
<FilesMatch \.(?i:gif|jpe?g|png)$>
Order allow,deny
Deny from all
</FilesMatch>
選擇使用文件系統(tǒng)容器還是使用網(wǎng)絡(luò)空間容器其實很簡單。當指令應(yīng)該作用于文件系統(tǒng)時,總是用<Directory>
或<Files>
;而當指令作用于不存在于文件系統(tǒng)的對象時,就用<Location>
,比如一個由數(shù)據(jù)庫生成的網(wǎng)頁。
絕對不要試圖用<Location>
去限制對文件系統(tǒng)中的對象的訪問,因為許多不同的網(wǎng)絡(luò)空間路徑可能會映射到同一個文件系統(tǒng)目錄,從而導(dǎo)致你的訪問限制被突破。比如:
<Location /dir/>
Order allow,deny
Deny from all
</Location>
上述配置對http://yoursite.example.com/dir/
請求的確起作用。但是設(shè)想在一個不區(qū)分大小寫的文件系統(tǒng)中,這個訪問限制會被http://yoursite.example.com/DIR/
請求輕易突破。而<Directory>
指令才會真正作用于對這個位置的任何形式的請求。但是有一個例外,就是Unix文件系統(tǒng)中的符號連接(軟連接),符號連接可以使同一個目錄出現(xiàn)在文件系統(tǒng)中的多個位置。<Directory>
指令將不重設(shè)路徑名而直接追蹤符號連接,因此,對于安全要求最高的,應(yīng)該用Options
指令禁止對符號連接的追蹤。
不要認為使用大小寫敏感的文件系統(tǒng)就無所謂了,因為有很多方法可以將不同的網(wǎng)絡(luò)空間路徑映射到同一個文件系統(tǒng)路徑,所以,應(yīng)當盡可能使用文件系統(tǒng)容器。但是也有一個例外,就是把訪問限制放在<Location />
配置段中可以很安全地作用于除了某些特定URL以外的所有URL。
<VirtualHost>
容器作用于特定的虛擬主機,為同一個機器上具有不同配置的多個主機提供支持。詳見虛擬主機文檔。
<Proxy>
和<ProxyMatch>
容器中的指令僅作用于通過mod_proxy
代理服務(wù)器訪問的、與指定URL匹配的站點。下例中的配置會拒絕通過代理服務(wù)器訪問cnn.com
站點。
<Proxy http://cnn.com/*>
Order allow,deny
Deny from all
</Proxy>
查閱指令的作用域,就可以知道哪些指令可以出現(xiàn)在哪些配置段中。從語法上看,允許在<Directory>
段中使用的指令當然也可以在<DirectoryMatch>
、<Files>
、<FilesMatch>
、<Location>
、<LocationMatch>
、<Proxy>
、<ProxyMatch>
段中使用,但也有例外:
AllowOverride
指令只能出現(xiàn)在<Directory>
段中。Options
中的FollowSymLinks
和SymLinksIfOwnerMatch
只能出現(xiàn)在<Directory>
段或者.htaccess
文件中。Options
指令不能用于<Files>
和<FilesMatch>
段。配置段會按非常特別的順序依次生效,由于這會對配置指令的處理結(jié)果產(chǎn)生重大影響,因此理解它的流程非常重要。
合并的順序是:
<Directory>
(除了正則表達式)和.htaccess
同時處理;(如果允許的話,.htaccess
的設(shè)置會覆蓋<Directory>
的設(shè)置)<DirectoryMatch>
(和<Directory ~>
)<Files>
和<FilesMatch>
同時處理<Location>
和<LocationMatch>
同時處理除了<Directory>
,每個組都按它們在配置文件中出現(xiàn)的順序被依次處理,而<Directory>
(上面的第1組),會按字典順序由短到長被依次處理。例如:<Directory /var/web/dir>
會先于<Directory /var/web/dir/subdir>
被處理。如果有多個指向同一個目錄的<Directory>
段,則按它們在配置文件中的順序被依次處理。用Include
指令包含進來的配置被視為按原樣插入到Include
指令的位置。
位于<VirtualHost>
容器中的配置段在外部對應(yīng)的段處理完畢以后再處理,這樣就允許虛擬主機覆蓋主服務(wù)器的設(shè)置。
當請求是由mod_proxy
處理的時候,<Proxy>
容器將會在處理順序中取代<Directory>
容器的位置。
后面的段覆蓋前面的相應(yīng)的段。
Aliases
和DocumentRoots
來映射URL到文件系統(tǒng))之前,會有一個<Location>
/<LocationMatch>
的序列被處理,而在名稱翻譯結(jié)束后,這個序列的處理結(jié)果則被完全拋棄。
這是一個演示合并順序的例子。如果這些指令都起作用,則會按 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>
段將會被最后處理,從而會允許不加限制的對服務(wù)器的訪問,可見合并的順序是很重要的,千萬小心!
<Location />
Order deny,allow
Allow from all
</Location>
# 這個<Directory>段將不會實際生效
<Directory />
Order allow,deny
Allow from all
Deny from badguy.example.com
</Directory>