5

跨網域 AD 帳號存取之防火牆 Port 再研究

 1 year ago
source link: https://blog.darkthread.net/blog/ad-ldap-conn-experiments/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

跨網域 AD 帳號存取之防火牆 Port 再研究

2023-02-28 08:40 AM 0 232

還是跨網域 AD 帳號登入 IIS 網站之 DC 連線需求議題的延伸。

上次實驗我們得到一個結論,使用跨網域帳號登入 IIS 時,不管走 NTLM 或 Kerberos,IIS 主機都不需直接連線跨網域DC。但這僅涵蓋帳號密碼驗證,若涉及更詳細的資料,例如查詢人員所屬群組,是否就必須直接連上跨網域 DC 主機才能完成?

照例寫程式實測,程式碼如下。使用 System.DirectoryEntries.AccountManagement 命令空間的方法連繫 AD DC,查詢 someone 帳號是否存在,並查詢其所屬群組。

void TestAd() 
{
    using (var otherDomain = new PrincipalContext(ContextType.Domain, "child")) 
    {
        var user = UserPrincipal.FindByIdentity(otherDomain, "someone");
        if (user != null)
        {
            foreach (GroupPrincipal p in user.GetAuthorizationGroups())
            {
                Console.WriteLine($"Group: {p.Name}");
            }
        }
    }
}

測試機器 10.0.0.8 屬於 web 網域,直屬 DC 為 10.0.0.7,child 網域 DC 為 10.0.0.6,測試前 10.0.0.8 一律重開機,避免錯過查詢一次可 Cache 沿用的資料查詢。

測試一,未阻擋 10.0.0.8 (以下簡稱 C) 對 10.0.0.6 (以下簡稱 D) 通訊

執行成功,查到 someone 屬於 Users 與 Domain Users 群組。

Fig2_638131422390341082.png

使用 Wireshark 觀察兩台主機間有以下傳輸:

  1. C ➜ D 389 LDAP
  2. C ➜ D 88 Kerberos
  3. C ➜ D 389 LDAP / bindRequest GSS-SPNNEGO
  4. C ➜ D 389 LDAP / SASL GSS-API
  5. C ➜ D 389 LDAP / searchRequest
  6. C ➜ D 389 LDAP / unbindRequest

測試二,阻擋 10.0.0.8 (C) 對 10.0.0.6 (D) 88 Port

驗證失敗,錯誤訊息為 The user name or password is incorrect. 根本原因是 Kerberos Port 不通,這訊息有點誤導。

Unhandled exception. System.Runtime.InteropServices.COMException (0x8007052E): The user name or password is incorrect.
   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_AdsObject()
   at System.DirectoryServices.PropertyValueCollection.PopulateList()
   at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName)
   at System.DirectoryServices.PropertyCollection.get_Item(String propertyName)
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
   at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
   at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
   at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)
   at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, String identityValue)
   at System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, String identityValue)

Fig1_638131422398633368.png

有點值得注意,上圖 22, 23 列(淺藍色)的 Protocol 為 CLDAP (Connectionless LDAP),走的是 UDP Port,我一直以為 LDAP 都是走 TCP,但實測也會用到 UDP。

測試三,阻擋 10.0.0.8 (以下簡稱 C) 對 10.0.0.6 (以下簡稱 D) 389 TCP Port

發生錯誤,訊息為找不到 LDAP 伺服器。

Unhandled exception. System.DirectoryServices.AccountManagement.PrincipalServerDownException: The server could not be contacted.
 ---> System.DirectoryServices.Protocols.LdapException: The LDAP server is unavailable.
   at System.DirectoryServices.Protocols.LdapConnection.Connect()
   at System.DirectoryServices.Protocols.LdapConnection.SendRequestHelper(DirectoryRequest request, Int32& messageID)
   at System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request, TimeSpan requestTimeout)
   at System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request)
   at System.DirectoryServices.AccountManagement.PrincipalContext.ReadServerConfig(String serverName, ServerProperties& properties)
   --- End of inner exception stack trace ---
   at System.DirectoryServices.AccountManagement.PrincipalContext.ReadServerConfig(String serverName, ServerProperties& properties)
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoServerVerifyAndPropRetrieval()
   at System.DirectoryServices.AccountManagement.PrincipalContext..ctor(ContextType contextType, String name, String container, ContextOptions options, String userName, String password)
   at System.DirectoryServices.AccountManagement.PrincipalContext..ctor(ContextType contextType, String name)

前後嘗試三次,等待近 30 秒 Timeout 失敗。

Fig3_638131422402744773.png

結論:使用跨網域帳號登入 IIS 時,若使用 NTLM 方式認證,IIS 可向自身網域 DC 驗證跨網域帳號。但如果 IIS 或 ASP.NET 程式需要查詢群組關係或詳細 AD 屬性,IIS 就需要直接連線跨網域帳號所屬 DC。依實驗結果,至少需開啟 389 UDP/TCP 及 88 Port,完整清單則可參考微軟文件


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK