當某個組織添加應用程序和服務時,集中進行認證和密碼服務可以提高安全性,並減少管理和開發人員的難題。但是,將所有服務合並到一台服務器會導致可靠性問題。高可用性對於企業認證服務尤為重要,因為在許多情況下,當認證停止工作時,整個企業將陷於停頓。本文描述了我們該如何使用開放源碼軟件創建可靠的、高度可用的認證服務器。 我們使用的開放源碼軟件 我們使用 LDAp(輕量級目錄訪問協議(Lightweight Directory Access protocol))服務器來提供各種應用程序都可以訂閱的認證服務。為了提供高度可用的 LDAp 服務器,我們使用了 Linux-HA 倡議(www.linux-ha.org)的 heartbeat 軟件包。我們還提供了一個設置 Apache web 服務器以使用 LDAp 認證的示例。 有關 LDAp 的一些背景知識 我們使用 OpenLDAp 軟件包(www.openldap.org),幾個 Linux 分發版(distribution)都包含該軟件包。它同 RedHat 7.1 一起提供,目前可下載的版本是 2.0.11。 RFC 2251 和 2253 定義了 LDAp 標准。現有的幾個 LDAp 商業實現包括密歇根大學和 Netscape 實現。創建 OpenLDAp 基金會是要“共同致力於開發健壯的、商業級別的、功能完善的和開放源碼的 LDAp 應用程序和開發工具套件”(請參閱 www.openldap.org)。OpenLDAp 版本 1.0 發布於 1998 年 8 月。目前的主要版本是 2.0,發布於 2000 年 8 月 31 日,並且添加了 LDApv3 支持。 象任何優秀的網絡服務一樣,LDAp 被設計成可以跨多個服務器運行。本文使用了 LDAp 的兩個功能 — 復制和參照。 參照機制允許您跨多個服務器分割 LDAp 名稱空間,並且以層次結構的方式安排 LDAp 服務器。對於特定的目錄名稱空間,LDAp 只允許有一個主服務器。 復制是由 OpenLDAp 復制守護程序 slurpd 驅動的。Slurpd 會定期運行,檢查主服務器的日志文件以獲知任何更新。然後將更新推送到從服務器。讀取請求可以由任一服務器應答,而更新只能由主服務器執行。對從服務器的更新請求會生成一個參照消息,該消息將提供主服務器的地址。跟蹤參照及重新嘗試更新是客戶機的職責。OpenLDAp 無內置的方法來分發跨復制服務器的查詢,因此您必須使用 Ip 噴射器(sprayer)/扇出(fanout)程序,例如 balance。 為了實現可靠性目標,我們將兩台服務器連在一起形成群集。我們可以使用服務器之間共享的存儲器和一份可維護的數據副本。但是為了簡單起見,我們選擇執行非共享實現。LDAp 數據庫通常很小,且更新頻率很低(提示:如果您的 LDAp 數據集是大型的,請考慮利用參照將名稱空間劃分成多個較小的部分)。當重新啟動故障節點時,非共享設置確實需要多費心一些:在重新啟動之前,任何新的更改都必須添加到發生故障的節點的數據庫中。稍後我們將顯示一個示例。 群集軟件和配置 首先,讓我們澄清一個小小的混淆。大多數 HA(高可用性)群集都帶有稱為“心跳(heartbeat)”的系統持活功能。HA 軟件使用心跳來監控群集中節點的“健康”狀況。Linux-HA(www.linux-ha.org)小組提供了開放源碼群集軟件。他們的軟件包稱為 Heartbeat(目前是 Heartbeat-0.4.9)。這會導致一些可以理解的混淆(是的,它有時就令我困惑)。本文將 Linux-HA 軟件包稱為“Heartbeat”,而將一般的概念稱為“心跳”。 Linux-HA 項目開始於 1998 年,是 Linux-HA HOWTO(Haranld Milz 著)的產物。該項目目前由 Alan Robertson 領導,許多其他代碼提供者也參與其中。版本 0.4.9 於 2001 年初發布。 Heartbeat 通過通信介質(通常是串行設備和以太網)監控節點的“健康”狀況。最好有多個冗余介質,以便我們既可以使用串行線又可以使用以太網鏈接。每個節點運行一個守護程序進程(稱為“心跳”)。主守護程序派生出讀和寫每個心跳介質的子進程,以及狀態進程。當檢測到某個節點發生故障時,Heartbeat 運行 shell 腳本來啟動(或停止)輔助節點上的服務。按照設計,這些腳本使用與系統 init 腳本(通常位於 /etc/init.d 中)相同的語法。缺省腳本是為文件系統、Web 服務器和虛擬 Ip 故障轉移提供的。 假定有兩個匹配的 LDAp 服務器,我們可以使用幾個配置。首先,我們可以進行“冷備用(cold standby)”。主節點擁有一個虛擬 Ip 和一個運行的服務器。輔助節點將處於空閒狀態。一旦主節點發生故障,服務器實例和 Ip 將轉移到“冷”節點。這實現起來很簡單,但是主服務器和輔助服務器之間的數據同步可能是個問題。為了解決這個問題,我們可以利用兩個節點上的活動服務器配置群集。主節點運行主 LDAp 服務器,輔助節點運行從實例。對主服務器的更新會立即通過 slurpd 推送到從服務器。 點擊查看大圖 主節點發生故障後,由輔助節點響應查詢,但是現在我們還不能更新。為了能夠進行更新,在故障轉移時,我們將重新啟動輔助服務器,並將它提升為主服務器。 點擊查看大圖 這為我們提供了完整的 LDAp 服務,但是增加了 gotcha 問題 — 如果更新是對輔助服務器進行的,則在允許主服務器重新啟動之前,我們將不得不對其進行修正。Heartbeat 支持“良好的故障回復”選項,它可以禁止故障節點在故障轉移後重新獲取資源,我們可以將其設為首選項。本文將演示用手工進行的重新啟動。我們的樣本配置將使用 Heartbeat 提供的虛擬 Ip 工具。如果需要支持繁重的查詢負載,則利用 Ip 噴射器代替虛擬 Ip,將查詢分攤給主和從服務器。在這樣的情況下,對從服務器的更新請求將產生一個參照。對參照的後繼操作不是自動的;該功能必須內置到客戶機應用程序中。除了復制偽指令外,主節點和從節點的其余配置是相同的。主配置文件指明復制日志文件的位置(第 16 行)並包含從服務器的清單,這些服務器是帶有憑證信息的復制對象。(第 34-36 行)。 34 replica host=slave5:389 35 binddn="cn=Manager,dc=lcc,dc=ibm,dc=com"; 36 bindmethod=simple credentials=secret 從配置文件未指明主服務器;而是列出了復制所需的憑證。(第 33 行) 33 updatedn "cn=Manager,dc=lcc,dc=ibm,dc=com" 一般 Heartbeat 准備 可用的基本 Heartbeat 配置有幾個很好的示例(請參閱本文結尾處的參考資料)。下面是我們配置中的一些相關內容。我們的配置非常簡單,所以內容也不多。缺省情況下,所有配置文件都保存在 /etc/ha.d/ 中。 ha.cf 包含群集的全局定義。對於所有超時,我們都使用缺省值。 # Timeout intervals keepalive 2 # keepalive could be set to 1 second here deadtime 10 initdead 120 # define our communications # serial serialportname ... serial /dev/ttyS0 baud 19200 # Ethernet information udpport 694 udp eth1 # and finally, our node id's # node nodename ... -- must match uname -n node slave5 node slave6 haresources 這是配置故障轉移的地方。令人感興趣的內容位於該文件的底部。 slave6 192.168.10.51 slapd 這裡我們表明了三件事。資源的主要所有者是節點“slave6”(該名稱必須與您打算將其作為主節點的機器的“uname -n”輸出相符)。服務地址(虛擬 Ip)是“192.168.10.51”(該示例是在專用實驗室網絡上完成的,因此使用 192.168 這樣的地址)。服務腳本稱為“slapd”。Hearbeat 將在 /etc/ha.d/resource.d 和 /etc/init.d 中查找腳本。 服務腳本 對於簡單的冷備用案例,我們可以使用標准的 /etc/init.d/slapd 腳本而無需做更改。但是我們希望執行特別的功能,所以我們創建了自己的 slapd 腳本,該腳本存儲在 /etc/ha.d/resource.d/ 中。Heartbeat 將該目錄作為它搜索路徑中的第一個,因此我們無需擔心會運行 /etc/init.d/slapd 腳本。但是,您應當檢查以確定在引導時不再啟動 slapd(從您的 /etc/rc.d 樹除去任何 S*slapd 文件)。首先,在第 17 和 18 行我們指明 slapd 服務器的啟動配置文件。 該腳本遵循標准 init.d 語法,因此啟動信息包含在從第 21 行開始的 test_start() 函數中。首先我們停止所有當前正在運行的 slapd 實例。在第 39 行我們利用主配置文件啟動主服務器。我們的設計將遵循這樣的規則:如果主節點和輔助節點都在運行,則在主節點上啟動 slapd 作為主服務器,在輔助節點上啟動 slapd 作為從服務器,並啟動復制守護程序。如果僅有一個節點在運行,則啟動 slapd 作為主服務器。虛擬 Ip 依賴於 slapd 主服務器。為了完成該操作,我們必須知道哪個節點正在執行腳本,並且如果我們位於主節點,那麼我們需要知道輔助節點的狀態。重要的內容位於腳本的“start”分支。因為我們已經在 Heartbeat 配置中指明了主節點,所以我們知道,當 test_start() 函數運行時,它是在 Heartbeat 的主節點上運行的(因為 Heartbeat 使用了 /etc/init.d/ 腳本,所以所有腳本都是利用參數“startstoprestart”調用的)。當調用腳本時,Heartbeat 會設置許多環境變量。下面是一個我們感興趣的環境變量: HA_CURHOST=slave6 我們可以使用“HA_CURHOST”值來告訴我們,何時正在主節點(slave6)上執行,何時正在進行故障轉移(此時 HA_CURHOST 的值為“slave5”)。現在我們需要