Apache HTTP 伺服器 2.4 版
驗證與授權程序中包含三種類型的模組。您通常需要從每一個群組中選擇至少一個模組。
AuthType
指令)
AuthBasicProvider
和 AuthDigestProvider
指令)
Require
指令)
除了這些模組,還有 mod_authn_core
和 mod_authz_core
。這些模組實作核心指令,核心對於所有認證模組都很重要。
模組 mod_authnz_ldap
既是驗證,也是授權提供者。模組 mod_authz_host
提供授權和存取控制,根據主機名稱、IP 位址或要求特性,但不屬於驗證提供者系統的一部分。為了與 mod_access 向下相容,還有一個新的模組 mod_access_compat
。
您可能也想要了解一下(討論如何控制伺服器存取的各種方式)存取控制指南。
如果您網站上的資訊很敏感,或只提供給一小群人,這篇文章中的技巧將可以協助您確保看到這些網頁的人,正是您想要讓他們看到的人。
這篇文章包含您大多會使用的「標準」方法,用來保護您的網站部分內容。
如果您的資料真的需要加強安全性,請考慮使用 mod_ssl
,作為任何認證的補充方式。
本文說明的指令需要放在您的主伺服器設定檔(通常在 <Directory>
區段)或各目錄設定檔(.htaccess
檔)。
如果您計畫使用 .htaccess
檔,您需要擁有伺服器設定,允許將認證指令放入這些檔中。這可以使用 AllowOverride
指令執行,此指令會指定哪些指令(如有)可以放入各目錄設定檔中。
既然我們是在此討論認證,您將需要一個類似的 AllowOverride
指令
AllowOverride AuthConfig
或者,如果您只要將指令直接放入主伺服器設定檔中,您當然需要具有寫入該檔的權限。
您也需要稍微了解伺服器目錄結構,才能知道某些檔案存放的位置。這不應該太難,當我們說明到那個重點時,我會盡量講解清楚。
您也需要確定 mod_authn_core
和 mod_authz_core
模組已內建於 httpd 二進位檔,或由 httpd.conf 設定檔載入。這兩個模組都提供核心指令和功能,對於網路上使用驗證和授權的設定和使用非常重要。
以下是伺服器目錄密碼保護基礎知識。
首先,您需要建立一個密碼檔案。如何執行此動作會因您所選擇的驗證提供者而異。稍後將再詳細解說。一開始,我們將使用一個純文字密碼檔案。
此檔案應放置在無法從網際網路存取的位置。這樣一來,使用者就無法下載密碼檔案。例如,假設您的文件放置在 /usr/local/apache/htdocs
,您可能需要將密碼檔案放置在 /usr/local/apache/passwd
。
若要建立檔案,請使用隨 Apache 附帶的 htpasswd
程式。此程式會位於您安裝 Apache 的 bin
目錄。如果您透過第三方套件安裝 Apache,它可能會在您的執行路徑中。
若要建立檔案,請輸入
htpasswd -c /usr/local/apache/passwd/passwords rbowen
htpasswd
會要求您提供密碼,然後要求您再次輸入以確認
# htpasswd -c /usr/local/apache/passwd/passwords rbowen
新密碼:mypassword
重新輸入新密碼:mypassword
正在為使用者 rbowen 新增密碼
當然,如果 htpasswd
不在您的路徑中,您必須輸入檔案的全路徑才能執行。於預設安裝中,它位於 /usr/local/apache2/bin/htpasswd
接下來,您需要設定伺服器以要求提供密碼,並告知伺服器允許哪些使用者存取。您可以透過編輯 httpd.conf
檔案或使用 .htaccess
檔案執行此動作。例如,如果您想保護目錄 /usr/local/apache/htdocs/secret
,您可以使用以下指令,放入檔案 /usr/local/apache/htdocs/secret/.htaccess
中,或放入 httpd.conf
中的 <Directory "/usr/local/apache/htdocs/secret"> 區段中。
AuthType Basic AuthName "Restricted Files" # (Following line optional) AuthBasicProvider file AuthUserFile "/usr/local/apache/passwd/passwords" Require user rbowen
讓我們逐一檢視每個指令。AuthType
指令會選擇用於驗證使用者的方法。最常見的方法是 Basic
,此方法由 mod_auth_basic
執行。但是,請務必了解 Basic 驗證會以未加密的方式將密碼從客戶端傳送到伺服器。因此,除非搭配使用 mod_ssl
,否則不應使用這種方法來處理高度敏感的資料。Apache 支援另一種驗證方法:AuthType Digest
。此方法由 mod_auth_digest
執行,旨在提供更高的安全性。現在已不再如此,而應該改用 mod_ssl
加密連線。
變數 AuthName
會設定 區域 以用於認證中。此區域具備兩個主要功能。首先,用戶端通常會將此資訊顯示給使用者作為密碼對話框的一部分。其次,客戶端會使用此資訊以判斷針對給定認證區域傳送哪個密碼。
因此,舉例來說,在用戶端於 "受限檔案"
區域進行認證後,它將會自動為同一伺服器上的任何區域重試相同的密碼,而該區域則標示為 "受限檔案"
區域。因此,您可以透過讓多個受限區域共用相同區域,避免使用者的密碼遭多次提示。當然,基於安全考量,伺服器的主機名稱發生變更時,用戶端總是需要再次詢問密碼。
在這個案例中,file
是此變數的預設值,因此變數 AuthBasicProvider
是選用的。如果您選擇其他認證來源,例如 mod_authn_dbm
或 mod_authn_dbd
,就需要使用此變數。
變數 AuthUserFile
會設定密碼檔案路徑,我們剛使用 htpasswd
建立這項檔案。如果您有大量的使用者,搜尋純文字檔以在每次要求時對使用者進行認證,可能會相當緩慢。Apache 也有能力將使用者資訊儲存在快速的資料庫檔中。mod_authn_dbm
模組提供 AuthDBMUserFile
變數。這些檔案可以使用 dbmmanage
及 htdbm
程式建立並操作。還有許多其他類型的認證選項可自第三方模組取得。
最後,Require
變數會透過設定被允許存取此伺服器區域的使用者來提供處理程序的授權部分。在下一部分中,我們會探討如何使用 Require
變數。
上述變數只允許一人(特別是使用者名稱為 rbowen
的人)進入目錄。在大部分案例中,您會想要允許多人進入。這正是 AuthGroupFile
變數派上用場之處。
如果您想要讓多人進入,您需要建立一個群組檔案,將群組名稱與該群組中使用者清單關聯在一起。此檔案格式非常簡單,您可以使用您最喜歡的編輯器建立檔案。檔案內容如下
GroupName: rbowen dpitts sungo rshersey
這只是一個成員清單,由空格分隔,並排列成長行。
若要將使用者新增至您現有的密碼檔案,請輸入
htpasswd /usr/local/apache/passwd/passwords dpitts
您會收到與先前相同的回應,但它將附加至現有檔案,而不是建立新檔案。(是 -c
建立新的密碼檔案)
現在,您需要修改 .htaccess
檔案或 <Directory>
區塊,如下所示
AuthType Basic AuthName "By Invitation Only" # Optional line: AuthBasicProvider file AuthUserFile "/usr/local/apache/passwd/passwords" AuthGroupFile "/usr/local/apache/passwd/groups" Require group GroupName
現在,任何列在 GroupName
群組中,且在 password
檔案中有輸入資料的任何人,如果輸入正確的密碼,將會被允許進入。
還有一種方法可以讓多位使用者進入,而這種方式較不具體。與其建立群組檔案,您可以使用下列指令
Require valid-user
使用它,而不是 Require user rbowen
列,將允許任何人列在密碼檔案中,並正確輸入其密碼。
由於基本驗證的指定方式,每次您從伺服器要求文件時,都必須驗證您的使用者名稱和密碼。即使您重新載入同一頁面,以及頁面上的每個影像(如果來自受保護的目錄)。正如您所想像的,這會稍微減慢一些。它變慢的程度與密碼檔案的大小成正比,因為它必須開啟該檔案,並向下瀏覽使用者清單,直到找到您的名稱。而且它必須在每次載入頁面時執行此操作。
這會帶來一個後果,就是您能放入一個密碼檔案的使用者數是有實際限制的。此限制會根據您特定伺服器主機的效能而有所不同,但如果您超過數百個輸入,您可以預期會變慢,並可能希望在那個時候考慮不同的驗證方法。
由於將密碼儲存在純文字檔案中有上述問題,您可能希望將密碼儲存在其他地方,例如資料庫。
mod_authn_dbm
和 mod_authn_dbd
是兩個讓此項操作成為可能的模組。與其選擇
,您可以選擇 AuthBasicProvider
filedbm
或 dbd
作為儲存格式。
例如要選擇 dmb 檔案而非文字檔案
<Directory "/www/docs/private"> AuthName "Private" AuthType Basic AuthBasicProvider dbm AuthDBMUserFile "/www/passwords/passwd.dbm" Require valid-user </Directory>
其他選項可用。請諮詢 mod_authn_dbm
文件以取得更多詳細資料。
隨著基於提供者的新身分驗證和授權架構引進,您不再受限於單一的身分驗證或授權方法。事實上,您可以混搭任意數量的提供者,以提供完全符合您需求的方案。在以下範例中同時使用了檔案和 LDAP 基於的身分驗證提供者。
<Directory "/www/docs/private"> AuthName "Private" AuthType Basic AuthBasicProvider file ldap AuthUserFile "/usr/local/apache/passwd/passwords" AuthLDAPURL ldap://ldaphost/o=yourorg Require valid-user </Directory>
在這個範例中,檔案提供者會先嘗試驗證使用者。如果無法驗證使用者,LDAP 提供者就會被呼叫。只要您的組織實作超過一種身分驗證儲存類型,這樣就能擴大身分驗證的範圍。其他身分驗證和授權情境可能包括將一種身分驗證與不同類型的授權混合。例如,針對密碼檔案進行身分驗證,但針對 LDAP 目錄進行授權。
除了可以實作多重的身分驗證提供者外,也可以使用多重的授權方法。在這個範例中同時使用了檔案群組授權和 LDAP 群組授權。
<Directory "/www/docs/private"> AuthName "Private" AuthType Basic AuthBasicProvider file AuthUserFile "/usr/local/apache/passwd/passwords" AuthLDAPURL ldap://ldaphost/o=yourorg AuthGroupFile "/usr/local/apache/passwd/groups" Require group GroupName Require ldap-group cn=mygroup,o=yourorg </Directory>
為了更進一步執行授權,權限容器指令例如 <RequireAll>
和 <RequireAny>
允許套用邏輯,因此可以透過設定完全控制處理授權的順序。請參閱 權限容器 以取得可以套用的範例。
現在可以套用的授權方式比只針對單一資料儲存進行單一檢查更彈性。現在可以進行排序、邏輯,並選擇如何執行授權。
控制如何以及以什麼順序套用授權過去一直有些難以理解。在 Apache 2.2 中引進了一個基於提供者的身分驗證機制,以將實際身分驗證流程與授權和支援功能分離。其中一個好處是,身分驗證提供者可以按照特定順序來設定和呼叫,而不依賴於驗證模組本身的載入順序。相同的基於提供者的機制也引進了授權。這表示 Require
指令不僅會指定應使用哪些授權方法,也會指定呼叫它們的順序。在設定中出現 Require
指令的順序,會對應到相同順序呼叫多重授權方法。
藉著引入授權容器指令,例如 <RequireAll>
和 <RequireAny>
,設定檔可以控制何時呼叫授權方法,以及哪些準則可判定何時授權存取。請參閱 授權容器 的範例,了解如何使用它們來表達複雜的授權邏輯。
預設所有 Require
指令會處理,如同包含在 <RequireAny>
容器指令中。換句話說,只要有任一指定的授權方法會成功,授權就會成功。
使用使用者名稱和密碼進行驗證只是其中的一部分。你常常會想讓使用者使用除了他們的身分以外的資訊來登入。可能是他們來自何處等資訊。
授權提供者 all
、env
、host
和 ip
讓你根據其他與主機相關的準則(例如主機名稱或要求文件之電腦的 IP 位址),來允許或拒絕存取。
使用這些提供者的方式透過 Require
指令來指定。此指令會在請求處理的授權階段,註冊將會呼叫的授權提供者。例如
Require ip address
其中 address 是 IP 位址(或部分 IP 位址)或
Require host domain_name
其中 domain_name 是完全限定的網域名稱(或部分網域名稱);如果你希望,你可以提供多個位址或網域名稱。
例如,如果你有其他人對你的留言板發垃圾訊息,而且你想要拒絕他們,你可以執行下列動作
<RequireAll> Require all granted Require not ip 10.252.46.165 </RequireAll>
來自該位址的訪客將無法看到此指令保護的內容。如果你有電腦名稱而非 IP 位址,你可以使用它。
<RequireAll> Require all granted Require not host host.example.com </RequireAll>
而且,如果你想要封鎖整個網域的存取,你可以只指定位址或網域名稱的一部分
<RequireAll> Require all granted Require not ip 192.168.205 Require not host phishers.example.com moreidiots.example Require not host ke </RequireAll>
如果使用 <RequireAll>
包含多個 <Require>
指令,每個指令都使用 not
否定,只有在所有否定的條件都為真的時候,才會允許存取。換句話說,只要任何否定的條件失敗,存取就會被封鎖。
採用基於提供者的驗證機制所帶來的一個副作用,就是以往的存取控制指令 Order
、Allow
、Deny
和 Satisfy
不再需要。不過,為了提供舊有組態的向下相容性,這些指令已被移至 mod_access_compat
模組中。
mod_access_compat
所提供的指令已被 mod_authz_host
棄用。混合使用舊有的指令(例如 Order
、Allow
或 Deny
)和新指令(例如 Require
)在技術上可行,但並不鼓勵。mod_access_compat
模組的建立是為了支援只包含舊有指令的組態,以利於 Apache 2.4 升級作業。如需更多資訊,請參閱 升級指南。
有時,驗證會對提供者或您的網路造成無法接受的負載。這最可能影響 mod_authn_dbd
(或第三方/自訂提供者)的使用者。為了解決這個問題,HTTPD 2.3/2.4 推出了新的快取提供者 mod_authn_socache
,以快取認證資料並減少原始提供者上的負載。
這可能會為部分使用者帶來大幅的效能提升。
您也應該閱讀 mod_auth_basic
和 mod_authz_host
的文件,其中含有這些運作方式的更多相關資訊。指令 <AuthnProviderAlias>
也有助於簡化特定驗證組態。
密碼加密說明了 Apache 支援的各種驗證資料加密方式。
您可能還想看看 存取控制操作指南,其中討論了許多相關主題。