Apache組態片段


組態檔案中的指令可能適用於整個伺服器,或者它們可能僅限於應用於特定目錄,檔案,主機或URL。本文件描述了如何使用組態片段容器或.htaccess檔案來更改其他組態指令的範圍。

組態片段容器的型別

有兩種基本型別的容器。大多數容器針對每個請求都會進行評估。隨附的指令僅適用於與容器匹配的請求。另一方面,<IfDefine><IfModule><IfVersion>容器僅在伺服器啟動和重新啟動時進行評估。如果糨們的條件在啟動時為真,那麼所附的指令將適用於所有請求。如果條件不為真,則將忽略所附的指令。

<IfDefine>指令包含只有在httpd命令列中定義了適當引數時才會應用的指令。例如,使用以下組態,僅當使用httpd -DClosedForNow啟動伺服器時,所有請求才會重定向到另一個站點:

<IfDefine ClosedForNow>
    Redirect / http://otherserver.example.com/
</IfDefine>

<IfModule>指令與上面<IfDefine>指令也非常相似,除了它包含只有在伺服器中有特定模組可用時才會應用的指令。模組必須在伺服器中靜態編譯,或者必須動態編譯,並且其LoadModule行必須在組態檔案中更早。只有在需要組態檔案才能使用該命令時,才能使用該指令,無論是否安裝了某些模組。它不應該用於包含您希望一直工作的指令,因為它可以抑制有關丟失模組的有用錯誤訊息。

在以下範例中,僅當mod_mime_magic可用時才會應用MimeMagicFile指令。

<IfModule mod_mime_magic.c>
    MimeMagicFile conf/magic
</IfModule>

<IfVersion>指令與<IfDefine><IfModule>非常相似,只不過它包含的指令只會在特定版本的伺服器執行時才會應用。該模組設計用於測試套件和大型網路,這些網路必須處理不同的httpd版本和不同的組態。

<IfVersion >= 2.1>
    # this happens only in versions greater or
    # equal 2.1.0.
</IfVersion>

<IfDefine><IfModule><IfVersion>可以通過在測試前加上!符號來應用否定條件。此外,這些部分可以巢狀以實現更複雜的限制。

檔案系統和網站空間

最常用的組態節容器是更改檔案系統或網站空間中特定位置的組態的容器。首先,了解兩者之間的區別非常重要。檔案系統是作業系統可以看到的磁碟檢視。例如,在預設安裝中,Apache位於Unix檔案系統中的/usr/local/apache2或Windows檔案系統中的「C:/Program Files/Apache Group/Apache2中。(請注意,正斜槓應始終用作Apache中的路徑分隔符,即使對於Windows也是如此。)相反,網站空間是由Web伺服器提供並由用戶端檢視的站點檢視。因此,webspace中的path/dir/對應於Unix上預設Apache安裝的檔案系統中的路徑/usr/local/apache2/htdocs/dir/。網站空間不需要直接對映到檔案系統,因為網頁可以從資料庫或其他位置動態生成。

檔案系統容器

<Directory><Files>指令及其正規表示式對應項將指令應用於檔案系統的某些部分。包含在<Directory>部分中的指令適用於指定的檔案系統目錄和該目錄的所有子目錄(以及這些目錄中的檔案)。使用.htaccess檔案可以獲得相同的效果。例如,在以下組態中,將為/var/web/dir1目錄和所有子目錄啟用目錄索引。

<Directory /var/web/dir1>
    Options +Indexes
</Directory>

包含在<Files>部分中的指令適用於具有指定名稱的任何檔案,無論它位於何種目錄中。例如,以下組態指令在放置在組態檔案的主部分時將拒絕存取任何檔案。檔案名為private.html,無論它在哪裡找到。

<Files "private.html">
    Require all denied
</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">
        Require all denied
    </Files>
</Directory>

Webspace容器

另一方面,<Location>指令及其正規表示式對應方更改了Webspace中內容的組態。例如,以下組態可防止存取以/private開頭的任何URL路徑。它將適用於http://yoursite.example.com/privatehttp://yoursite.example.com/private123http://yoursite.example.com/private/dir/file的請求。html以及以/private字串開頭的任何其他請求。

<LocationMatch "^/private">
    Require all denied
</LocationMatch>

<Location>指令不需要與檔案系統有任何關係。例如,以下範例顯示如何將特定URL對映到mod_status提供的內部Apache HTTP Server處理程式。檔案系統中不需要存在稱為伺服器狀態的檔案。

<Location "/server-status">
    SetHandler server-status
</Location>

重疊的Webspace

為了有兩個重疊的URL,必須考慮評估某些部分或指令的順序。對於<Location>將是:

<Location "/foo">
</Location>
<Location "/foo/bar">
</Location>

另一方面,<Alias>對映反之亦然:

Alias "/foo/bar" "/srv/www/uncommon/bar"
Alias "/foo"     "/srv/www/common/foo"

ProxyPass指令也是如此:

ProxyPass "/special-area" "http://special.example.com" smax=5 max=10
ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofailover=On

萬用字元和正規表示式

<Directory><Files><Location>指令都可以使用shell樣式的萬用字元,如C標準庫中的fnmatch。字元*匹配任何字元序列,? 匹配任何單個字元,[seq]匹配seq中的任何字元。/字元不會被任何萬用字元匹配;

如果需要更靈活的匹配,每個容器都有一個正規表示式(正規表示式)對應<DirectoryMatch><FilesMatch><LocationMatch>,它們允許在選擇匹配時使用與perl相容的正規表示式。但請參閱下面有關組態合併的部分,以了解使用正規表示式部分將如何更改指令的應用方式。

更改所有使用者目錄組態的非正規表示式萬用字元部分可能如下所示:

<Directory "/home/*/public_html">
    Options Indexes
</Directory>

使用正規表示式部分,可以一次拒絕存取多種型別的影象檔案:

<FilesMatch "\.(?i:gif|jpe?g|png)$">
    Require all denied
</FilesMatch>

包含命名組和反向參照的正規表示式將新增到環境中,並以大寫形式顯示相應的名稱。這允許從表示式和模組(如mod_rewrite)中參照檔案名路徑和URL的元素。

<DirectoryMatch "^/var/www/combined/(?<SITENAME>[^/]+)">
    require ldap-group "cn=%{env:MATCH_SITENAME},ou=combined,o=Example"
</DirectoryMatch>

布林表示式
<If>指令根據可由布林表示式表示的條件更改組態。例如,如果HTTP Referer檔頭不以http://www.example.com/開頭,則以下組態拒絕存取。

<If "!(%{HTTP_REFERER} -strmatch 'http://www.example.com/*')">
    Require all denied
</If>

什麼時候用什麼?

在檔案系統容器和webspace容器之間進行選擇實際上非常簡單。將指令應用在位於檔案系統中的物件時,請始終使用<Directory><Files>。將指令應用於不駐留在檔案系統中的物件(例如從資料庫生成的網頁)時,請使用<Location>

在嘗試限制對檔案系統中物件的存取時,不要使用<Location>。這是因為許多不同的網站空間位置(URL)可以對映到相同的檔案系統位置,從而可以規避限制。例如,請考慮以下組態:

<Location "/dir/">
    Require all denied
</Location>

如果請求是http://yoursite.example.com/dir/,這可以正常工作。但是,如果使用不區分大小寫的檔案系統呢? 然後,通過請求http://yoursite.example.com/DIR/可以輕鬆規避限制。相反,<Directory>指令將適用於從該位置提供的任何內容,無論其如何呼叫。(檔案系統連結是一個例外。使用符號連結可以將同一目錄放在檔案系統的多個部分中。<Directory>指令將遵循符號連結而不重置路徑名。因此,為了最高階別的安全性,符號 應使用適當的Options指令禁用連結。)

如果因為使用區分大小寫的檔案系統而認為這些都不適用,請記住,還有許多其他方法可將多個網站空間位置對映到同一檔案系統位置。因此,應該始終使用檔案系統容器。但是,這條規則有一個例外。將組態限制放在<Location "/">部分是非常安全的,因為無論具體的URL如何,本節都將適用於所有請求。