Active Directory ortamına Domain Join işlemi başlatıldığında, işletim sistemi çekirdek servisleri üzerinden DNS tabanlı bir çözümleme akışı tetiklenir. Girilen Domain adı Client tarafında yorumlanır ve buna karşılık gelen DNS SRV (Service Record) sorguları otomatik olarak üretilir. Sürecin ilerleyebilmesi için DNS Query, SRV ve Host (A) kayıtları üzerinden çözümleme yapılır ve bağlantı kurulacak uygun Domain Controller belirlenir. Bu aşamadan itibaren Client tarafında sırasıyla Service Discovery, Authentication, Secure Channel kurulumu ve Group Policy Processing işlemleri devreye girer.
İşletim sistemi bu süreci belirli koşullara göre yönlendirir. Hangi API'nin çağrılacağı, hangi DLL'in devreye gireceği ve hangi Port'un kullanılacağı, ortamdan alınan yanıtlara göre belirlenir. Her adım, bir öncekinin döndürdüğü bilgi üzerinden şekillenir. Domain Join, işletim sistemi servislerinin birbirine bağlı ve eş zamanlı çalışmasıyla ilerleyen bir yapı ortaya çıkarır. İşlem tamamlandığında Client'ın Domain üyeliği tanımlanır ve makine hesabı üzerinden sürdürülebilir bir güven ilişkisi başlatılır. Bu yapı; Kerberos Ticket işlemleri, Group Policy uygulaması ve Secure Channel devamlılığı için işletim sistemi tarafından temel güven bağı olarak kullanılır.
Bu makalede; Domain Join sürecinin işletim sistemi tarafından hangi adımlarla yürütüldüğünü, hangi bileşenlerin ne zaman devreye girdiğini ve DNS tabanlı çözümleme akışının sistem içi servislerle nasıl ilişkilendiğini adım adım inceliyorum.
1- Domain Bilgisinin Girilmesi
Bir bilgisayarı Domain'e dahil etmek için System Properties penceresindeki Change... butonuna tıklıyorum ve Computer Name/Domain Changes ekranına ulaşıyorum. Bu ekranda Domain seçeneğini işaretliyor, hedef Domain adını Suffix ile birlikte giriyorum. Benim Active Directory Domain'im abc.local şeklindedir.

Bu alan, sistem tarafından bir Fully Qualified Domain Name (FQDN) olarak değerlendirilir. Windows, bu bilgiyi temel alarak DNS üzerinden Domain Controller'ları tespit etmek için bir çözümleme süreci başlatır. Süreç boyunca Netlogon servisi devreye girer ve DC keşfi için gerekli DNS sorgularını üretir.
Mevcut Hostname bilgisi DESKTOP-OMCA19O iken yeni Hostname olarak DMISTPC01 atıyorum ve WORKGROUP yapısından çıkıp abc.local Domain'ine geçiş hazırlığını yapıyorum. Bu adım, tüm Domain Join sürecinin tetiklendiği ilk noktadır.
.local Suffix'i halen çalışıyor olsa da mDNS (Bonjour) çakışmaları nedeniyle Microsoft'un yeni dağıtımlar için önerdiği bir yapı değildir. Yeni kurulan ortamlarda kuruma ait kayıtlı bir alt Domain (ör. ad.firma.com) tercih edilir.
2- DC Keşif Sürecinin Başlatılması
DNS üzerinden yapılacak SRV kaydı sorgusunu Client tarafında teknik olarak tetikleyen bileşen Netlogon servisidir. Bu servis, Client Domain'e üye olduğunda Authentication ve DC keşfi gibi işlemler için aktif hale gelir ve sistemin temel servisleriyle senkron çalışır.
Ancak Domain'e henüz Join edilmemiş yani Workgroup durumunda çalışan makinelerde Netlogon servisi varsayılan olarak pasif durumdadır. Services.msc üzerinden manuel olarak başlatmak istediğimde servis bir anlığına çalışır gibi görünse de hemen ardından durur. Bunun nedeni, Workgroup'taki makinenin kuracağı bir Secure Channel'ın ve doğrulayacağı bir Trust ilişkisinin olmamasıdır. Netlogon, ihtiyaç görmediği için kendiliğinden kapanır. Bu davranış bir hata değil, tasarımsal bir tercihtir.


Domain Join işlemini başlattığımda, Join için girdiğim Credential bilgisi yani User Name ve Password değerleri Domain Controller tarafında doğrulanır. Bu doğrulama, Client'tan DC'ye SAMR ve LSARPC RPC kanalları üzerinden yapılan çağrılarla gerçekleşir. DC, kullanıcının kimliğini doğruladıktan sonra Add workstations to domain kullanıcı hakkına veya hedef OU üzerinde delege edilmiş Create Computer objects iznine sahip olup olmadığını kontrol eder. Yetkilendirme bu noktada DC tarafında gerçekleşir; Client tarafındaki SSPI yalnızca Authentication paketinin seçilmesi ve token üretimi ile ilgilenir.
Kimlik doğrulama tamamlandığında Netlogon servisi otomatik olarak aktif hale gelir ve herhangi bir manuel müdahaleye gerek kalmaz. Süreç kendi içinde ilerler. Client'ın hangi Domain Controller ile iletişim kuracağını belirlemek için Netlogon, kendi içinden DsGetDcName() API'sini çağırır ve DC seçimi için gerekli teknik akış başlar.


DC keşfinin teknik akışında Client, hedef Domain'e ait DNS SRV kaydını sorgular. Bu sorgu, uygun bir Domain Controller bulunması için başlatılır ve çözümleme işi, Client tarafında çalışan DNS Resolver modülü olan dnsapi.dll üzerinden yürütülür. Aldığı yanıt ile birlikte DC keşfi sürdürülür.
Normalde tüm bu akış arka planda sessizce yürür ve kullanıcıya yansımaz. İstediğimde akışı yakından izleyebilmek için Domain Controller üzerinde Netlogon servisine ait Debug Log özelliğini CMD üzerinden tetikleyerek açıyorum.
nltest /dbflag:0x2080ffff
Bu komut; hangi SRV kayıtlarının sorgulandığını, DsGetDcName() çağrısının nasıl işlendiğini ve sürecin hangi adımlardan geçtiğini doğrudan kayıt altına alır. İzleme çıktıları C:\Windows\debug\netlogon.log dosyasında tutulur. SRV sorguları başta olmak üzere DC keşfine dair tüm detayları bu dosyadan takip edebiliyorum.
Debug Log özelliğini açtıktan sonra Log'un gereksiz büyümemesi için aşağıdaki komutla kapatmayı öneririm.
nltest /dbflag:0x0

Log kaydında; DNS üzerinden hangi SRV kaydının sorgulandığı, kaç Domain Controller'ın bulunduğu ve hangisinin seçildiği gibi detaylar yer alır. DsGetDcName() API'si, DC keşif sürecinin merkezinde duran ve diğer alt sistemleri ihtiyaca göre zincirleme biçimde devreye sokan bir yönlendirici işlevi üstlenir.
netlogon.log dosyasındaki aşağıdaki satır; DMISTPC01 bilgisayarının Netlogon servisi tarafından, ABC NetBIOS isimli Domain için DC Locator sürecini tetiklemek üzere DsGetDcName() fonksiyonunun çağrıldığını açıkça gösterir.
07/23 03:52:39 [MISC] [5348] ABC: DsGetDcName function called: Client PID=5920, Dom:ABC Acct:(null) Flags: DS_RETURN_DNS_NAME
Çağrı satırının sonundaki DS_RETURN_DNS_NAME bayrağı, sonucun NetBIOS adı yerine DNS adı formatında dönmesini zorunlu kılar. Yani Client, dönecek DCName alanında DMISTDCSRV01.abc.local gibi bir FQDN bekler. Modern DC Locator akışında neredeyse her zaman bu bayrak tercih edilir.
Fonksiyon çalıştırıldıktan sonra Log kayıtlarında dönen sonuç satırı, hangi Domain Controller'ın seçildiğini ve bu DC'ye ait temel parametrelerin neler olduğunu gösterir. Bu veriler; DsGetDcName()'in başarılı şekilde bir hedef DC belirlediğini ve bağlantı kurulabilecek adres, Site bilgisi, IP adres türü gibi detayları sağladığını teknik olarak doğrular.
07/23 03:52:39 [MISC] [5348] DsGetDcName: results as follows:
DCName: \\DMISTDCSRV01.abc.local
DCAddress: \\10.10.10.100
DCAddrType: 0x1
DomainName: abc.local
DnsForestName: abc.local
Flags: 0xe003f3fd
DcSiteName: Default-First-Site-Name
ClientSiteName: Default-First-Site-Name

Buraya kadar aktardığım kısım, Domain Join işleminin kullanıcı tarafında nasıl göründüğünü ve arka planda hangi temel bileşenlerin devreye girdiğini özetleyen bir akış niteliğindedir. Görseller ve açıklamalar, sürecin adım adım nasıl ilerlediğini göstermek için kullanıldı. Bundan sonra işin daha derin teknik kısmına geçiyorum.
Artık odak noktam DsGetDcName() API'si olacak. Bu API, Netlogon servisi aracılığıyla çağrılarak hangi Domain Controller'a bağlanılacağını belirleyen mekanizmanın merkezinde yer alıyor. Parametrelerin nasıl işlendiğini, dönen yapıların ne anlama geldiğini ve hangi DLL'lerin sırasıyla devreye girdiğini inceleyerek süreci en düşük seviyede anlamaya başlıyorum.
DsGetDcName() API Prototipi
DsGetDcName(), Netlogon servisi tarafından çağrılan ve bir Client'ın hangi Domain Controller'a bağlanacağını belirleyen API'dir. Active Directory ortamında DC keşfi bu API tarafından yürütülür ve DNS tabanlı sorgularla desteklenir.
Fonksiyon çalıştırıldığında ComputerName, DomainName, DomainGuid, SiteName ve Flags gibi parametreler alır. Bu parametreler, yapılacak DNS sorgusunun kapsamını ve fonksiyonun davranışını belirler. API'nin hangi bilgileri arayacağı veya hangi türde Domain Controller seçimi yapacağı bu girdiler üzerinden yönlendirilir.
Başarılı şekilde tamamlandığında fonksiyon, uygun bir Domain Controller hakkında ayrıntılı bilgi içeren bir DOMAIN_CONTROLLER_INFO yapısı döndürür. Bu yapı, ilgili DC'ye ait şu teknik bilgileri içerir:
✔ DC'nin Hostname bilgisi (ör. SRVDC01.abc.local).
✔ DC'nin IPv4 / IPv6 adresi.
✔ DC'nin bulunduğu Active Directory Site adı.
✔ DC'nin FQDN değeri.
✔ DC'nin GUID bilgisi.
✔ DC'nin Flags alanındaki yetenekleri (örneğin DS_GC_FLAG, DS_DS_FLAG, DS_WRITABLE_FLAG, DS_KDC_FLAG, DS_PDC_FLAG, DS_TIMESERV_FLAG).
✔ Client ile iletişimde kullanılacak NetBIOS adı gibi diğer kimlik bilgileri.
DsGetDcName(), Domain Controller seçim sürecinin merkezinde duran ve aldığı parametrelere göre farklı davranışlar sergileyebilen bir API'dir.
|
Parametre |
Açıklama |
LPCWSTR ComputerName |
DC keşfinin yapılacağı bilgisayarın adıdır. NULL verildiğinde işlem yerel makine üzerinde yürütülür. Domain Join akışında neredeyse her zaman NULL kullanılır. |
LPCWSTR DomainName |
Hedef Domain'in FQDN bilgisidir. API, bu bilgiyi kullanarak ilgili Domain'e ait DC'leri arar. |
GUID *DomainGuid |
Hedef Domain'in benzersiz GUID değeridir. Çoğu durumda gerekmez ve NULL bırakılır. Domain adı değişmişse ya da doğrudan GUID üzerinden erişim gerekiyorsa kullanılabilir. |
LPCWSTR SiteName |
Hangi Active Directory Site içinde DC aranacağını belirtir. Genellikle NULL bırakılır; Client'ın IP/Subnet bilgisine göre Site eşleşmesini DC tarafı belirler. |
ULONG Flags |
API'nin davranışını yöneten kontrol bayraklarıdır. Örneğin:
• DS_GC_SERVER_REQUIRED: Global Catalog SRV kaydı sorgulanır.
• DS_RETURN_DNS_NAME: Sonuç FQDN olarak döner.
• DS_FORCE_REDISCOVERY: Cache yok sayılır, yeni keşif yapılır.
• DS_WRITABLE_REQUIRED: Yazılabilir bir DC döndürülür (RODC dışlanır). |
PDOMAIN_CONTROLLER_INFO DomainControllerInfo |
Bulunan DC hakkında dönen sonuç yapısıdır. İçinde DC Hostname, IP adresi, AD Site, FQDN, Flags ve diğer kimlik bilgileri yer alır. |
DsGetDcName() sonuçları Netlogon tarafında cache'lenir. Bayatlamış cache nedeniyle yanlış DC'ye düşüldüğü şüpheleniliyorsa DS_FORCE_REDISCOVERY bayrağı veya nltest /dsgetdc: /force komutu ile yeniden keşif tetiklenebilir.
LPCWSTR DomainName parametresi, DNS Query sürecinde hangi Domain adı için sorgu yapılacağını belirleyen anahtar girdidir. DNS sorgusunu doğrudan başlatmaz, ancak sorgunun hedefini tanımlayarak sürecin başlangıç noktasını oluşturur.
DsGetDcName() Çağrısı ve DLL Etkileşimi
DsGetDcName() tek başına tüm işi yapmaz; yalnızca DC keşif sürecinin ana API'sidir. Çalışırken ihtiyaç duyduğu işlemleri sistemdeki farklı DLL'lere devreder ve bu DLL'lerdeki hazır fonksiyonları çağırarak süreci tamamlar.
Buradaki temel mantık şudur: DLL'ler işi yapan eller, parametreler ise bu ellere "ne yapacağını" söyleyen talimatlardır. Hangi Domain için sorgu yapılacağı, hangi Site'ın öncelikli olacağı veya hangi tür DC'nin aranacağı gibi kararlar API'ye verilen parametrelerle belirlenir. DLL'ler bu talimatlara göre devreye girer.
Örneğin DNS sorgusu gerektiğinde Netlogon, bu işi kendi içinde çözmez. Bunun yerine LPCWSTR DomainName parametresinde verilen bilgiye dayanarak dnsapi.dll içindeki DnsQuery_W() fonksiyonunu çağırır. Bu sayede DNS üzerinden doğru kayıtlar sorgulanır ve sonuçlar Netlogon'un akışına geri aktarılır. Makalenin ana odak noktası da zaten tam olarak bu parametre ile bu DLL arasındaki etkileşimde yürütülen işlemlerdir.
Bir modülün başka bir modüldeki hazır işlevleri dışarıdan çağırarak kullanması, yazılım mimarisinde Function Call olarak adlandırılır.
Aşağıdaki tablo, DsGetDcName() çağrısı sırasında devreye giren başlıca DLL bileşenlerini ve bu bileşenlerin işlevsel rollerini açıklamaktadır.
|
DLL Adı |
Açıklama |
netlogon.dll |
DC Locator ve DsGetDcName() gibi fonksiyonları içerir. Domain keşfi ve Secure Channel başlatma mantığı burada yürütülür. |
dnsapi.dll |
DsGetDcName() çağrısı sırasında DNS çözümlemesi gerektiğinde devreye girer ve DnsQuery_W() fonksiyonları üzerinden SRV ve A kaydı sorgularını yürütür. |
secur32.dll |
SSPI giriş noktasıdır. Kimlik doğrulama isteklerini karşılar ve uygun Authentication Provider'a (Kerberos veya NTLM) yönlendirir. |
kerberos.dll |
Kerberos ile doğrulama yapılacaksa TGT üretimi, AS-REQ / AS-REP ve TGS-REQ / TGS-REP bilet alışverişi süreçlerini yönetir. |
msv1_0.dll |
NTLM kullanılacaksa Challenge / Response akışını yönetir. |
Süreç sırasında tüm DLL bileşenleri aynı anda ya da sabit bir sırayla devreye girmez. netlogon.dll genel kontrol akışını yöneten çekirdek bileşendir. Ancak ihtiyaç doğduğunda diğer DLL'ler devreye alınır. DNS çözümlemesi gerektiğinde dnsapi.dll çağrılır, Secure Channel kurulumu yapılacaksa secur32.dll devreye girer. Ortam Kerberos tabanlı ise kimlik doğrulama görevleri kerberos.dll üzerinden yürütülür; NTLM tercih edilirse bu görevler msv1_0.dll tarafından üstlenilir.
Her DLL, yalnızca kendi işlevsel kapsamına giren durumlarda ve bağlam koşullarına göre aktif hale gelir. DsGetDcName(), sistemi doğrudan yöneten bir bileşen değildir. Hangi işlevin hangi koşulda devreye girmesi gerektiğini belirleyen bir denetim mekanizması gibi çalışır.
Bu DLL dosyalarının tamamı C:\Windows\System32 dizini altında yer alır.
secur32.dll ve kerberos.dll İlişkisi
Bir kullanıcı oturum açmak istediğinde ya da bir bilgisayar Domain'e katılma sürecini başlattığında, kimlik doğrulama isteği doğrudan Kerberos veya NTLM protokolüne gönderilmez. İstek önce secur32.dll tarafından karşılanır. Bu bileşen, ortamın hangi kimlik doğrulama mekanizmasına uygun olduğunu belirleyen SSPI giriş noktasıdır.
İşletim sistemi, hangi protokolün kullanılacağını baştan bilmek zorunda değildir. secur32.dll; çağırılan paket (Negotiate, Kerberos, NTLM) ve ortamın yapılandırmasına bakarak en uygun mekanizmayı seçer. Kerberos uygunsa süreç kerberos.dll üzerinden bilet alışveriş adımlarıyla devam eder. NTLM uygunsa doğrulama akışı msv1_0.dll üzerinden yürür.
Bu yapı sayesinde karar verme süreci tek bir noktadan yönetilir ve yalnızca ihtiyaç duyulan servisler devreye girer. Karar aşaması tamamlandıktan sonra kontrol secur32.dll'den çıkar, seçilen protokolün ilgili DLL'i süreci devralır ve doğrulama işlemleri arka planda protokole uygun şekilde ilerler.
Teknik akış soyut görünebilir. Mantığı daha anlaşılır kılmak için günlük hayattan bir benzetme yapıyorum:
➔ Windows, ilk olarak gişe görevlisi gibi çalışan secur32.dll'e gider ve şunu söyler:
"Beni Domain'e bağla. Hangi protokol uygunsa onu kullan."
➔ secur32.dll ortama bakar ve karar verir:
"Bu ortamda Kerberos uygun, seni oraya yönlendiriyorum."
veya
"Kerberos şu an uygun değil, NTLM ile devam edeceksin."
➔ Kerberos uygunsa kerberos.dll'i çağırır:
"Şuna bir TGT bileti hazırla, AS-REQ sürecini başlat."
➔ NTLM seçilmişse kontrol msv1_0.dll'e geçer ve Challenge / Response akışı başlar.
Bu yapı sayesinde sistem, gereksiz bileşenleri devreye almadan yalnızca ihtiyaç duyulan protokolleri çalıştırır. Böylece Windows kimlik doğrulama mimarisi hem performans hem güvenlik açısından dengeli bir işleyiş sağlar.
Domain Join'in ilk anlarında makine hesabı henüz oluşmadığı ve SPN'ler yazılmadığı için Kerberos Service Ticket alınamaz; bu nedenle başlangıç kimlik doğrulaması büyük ölçüde NTLM üzerinden yürür. Join tamamlanıp replikasyon oturduktan sonra Kerberos devreye girer.
DNS Sorgusu: SRV Kaydı
Client, Active Directory ortamında hangi Domain Controller'ların hizmet verdiğini tespit edebilmek için DNS sunucusuna bir SRV kaydı sorgusu gönderir. Sorgu, _ldap._tcp.dc._msdcs.abc.local hedefine yöneltilir ve varsayılan olarak UDP 53 üzerinden iletilir. Bu SRV kaydı, yalnızca DC Locator amacıyla kullanılan _msdcs.abc.local DNS Zone'u altında yer alır. Domain Join gibi işlemlerde hangi sunucuların Domain Controller olarak hizmet verdiğini belirlemek için referans noktasıdır.

DNS sunucusu bu isteğe karşılık olarak Domain'e ait DC'lerin FQDN bilgilerini, LDAP Port 389 numarasını, Priority (öncelik) ve Weight (ağırlık) değerlerini içeren SRV kayıtlarıyla yanıt verir. Bu veriler Client tarafında değerlendirilerek hangi DC'ye bağlantı kurulacağına karar verilir.
DNS sorguları varsayılan olarak UDP 53 ile başlar. Yanıt, EDNS0 yoksa 512 byte sınırını aştığında TC (Truncation) bayrağıyla işaretlenir ve Client aynı sorguyu TCP 53 üzerinden yeniden gönderir. Çok DC'li ortamlarda SRV yanıtları sıklıkla bu fallback'i tetikler.
Örnek SRV Kaydı Yanıtı
Client, DC bilgilerini öğrenmek üzere DNS sunucusuna SRV kaydı sorgusu gönderdiğinde dönen yanıtta birden fazla kayıt yer alabilir. Her SRV kaydı, farklı bir DC'nin bilgilerini taşır ve sistem bu kayıtları değerlendirerek bağlantı kurulacak DC'yi seçer.
Yanıttaki her kayıt; Priority, Weight, LDAP Port 389 ve hedef FQDN bilgisini içerir. Priority değeri en düşük olan kayda öncelik verilirken aynı Priority seviyesindeki kayıtlar arasında Weight oranına göre dağılım yapılır. Bu yapı; ortamda birden fazla DC bulunduğunda yük dengelemesi ve yüksek erişilebilirlik için kullanılır.
Aşağıda bu sorguya ait örnek bir yanıt yer alıyor.
_ldap._tcp.dc._msdcs.abc.local SRV Priority 0 Weight 100 Port 389 Target dc01.abc.local
_ldap._tcp.dc._msdcs.abc.local SRV Priority 0 Weight 100 Port 389 Target dc02.abc.local
_ldap._tcp.dc._msdcs.abc.local SRV Priority 10 Weight 50 Port 389 Target dc03.abc.local
SRV kaydı yanıtları sistem tarafından belirli kurallara göre yorumlanır. Client, hangi DC'ye bağlanacağına karar verirken bu kuralları dikkate alır:
✔ dc01 ve dc02 kayıtlarında Priority değeri aynıdır ve 0 değerini taşır. Bu nedenle aralarında Load Balancing uygulanır. Weight değeri yüksek olan hedef bağlantı için daha avantajlıdır.
✔ dc03 kaydının Priority değeri 10 olduğu için yedek bir hedef olarak değerlendirilir. Diğer kayıtlar başarısız olursa devreye alınır.
✔ Windows Client, SRV yanıtlarını aldıktan sonra önce Priority'ye göre, ardından aynı Priority değerine sahip kayıtlar arasında Weight'e göre sıralama yapar. Bağlantı kurulacak DC bu sıralamaya göre seçilir.
Birden fazla DC varsa hepsinin SRV kayıtları toplanır ve SRV yanıtında tüm DC'lerin FQDN ile Priority/Weight bilgileri Client'a iletilir.
Her ortamda Priority ve Weight değerlerinin farklı yapılandırılması zorunlu değildir. Birçok yapıda tüm DC'ler aynı Priority ve Weight değerleriyle tanımlanır ve yük dengeleme Client tarafından rastgele yapılır. Belirli DC'lere öncelik verilmesi ya da ağırlık farklarıyla trafik yönlendirmesi istenirse, bu değerler DC üzerindeki LdapSrvPriority ve LdapSrvWeight Registry değerleriyle bilinçli olarak farklılaştırılabilir.
cldap Ping ve Site Belirleme
Client, SRV yanıtında dönen DC FQDN'lerini Priority/Weight sırasına göre değerlendirdikten sonra her hedefe cldap (Connectionless LDAP) ping gönderir. Bu ping, UDP 389 üzerinden yapılan bir LDAP Search isteğidir ve hedef DC'nin gerçekten yanıt verip vermediğini ölçer.
Ping'e cevap veren DC, yanıtın içinde Client'ın IP adresine karşılık gelen ClientSiteName bilgisini de döndürür. DC bu bilgiyi; kendi Active Directory Sites and Services yapılandırmasındaki Subnet → Site eşleştirmesinden üretir. Yani Client'ın gerçek Site'ı, ilk yanıt veren DC tarafından belirlenir.
Bu noktadan itibaren Client iki davranış sergileyebilir:
✔ İlk yanıt veren DC, Client'ın belirlenen Site'ında bulunuyorsa Client bağlantıyı bu DC ile sürdürür.
✔ İlk yanıt veren DC, Client'ın Site'ında değilse Client bu kez Site-aware bir SRV sorgusu yapar.
_ldap._tcp.._sites.dc._msdcs.abc.local
Site-aware SRV sorgusu sayesinde Client, kendi Site'ında bulunan DC'lerin listesini alır ve bağlantıyı bu Site içindeki bir DC ile kurar. Böylece Domain Join trafiği gereksiz yere uzak Site'lardaki DC'lere yönelmez. Bu mekanizma, çok şubeli yapılarda WAN trafiğinin önüne geçen temel optimizasyondur.
DNS Sorgusu: Host (A) Kaydı
SRV kayıtları üzerinden alınan FQDN'ler, sistemin hangi DC'ye yönleneceğini belirler. Ancak bir FQDN yalnızca isim bilgisidir; bağlantının kurulabilmesi için bu ismin hangi IP adresine karşılık geldiğinin bilinmesi gerekir. Bu amaçla DNS sunucusuna doğrudan bir Host (A) kaydı sorgusu gönderilir.
SRV sorgusu sonucunda Client, DC'nin FQDN bilgisine (örneğin dc01.abc.local) ulaşır. Bu bilgi; LDAP gibi dizin servisleri doğrudan IP üzerinden iletişim kurduğu için tek başına yeterli değildir. Client, dc01.abc.local adresinin hangi IP'ye karşılık geldiğini öğrenmek için DNS sunucusuna bir Host (A) sorgusu gönderir. Sorgu, Client'ın DNS Resolver bileşeni tarafından başlatılır ve verilen FQDN'e ait IPv4 ya da varsa IPv6 adresi geri döner.
Dönen IP adresi, Client'ın fiziksel olarak bağlantı kuracağı Domain Controller hedefini belirler. Bu adrese TCP 389 üzerinden LDAP oturumu açılarak dizin servislerine erişim sağlanır. Bağlantı üzerinden bilgisayar nesnesinin oluşturulması, kimlik doğrulama oturumunun açılması ve Group Policy verilerinin alınması gibi işlemler gerçekleştirilir. A kaydının çözülmesi, Domain Join sürecinin başarıyla tamamlanabilmesi için zorunlu bir adımdır.
Bu noktada dikkat etmem gereken bir detay vardır:
✔ Sistem, Forward Lookup Zone altında yer alan tüm Host (A) kayıtlarını taramaz.
✔ Yalnızca _ldap._tcp.dc._msdcs.abc.local SRV sorgusuna karşılık dönen DC FQDN'leri için Host (A) sorgusu yapılır.
Bu yapı sayesinde işlem gereksiz sorgulardan arındırılmış şekilde yalnızca hedef DC'lere odaklanarak ilerler.
Client, yalnızca SRV yanıtında dönen FQDN'lere ait Host (A) kayıtlarını sorgular. Forward Lookup Zone genelinde toplu bir tarama yapılmaz.
Bu süreci daha somut görmek için örnek bir DNS çözümleme akışı şu şekilde ilerler: Client, _ldap._tcp.dc._msdcs.abc.local adresine bir SRV sorgusu gönderir. DNS sunucusundan gelen yanıtta DC'lere ait FQDN bilgileri yer alır. Bu yanıtı aldıktan sonra Client, yalnızca belirli DC'ler için A kaydı sorgusu başlatır.
A? dc01.abc.local → 10.10.10.100
A? dc02.abc.local → 10.10.10.101
dc03 için sorgu yapılmamışsa, bu FQDN cldap ping aşamasında yanıt vermemiş ya da Priority/Weight sırasında çağırılacak hedeflerin dışında kalmış olabilir. Bu seçicilik, gereksiz DNS sorgularının önüne geçilmesi ve isim çözümleme trafiğinin sade tutulması açısından önemlidir. Forward Lookup Zone'daki tüm A kayıtlarını sorgulamak yerine yalnızca SRV yanıtı içindeki hedeflerin çözülmesi, süreci hem verimli hem güvenli kılar.
Client, SRV ve A DNS kayıtlarını çözüp Domain Controller'ın IP adresini öğrendikten sonra gerçek bağlantı aşamasına geçer. İsim çözümleme bu noktada tamamlanmış sayılır ve iletişim ilgili protokoller ile Port'lar üzerinden sürdürülür. İşletim sistemi, Domain Join sürecinde gerekli servisleri sırasıyla devreye alır; bu sıra, ortamdan gelen yanıtlar ve o anki gereksinimlere göre şekillenir.
Sürecin Tamamlanması
Bu makalede, bir Client'ın Active Directory ortamına Domain Join sürecinde izlediği teknik adımları tüm bileşenleriyle birlikte ele aldım. İşlem başlatıldığında arka planda devreye giren Netlogon servisi, DsGetDcName() API çağrısı üzerinden DNS yapılarına ulaşarak _ldap._tcp.dc._msdcs. formatındaki SRV kayıtlarını sorgular. Bu kayıtlar sayesinde hangi DC ile haberleşileceği belirlenir; cldap ping sonrası Client, kendi Site bilgisine en uygun DC üzerinden süreci sürdürür. DNS katmanındaki çözümleme tamamlandığında Client tarafında LSASS, makine hesabı için Secure Channel anahtarlarını saklayacak yapıyı hazırlar.
Computer Object'in fiziksel olarak oluşturulması Domain Controller tarafında gerçekleşir. Client, hedef DC ile LDAP kanalı üzerinden iletişime geçer; SAMR ve LSARPC RPC çağrıları ile makine hesabı kaydedilir. Bu sırada DNSHostname ve ServicePrincipalName gibi Attribute değerleri yazılır. İlk Join anında SPN'ler henüz yayılmadığı için kimlik doğrulama büyük ölçüde NTLM üzerinden ilerler; replikasyon ve makine parolasının oturmasının ardından Kerberos da devreye girer ve güven ilişkisi tam anlamıyla kurulur. Sürecin sonunda Client; Domain içindeki kaynaklarla konuşabilecek, Group Policy nesnelerini işleyebilecek ve DC ile Secure Channel üzerinden bağlantıda kalacak şekilde yapılandırılmış hale gelir.
Her adımda rol alan servisler, kullanılan API'ler, DNS kayıt türleri ve protokol seviyesindeki geçişler düşünüldüğünde Domain Join işleminin basit bir üyelik eyleminden çok daha kapsamlı bir altyapı çağrısı olduğu görülür. Arka plandaki bu teknik kurgu anlaşılmadan; sürecin neden zaman zaman başarısız olabileceğini ya da hangi detayların Log'lar üzerinden izlenebileceğini doğru yorumlamak mümkün değildir. Yapının bütünlüğü ancak bu derinliğe inilerek kavranabilir.
Faydalı olması dileğiyle...
Makale ile ilgili düşüncelerinizi ve sorularınızı aşağıdaki yorum kısmında paylaşmaktan çekinmeyin. Her katkı, içeriğin daha fazla kişiye ulaşmasını ve daha faydalı bir tartışma ortamı oluşmasını sağlar.