Active Directory 複製指南

在引入 Windows 2000 Server 和 Active Directory 之前,許多企業環境都依賴 Windows NT 作爲其服務器基礎結構及進行身份識別與訪問

管理。自 Windows NT® 4.0 推出後,它就成爲網絡操作系統 (NOS) 領域的中堅支持產品,但由於它有很多缺陷,因而難以在大型企業範圍內部署。

對於初學者,Windows NT 使用平面命名空間來存儲網絡資源,這意味着難以將資源分割爲更小的子集或配置各種精細管理。例如,您無法爲市場部門中的資源配置部門容器,也無法配置僅有權重新設置該部門內的用戶密碼的本地管理員。如此看來,Windows NT 安全性幾乎完全得不到保障。如果您要向桌面支持工程師委派管理任務,通常不得不對其授予遠遠超出需要的權限。

此外,Windows NT 將所有信息存儲在安全帳戶管理器 (SAM) 數據庫中,該數據庫大小不能超過 40 MB。如果 SAM 數據庫超過了此建議的最大大小(大約在達到 25,000-40,000 個對象時就會超過此值,具體取決於您的配置),則需要將環境分爲多個單獨的域,這樣管理網絡和爲用戶提供資源訪問就會變得複雜。每個 NT 域都包含一個主域控制器 (PDC),其中包含 SAM 數據庫的只讀/只寫副本;儘管您可以爲默認容錯部署一個或多個備份域控制器 (BDC),但這些 BDC 是隻讀的,無法執行任何需要寫入操作的更新,如更改用戶的密碼。

最終,Windows NT 依賴於 NetBIOS 命名解決方案,它基於廣播並且經常在用戶瀏覽網絡資源時(尤其是在需要通過慢速或被大量使用的 WAN 鏈接瀏覽時)生成大量通信。


新模型應運而生

在 2000 年,Microsoft 發佈了 Windows® 2000,其中包含對早期 NOS 產品的重要革新。您可以想像到,新的 NOS 服務 Active Directory® 與 Windows NT 大不相同。Active Directory 不再依賴於平面命名空間,而是基於 X.500 標準構建,它創建了分層組織結構;現在您可以將資源組織到單個域的多個組織單元中,並基於任務級別對每個 OU 委派管理。

與 Windows NT 相比,另一個重大改進是全新的多主機複製模型。僅可寫入的 PDC 及其相關的 BDC 一去不復返了;在 Active Directory 中,每個域控制器都可以寫入到 Active Directory 數據庫中。

不過,雖然這樣可在支持大型和/或分散環境方面提供極大的靈活性,但對維護 Active Directory 的完整性也形成了新的挑戰。如果 John Smith 和 Jane Dow 在某個國家/地區兩端位置的辦公室中對同一個對象進行了更改,而這些更改相互衝突,會發生什麼情況呢?Active Directory 複製模型定義了將更新傳達到某個環境中所有域控制器的方法,還定義瞭如何處理由可從任何地方進行更改的多主功能產生的衝突。


Active Directory 複製原理

爲了結合以下示例進行說明,我們將只討論站點內複製。基本上,站點內複製旨在將更改快速複製到同一站點的 DC 內,然後使用更改通知來執行。在站點內複製的情況下,DC1 將通知 DC2 有需要複製的更改,然後 DC2 從 DC1 中拉出這些更改。同樣,當 DC2 有任何更改時,它也會通知 DC1,然後 DC1 從 DC2 中拉出這些更改。您可以看到,所有的 Active Directory 複製都通過“拉”操作而不是“推”操作進行。

因爲 Active Directory 可擴展至幾十萬甚至數百萬個對象,所以有必要將 Active Directory 數據庫劃分爲多個部分(稱爲命名上下文)。每個域控制器可在 Active Directory 數據庫的本地副本中存儲至少三個 NC。

架構 NC 此 NC 將被複制到林中的其他各個域控制器中。它包含有關 Active Directory 架構的信息,該信息又定義了 Active Directory 內不同的對象類和屬性。

配置 NC 此 NC 也會被複制到林中的其他各個 DC 中,它包含林範圍內有關 Active Directory 的物理佈局的配置信息,以及有關顯示標識符和林範圍內 Active Directory 配額的信息。

域 NC 此 NC 將被複制到單個 Active Directory 域中的其他各個 DC 中。正是此 NC 中包含最常訪問的 Active Directory 數據:實際用戶、組、計算機以及其他駐留在特定 Active Directory 域中的對象。

爲了更好地優化複製通信量,將單獨複製每個命名上下文,以使更改不頻繁的 NC(如架構 NC)不佔用域 NC(更改很可能更加頻繁)所需的網絡帶寬。

由於可從任何 Active Directory DC 進行目錄更改,因此 Active Directory 複製需要跟蹤兩種類型的寫入操作。一種類型是原始寫入,在直接對特定 DC 執行特定更改時進行的寫入。例如,如果您連接到 DC1 並更改用戶的密碼,此更改便被視爲 DC1 上的原始寫入。Active Directory 還必須跟蹤複製的寫入,正如您能想像到的,這表示會將特定更改從其他域控制器中複製過來。被視爲 DC1 上的原始寫入的更改在被複制到 DC2、DC3 以及域範圍內的其他任何 DC 中後,便被視爲複製的寫入。

Active Directory 域控制器通過使用複製元數據管理目錄更改的傳輸。這表示 Active Directory 除了將已更改的實際數據從一個 DC 傳輸到另一個 DC(對 John Smith 的描述更改爲“人力資源主管”),還會傳遞關於該更改的其他信息(如更改源自的 DC、進行更改的時間以及其他關鍵信息)以使域控制器以最高效的方式管理複製。

我們要討論的第一個複製元數據項目是更新序列號 (USN)。每個域控制器都維護特定於該域控制器的 USN。每當從該 DC 對 Active Directory 進行更改,USN 都會增加 1。因此如果某 DC 的 USN 在上午 11:00 時爲 1000,而在上午 11:30 時爲 1005,您就會知道已在該 DC 上對 Active Directory 數據庫進行了 5 次更改。事實上,進行什麼樣的更改對 USN 來說並不重要 — 您可以修改 5 個不同的對象、創建 5 個對象、刪除 5 個對象或前述操作的任意組合,該 DC 的 USN 都會增加 5。此外,USN 僅是特定域控制器的內部項目,與其他 DC 相比較時沒有任何參考價值。域中的某個 DC 可能在上午 11:30 時進行更改,並指定 USN 爲 1051;而相同域的另一個 DC 可能在同一時刻進行更改,並指定 USN 爲 5084。儘管兩個 DC 對於幾乎同時進行的更改很明顯具有完全不同的 USN,但這與如何複製這些更改並不相關;就不同變更之間的比較來說,某個 DC 的更新序列號對其他任何 DC 而言都毫無意義。

但這並不是增加 DC 的 USN 的唯一方式。請記住,對 Active Directory 數據庫的更改可包括原始寫入或複製的寫入。兩種類型的寫入操作都可增加域控制器上的更新序列號,這意味着每當從其他 DC 複製了更改時,該序列號都會增加。現在,很明顯可以看出,每個 DC 都需要一種方法來跟蹤已複製的更改,否則每個 DC 在每次複製時都會通過纜線發送整個 Active Directory 數據庫。爲避免發生這種情況,每個 Active Directory 域控制器都爲其他用於進行復制的域控制器維持一個稱爲高水準矢量 (HWMV) 的值。每個 DC 都將此高水準矢量與遠程 DC 的全局唯一標識符 (GUID) 相關聯,以防止在遠程域控制器被重命名或從目錄中刪除後產生混淆。

我們從一個簡單的示例開始,假設您在 contoso.com 域中配置了兩個域控制器 dc1.contoso.com 和 dc2.contoso.com。因爲 contoso.com 域中只有兩個 DC,所以 DC1 和 DC2 只能彼此複製。(請注意這只是一個簡化的示例,並不能完全說明 Active Directory 複製的所有細節。隨着講述的深入,我們會添加更多詳細信息。)

我們再假設 DC1 的當前 USN 爲 3000,DC2 的當前 USN 爲 4500,在開始我們的示例時兩個 DC 對彼此而言都已處於最新狀態:

步驟 1:DC1 和 DC2 對彼此而言均處於最新狀態。DC1 對於 DC2 的高水準矢量爲 4500,DC2 對於 DC1 的高水準矢量爲 3000,如圖 1 所示。

圖 1 兩個 DC 的當前狀態
圖 1 兩個 DC 的當前狀態

步驟 2:管理員在 DC1 上創建了一個新對象,DC1 的 USN 增加到了 3001,如圖 2 所示。請注意 DC1 針對 DC2 的 HWMV 沒有更改,因爲 DC1 尚未通知 DC2 自己有正等待中的更改。

圖 2 添加了一個新對象
圖 2 添加了一個新對象

步驟 3:DC1 通知 DC2 自己有可用更改。隨後 DC2 啓動對 DC1 的複製來請求任何可用的更新。作爲此請求的一部分,DC2 將向 DC1 發送其針對 DC1 存儲的高水準矢量,如圖 3 所示。

圖 3 更改 通知
圖 3 更改通知 (單擊該圖像獲得較大視圖)

步驟 4:DC1 向 DC2 發送與 USN 3001 相對應的更改,即在步驟 2 中在 DC1 上創建的對象。DC2 將自己的 USN 更新爲 4501 並將針對 DC1 的 HWMV 更新爲 3001,如圖 4 所示。

圖 4 更改和更新
圖 4 更改和更新 (單擊該圖像獲得較大視圖)

到目前爲止都沒有問題吧?但現在問題就來了。DC2 有一個需要複製的更改。如果原來進行的只是 USN 和高水準矢量的更改,那麼現在 DC2 要聯繫 DC1 以將 DC1 剛纔複製到 DC2 的相同更改複製回 DC1,這將形成一個無窮的複製循環,並會不斷佔據越來越多的帶寬。爲防止此種情況,我們需要再多用幾個矢量來解決難題,第一個是最新矢量(UTD 矢量或 UTDV)。

UTDV 是另一個用於強化抑制的複製元數據,即其目的是防止相同的更改通過網絡一再重複被複制而耗費帶寬。每個 DC 針對其他每個 DC 維護一個 UTDV 表,其中存儲相關命名上下文的副本。對於域 NC,域中的各個 DC 針對該域中的每個 DC 維護一個 UTDV;對於配置和架構 NC,則針對林中的每個 DC 維護一個 UTDV。該 UTDV 表不僅會跟蹤每個 DC 從其複製合作伙伴接收的最大 USN,還會跟蹤從複製給定 NC 的各個 DC 中接收的最大 USN 值。爲此,每個複製的更改還需要包括以下信息:

 

  • 要複製更改的 DC 的 GUID。這個要複製的更改可以是原始寫入或複製的寫入。
  • 要從中複製更改的 DC 的 USN。同樣,此更改既可以來自原始寫入,也可以來自複製的寫入。
  • 引起更改的 DC 的 GUID。如果此 GUID 與複製更改 DC 的 GUID 相同,表明它是原始寫入。否則,UTDV 表就起作用了。
  • 引起更改的 DC 的 USN。同樣,如果此 USN 與複製更改的 DC 的 USN 相同,就表明這是原始寫入。否則,它就不是 UTDV 表。

 

爲了更好的說明此過程,我們添加第三方域控制器 (DC3) 增加示例的複雜性。在本示例中,DC1、DC2 和 DC3 是相互的複製夥伴;DC1 與 DC2 和 DC3 互相複製,DC2 與 DC1 和 DC3 互相複製,DC3 與 DC1 和 DC2 互相複製:

步驟 1:DC1、DC2 和 DC3 對彼此而言都處於最新狀態。

步驟 2:DC3 通過重置 jsmith 用戶帳戶的密碼執行單個原始寫入。DC3 通知 DC1 和 DC2 自己有可用更改。DC1 和 DC2 從 DC3 拉出原始寫入,然後更新各自針對 DC3 的 HWMV 和 UTDV 表,如圖 5 所示。

圖 5 更新 HWMV 和 UTDV 表
圖 5 更新 HWMV 和 UTDV 表 (單擊該圖像獲得較大視圖)

步驟 3:輪到最新矢量登場了。DC2 通知 DC1 自己有可用更改。然後 DC1 通過向 DC2 發送以下信息與 DC2 聯繫以請求新更改:

 

  • DC1 對 DC2 的高水準矢量值,在此情況下爲 4501。
  • DC1 的 UTDV 表(如圖 6 所示),指示已從所有 DC(包括 DC3)接收的最高原始 USN 。

 

根據 HWMV 爲 4501 的情況判斷,DC2 知道尚未將相關更改複製到 DC1(請參見圖 7)。

但是,根據在開始複製之前 DC1 傳送的 UTDV 表,DC2 斷定 DC1 實際上並不需要此更改,因爲 DC1 已從 DC3 接到了此更改。此時,DC1 僅更新對 DC2 的 HWMV 項目來反映 USN 的增加,如圖 8 所示。但是,爲了節省帶寬,並不通過纜線發送實際數據。

圖 8 傳播抑制
圖 8 傳播抑制 (單擊該圖像獲得較大視圖)

步驟 4:當 DC2 通知 DC3 自己有可用更改時以及當 DC1 以類似方式通知 DC2 和 DC3 時,便會發生相同的傳播抑制情況。這三個 DC 將更新各自針對自已的複製夥伴的 HWMV 條目,如圖 8 所示,但因爲實際數據已在步驟 2 中傳送到各個 DC,所以不會再度通過纜線傳輸。


多主機環境中的衝突解決方案

到目前爲止,我們的示例依然存於一個完美的世界中,每次只有一個管理員對 DC 進行更改,從不會出現衝突情況。我們知道這在現實世界中很罕見。既然對 Active Directory 對象的更新可以來自域中的任何域控制器,那麼,如果兩個管理員從兩個不同域控制器執行的更新相互衝突時會發生什麼情況?Active Directory 環境中可能發生三種類型的衝突,它們使用不同的衝突解決方案方法。

衝突的屬性變更 . 如果兩名管理員用相互衝突的方式更新相同的對象,便會發生此類型的衝突:一名管理員將用戶描述設置爲“市場”,另外一名管理員在另一 DC 上將用戶描述設置爲“銷售和市場”。

創建衝突的新對象 . 如果兩個管理員同時使用相同的名稱創建對象,例如,兩個名爲 jsmith 的用戶,便會發生此類型的衝突。

將對象移動到刪除的容器 . 這種類型的衝突較爲少見,如果管理員在容器內(例如,OU)創建或移動對象,與此同時另一名管理員在另一 DC 上刪除了該容器,便會發生此類型的衝突。

爲了解決前兩種類型的衝突,下面介紹另外兩個主要用於衝突解決方案的複製源數據。爲對象中每個單獨的屬性分配 versionID 值,初次創建對象時,該值的起始值爲 1。只要一修改任意 DC 中的某個屬性,versionID 就會增加 1。因此如果特定用戶的描述屬性已從默認值(空白或 <未設置>)更新爲“市場部”,則描述屬性的 versionID 會變成 2。如果稍後該描述修訂爲“銷售和市場部”,則描述屬性的 versionID 會變成 3,依此類推。此 VersionID 與我們之前介紹的其他元數據一起包含在每個複製項目中。

此 versionID 也可用於進一步減少複製通信量。例如,如果 DC2 上的管理員已對某個屬性進行多次更改(可能該管理員幾次鍵入錯誤更改),使 DC2 具有與 versionIDs 2、3、 4、和 5 對應的原始寫入,在此情況下 DC2 將僅複製與最後一個版本 versionID 5 相對應的寫入。由於早期更改難逃被覆蓋的命運,因此這樣可便捷地減少不必要的帶寬佔用。

對 Active Directory 所做的每個更改中還包含衝突解決方案使用的第二個附加元數據,這是一個時間戳,屬於複製元數據的一部分,指示修改是何時進行的。

也可將時間戳屬性用作檢測 Active Directory 複製運行情況的主動措施。如果 DC 使用相對較新的時間戳未發現特定 DC 中有任何更改,就會開始生成錯誤消息指示相關 DC 中可能存在問題。

那麼,如何在衝突解決方案中使用這兩個屬性?我們來依次檢查每種衝突類型。


解決衝突的屬性變更問題

請看 contoso.com 域中 jsmith 用戶對象的例子。DC1 上的管理員將對 jsmith 的描述改成了“市場”。幾乎同時,DC3 上的管理員將這同一名用戶的描述改成了“銷售和市場”。此時,DC1 和 DC3 中關於 jsmith 描述屬性的比較如圖 9 所示。

如果 DC2 同時接到這兩種更改,它無疑就需要確定哪個更改“獲勝”。相互衝突的解決方案的加時賽順序如下所示:

 

  1. 具有較高 versionID 的修改會“獲勝”,而“失敗”的修改會被覆蓋。在本例中,如果兩個記錄的 versionID 都是 2,我們就需要進入第二場加時賽。
  2. 如果兩個記錄具有相同的 versionID,時間戳較晚的更改將獲勝,而失敗的更改將被覆蓋。本例中 DC3 的原始寫入的時間戳較晚,所以 jsmith 的描述將被設置爲“銷售和市場”。極少數情況下,如果 versionID 和時間戳都相同,就需要進行第三場決定性的加時賽:
  3. 如果兩個記錄的 versionID 和時間戳都相同,則具有較低編號 GUID 的 DC 生成的寫入將獲勝;而具有較高編號 GUID 的寫入會被覆蓋。因此在 DC1 的 GUID 是 1234567890,DC3 的 GUID 是 2345678901,而兩者的 versionID 和時間戳都相同的情況下,DC1 生成的寫入會獲勝。

 

您可能在想,“在第一場加時賽中應用時間戳豈不更有意義?”然而事情並不像您想象的那樣毫無波瀾。如果時間戳是 Active Directory 衝突解決方案中主要的加時賽,想要傳播更改的惡意管理員只需將特定 DC 的時鐘往回撥,就可以總能靠時間戳獲勝。


解決創建衝突對象的問題

在兩個對象具有相同創建名的情況下,Active Directory 同樣將使用上一節介紹的那三場加時賽來確定哪個對象會“獲勝”。但是,與上節所述的不同之處在於“失敗”的對象不會被覆蓋,而是使用字符 CNF(對於衝突對象來說)重命名失敗的對象,後面加上冒號和“失敗”對象的 GUID。這樣,管理員即可更系統地確定應該保留和刪除的對象。


解決將對象移動到刪除的容器的問題

如上所述,解決將對象移動到刪除的容器是相對較少發生的衝突,只在兩種情況下才會發生。一種情況是,某個 DC 上的管理員在特定容器中(例如 Training OU)創建了一個對象,而與此同時另一個 DC 上的管理員刪除了該 Training OU。另外一種情況是,某個 DC 上的管理員將一個對象移動到了某個容器中,而與此同時另一個 DC 上的管理員刪除了該容器。

在這種情況下,解決方案非常直接:Active Directory 會將“孤兒”對象移動到 Active Directory 的一個特殊容器中(該容器是專爲此用途而設)— LostAndFound 容器,它存在於每個 Active Directory 域的根目錄下。對於 contoso.com 域,可在以下 LDAP 路徑中找到 LostAndFound 容器:LDAP://cn=LostAndFound,dc=contoso,dc=com。如果打開 Active Directory 用戶和計算機管理單元時未看到 LostAndFound 容器,只需單擊“查看”|“高級功能”。


防止 USN 回滾

在 Active Directory 環境中,您可能會遇到一種最嚴重的情況,如果您瞭解了它的成因和解決方法,這種最嚴重的情況也是最容易避免的情況。USN 回滾是一種錯誤狀態,可使網絡上的複製完全關閉。之所以會發生 USN 回滾,是因爲允許域控制器保持脫機狀態相當長時間後返回服務狀態,也可能是因爲使用不受支持的方法還原域控制器。

導致 USN 回滾的一個基本原因與在 Active Directory 多主機環境中處理刪除對象的方式有關。在 DC 上刪除對象時,並不會將該對象徹底刪除,而是被邏輯刪除,以便邏輯刪除的對象可以複製到其他 DC 中,以此通知它們對象的刪除。最值得注意的是,邏輯刪除對象具有一個設爲 TRUE 的 isDeleted 屬性。爲減小邏輯刪除對象的大小,對象中所包含的大部分值(如描述、個人信息和用戶對象的組成員身份)已被刪除(有關此過程的詳細信息,請參閱 technetmagazine.com/issues/2007/09 上 Gil Kirkpatrick 的文章《恢復 Active Directory 邏輯刪除對象》。

因爲這些邏輯刪除對象不會無限期保留,所以可能會發生 USN 回滾。默認情況下,60 或 180 天后 Active Directory 數據庫會完全清空這些邏輯刪除對象(具體時間取決於您首次創建 Active Directory 環境時運行的 Windows Server® 版本)。這 60 或 180 天的間隔稱爲 tombstone 生存時間。在這段時間內,所有域控制器都必須能至少複製一次,否則不僅於事無補,而且會讓事情更糟;它們爲 USN 回滾創造了機會。基本上,如果域控制器完全過時而“遺漏”了一個或多個邏輯刪除對象,並因此無法向其他 DC 提供最新的 Active Directory 數據庫本地副本,這時就會發生 USN 回滾。爲避免發生這種情況,不應將脫機時間已超過邏輯刪除生存時間的域控制器返回到服務狀態;而是使用 Microsoft 知識庫文章 216498 (support.microsoft.com/kb/216498) 中提供的步驟,從 Active Directory 中刪除舊 DC 的元數據,然後從頭重建域服務器。

導致發生 USN 回滾的第二個原因是使用不受支持的方法(最常使用的是磁盤克隆或映像工具)還原了域控制器。如果發生 USN 回滾,由於還原方法沒有 Active Directory 感知功能,所以已還原的 Active Directory 數據庫並不會意識到自己已“回到過去”。Windows 2000 和最初發行版本的 Windows Server 2003 很難檢測出 USN 回滾,但是 Windows Server 2003 SP1(和即將發佈的 Windows Server 2008)具有內置控件,可檢測出未正確還原的 DC 情況。在這些比較新的 OS 版本中,DC 會在 Directory Services 事件日誌中記錄事件 ID 1115、2095、2103 和 2110;這些事件的文本和從 USN 回滾中恢復的必要步驟可在適用於 Windows Server 2003 的知識庫文章 875495 (support.microsoft.com/kb/875495) 中找到。(有關在 Windows 2000 中處理 USN 回滾的信息,可從 support.microsoft.com/kb/885875 上的知識庫文章 885875 中找到。)


在 2008 版中更新多主機模型

在即將發佈的 Windows Server 2008 版本中,Microsoft 通過引入只讀域控制器 (RODC),在多主機模型中進行了細微的改動。RODC 主要用於分支機構部署,或用於在特定位置沒有派專業工作 IT 人員到現場,但需要採取額外步驟來確保特定 DC 的完整性的情形。雖然我們滿可以用整篇文章來討論關於 RODC 的所有技術細節,但我們還是重點研究一下您應該熟悉的要點吧。

如名稱所示,駐留在 RODC 上的 Active Directory 數據庫的副本是隻讀的。可以連接到 RODC 來讀取所需的幾乎所有信息,但在 RODC 上無法執行任何寫操作。

其次,RODC 不執行任何出站複製操作。這是與我們目前爲止一直討論的多主機複製模型最根本的不同。RODC 會從其他可寫 Windows Server 2008 DC 接收入站複製,但它不向其他 DC 複製任何信息。這樣可再增加一層安全屏障,即使惡意用戶能設法從 RODC 中修改 Active Directory,這些修改也不會傳播到環境的其他部分。

也許最令人感興趣的是,在默認情況下,RODC 不復制用戶密碼。將 Active Directory 數據庫從可寫 DC 入站複製到 RODC 時,將複製所有用戶對象,但不包括用戶的密碼信息。這爲分支機構環境提供了另一安全屏障,假如 DC“長腿跑了”,DC 的硬盤驅動器上也沒有密碼信息。整體來看,這些對多主機 Active Directory 複製最初理念的更改創建了一個有很大改進的模型,可用於確保分支機構或其他遠程位置中的域控制器的安全。

 
發佈了20 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章