dnspython ile DNS sorgulama, yalnızca bir alan adını çözüp sonucu ekrana yazdırmaktan ibaret değildir. Uygulamada kullanılacak recursive resolver (özyinelemeli DNS çözümleyicisi), sorgu adı, kayıt türü, toplam bekleme süresi ve hata durumlarının nasıl ele alınacağı açıkça belirlenmelidir.

dnspython'ın resolver modülü, sorguyu recursive resolver'a iletip yanıtı uygulamaya döndüren bir DNS istemcisi, yani stub resolver sunar. Varsayılan yapılandırmada işletim sisteminin belirlediği recursive resolver ile çalışır. Uygulama gerektiriyorsa recursive resolver listesi ayrıca tanımlanabilir. Bu seçim, alınan yanıtı ve iç ağ adlarının çözülebilmesini doğrudan etkiler.

dnspython ile DNS Sorgusunu Hazırlama ve Yanıtı İşleme

  • Projede kullanılan dnspython ve Python sürümünü sabitleyin; yöntem ve istisna adlarını aynı sürümün resmi belgesinden doğrulayın.
  • İşletim sistemi DNS ayarlarını mı yoksa uygulamaya özel recursive resolver'ları mı kullanacağınızı belirleyin.
  • Tek bir DNS sunucusundan yanıt bekleme süresi ile sorgunun tüm denemelerine ayrılan toplam süreyi ayrı ayrı yapılandırın.
  • Sorgu adını, kayıt türünü ve gerekirse DNS sınıfını açık girdiler olarak verin.
  • Answer içindeki RRset'i (aynı ada, türe ve sınıfa ait kayıt kümesini), kayıt verisini, önbellekte kalma süresini belirten TTL değerini ve takma ad zincirinin sonundaki kanonik adı ayrı ayrı işleyin.
  • NXDOMAIN, NoAnswer, LifetimeTimeout ve NoNameservers durumlarını aynı genel hata olarak ele almayın.

Resolver için DNS Sunucusu ve Sorgu Ayarları

Resolver nesnesi, uygulamanın recursive resolver'a sorgu gönderen istemci katmanıdır. Varsayılan yapılandırma POSIX sistemlerde /etc/resolv.conf dosyasını, Windows'ta ise kayıt defterindeki DNS ayarlarını okuyabilir. Bu işlem DNS sunucusu adreslerini ve desteklenen ayarları alır; işletim sisteminin bütün ad çözümleme davranışını devralmaz. Örneğin dnspython doğrudan /etc/hosts dosyasını kullanmaz. Bu nedenle sistemde çözülen bir iç ağ adının dnspython ile de çözüleceği varsayılmamalıdır.

Sistem DNS Ayarları ile Özel Recursive Resolver Seçimi

Aynı alan adına sorgunun geldiği ağa göre farklı yanıtlar verilen split-horizon DNS düzeninde, iç ağ adlarını bilen recursive resolver'ı kullanmak gerekir. Sistem DNS ayarları bu sunucuları sağlayabilir; seçilen sunucuların ve VPN erişiminin uygulamanın çalıştığı ortamda doğrulanması önemlidir. Buna karşılık belirli bir test ortamında veya denetimli bir hizmette aynı recursive resolver grubunu kullanmak isteniyorsa Resolver nesnesinin nameservers alanı uygulama tarafından yönetilebilir. Sistem ayarları okunmadan başlamak için Resolver nesnesi configure=False ile oluşturulursa nameservers listesi ayrıca doldurulmalıdır.

Özel bir recursive resolver seçmek yalnız teknik bir yönlendirme kararı değildir. Bu hizmet sorgulanan alan adlarını görebilir, farklı önbellek veya filtreleme politikaları uygulayabilir ve iç ağ adlarını bilmeyebilir. Bu nedenle genel kullanıma açık bir DNS sunucusu adresini her ortamın varsayılanı yapmak yerine, seçimin nedenini yapılandırmada belirtin.

Timeout ile Lifetime Arasındaki Farklar

Resolver üzerindeki timeout, tek bir DNS sunucusundan yanıt bekleme süresini sınırlar. Bir diğer ayar olan lifetime ise farklı denemeler ve sunucular dahil sorgunun tamamına ayrılan toplam süreyi belirler. Yalnız timeout değerini değiştirmek, uygulamanın toplamda ne kadar bekleyeceğini tek başına belirlemez.

Bu değerler kullanıcı arayüzü, arka plan işi ve toplu sorgu gibi kullanım biçimlerine göre farklı olabilir. Çok kısa sınırlar, geçerli olduğu halde geciken yanıtları hata sayabilir; çok uzun sınırlar ise iş parçacıklarını veya istek havuzunu gereğinden fazla meşgul edebilir. Yeniden deneme uygulanacaksa toplam süre bütçesi ve azami deneme sayısı birlikte sınırlandırılmalıdır.

Arama Listesi ve Tam Alan Adı Kullanımı

Göreli bir ad, Resolver arama listesi devredeyse farklı alan adı son ekleri eklenerek denenebilir. Genel internet alan adlarında aynı adın her ortamda sorgulanması için example.com. gibi sonundaki noktayla DNS kökünü açıkça belirten tam alan adı kullanılmalıdır. resolve çağrısında search=False verilmesi de arama listesiyle son ek eklenmesini engeller. Kurumsal arama listesiyle genişletme yalnız bilinçli bir seçimse etkinleştirilmelidir.

Bu ayrım özellikle aynı uygulamanın geliştirici bilgisayarında, konteynerde ve üretim sunucusunda farklı sonuç vermesini önlemek için önemlidir. Uygulama, kullanıcının yazdığı değeri ve gerçekten sorgulanan tam adı ayrı alanlarda tutabilir.

Sorgu Adı, Kayıt Türü ve DNS Sınıfı

Bir DNS sorgusunun soru bölümü QNAME, QTYPE ve QCLASS alanlarından oluşur. dnspython tarafında bunlar sırasıyla sorgu adı, kayıt türü ve kayıt sınıfı olarak Resolver.resolve çağrısına aktarılır. İnternet sorgularında sınıf çoğunlukla IN olsa da kayıt türü her kullanım amacı için açıkça seçilmelidir.

A kayıtları IPv4 adresi, AAAA kayıtları IPv6 adresi, MX kayıtları e-posta sunucusu, NS kayıtları yetkili DNS sunucusu, TXT kayıtları metin tabanlı bilgi ve CNAME kayıtları takma adın hedefini döndürür. Uygulama tüm kayıtları tek bir metin alanı gibi işlememeli; istenen türü önceden izin verilen bir listeyle sınırlandırmalı ve kayıt içeriğini taşıyan RDATA nesnelerini o türe uygun alanlara ayırmalıdır. Sorgu adının biçimi ve uzunluğu da DNS ad kurallarına ve uygulamanın izin verdiği kapsama göre doğrulanmalıdır.

Yeni Uygulamalarda Resolve Yönteminin Kullanımı

Güncel resolver arayüzünün temel yöntemi resolve'dur. Geriye dönük uyumluluk için korunan query yöntemi, resolve'u search=True ile çağırır. resolve çağrısında search belirtilmezse use_search_by_default ayarı kullanılır; bu ayar varsayılan olarak False değerindedir. Bu nedenle göreli adlarda query ile resolve farklı sonuç verebilir. Yeni bir uygulamada yöntem seçimi, kurulu sürümün resmi API belgesine göre yapılmalı ve eski örneklerden kopyalanan çağrılar doğrudan üretime alınmamalıdır.

PTR sorgusu için bir IP adresini elle ters bölge adına çevirmek yerine dnspython'ın resolver arayüzündeki resolve_address yardımcısı kullanılabilir. Bu yardımcı yöntem, PTR kayıt türünü ve ters DNS adını uygulamanın elle hazırlama zorunluluğunu ortadan kaldırır.

Yanıt Bulunmadığında Uygulama Davranışı

resolve çağrısında raise_on_no_answer etkinse, ad var olduğu halde istenen türde RRset bulunmaması NoAnswer istisnası üretir. Bu seçenek kapatılırsa Answer nesnesi dönebilir ancak rrset alanı boş olabilir. Uygulama bu iki davranıştan hangisini kullandığını bilmeden doğrudan kayıtlar üzerinde döngü kurmamalıdır.

Uygulama, DNS yanıtında RRset bulunmaması ile yanıt işlendikten sonra kayıt listesinin boş kalmasını birbirinden ayırmalıdır. İlk durum, istenen türde yanıt alınmadığını gösterir. İkinci durumda ise gelen kayıtlar ayrıştırma veya filtreleme sırasında elenmiş olabilir.

DNS Yanıtının RRset, Tür ve TTL Bilgileriyle Ayrıştırılması

Başarılı çözümleme bir Answer nesnesi döndürür. Bu nesne sorgu adını, kayıt türünü, DNS sınıfını, ham yanıt mesajını ve yanıt RRset'ini birlikte taşır. Answer nesnesi üzerinde döngü kurulduğunda işlem RRset kayıtları üzerinde yürür. CNAME veya DNAME zinciri varsa sonuç RRset'inin sahibi ilk sorgulanan addan farklı olabilir.

Kayıt Verisini Türüne Göre Okuma

Her RDATA türünün alanları farklıdır. A ve AAAA kayıtlarında IP adresi, MX kaydında öncelik ve hedef, SOA kaydında ise bölgenin birincil DNS sunucusunun adı, bölge sorumlusunun posta kutusu, seri numarası ve zamanlama değerleri bulunur. SOA içindeki posta kutusu bir DNS adı biçiminde kodlanır; doğrudan e-posta adresi metni olarak kullanılmamalıdır. Yalnız metin biçimine dönüştürmek hızlı bir gösterim üretebilir; fakat sıralama, doğrulama veya veri tabanına yazma gerekiyorsa türün yapısal alanları korunmalıdır.

Yanıtın qname alanı, bu yanıt için gerçekten sorgulanan DNS adını; canonical_name alanı ise CNAME ve DNAME zinciri sonrasında ulaşılan adı gösterir. Arama listesi göreli adı genişlettiyse qname, kullanıcının yazdığı ham girdiden farklıdır. Ham girdi, qname ve canonical_name ayrı kaydedildiğinde hem son ek eklenmesi hem de takma ad zincirinden kaynaklanan hedef değişiklikleri izlenebilir.

TTL ve Uygulama Önbelleği

RRset üzerindeki TTL, kayıt kümesinin kaç saniye önbellekte tutulabileceğini belirtir. Bu değer kaydın sonsuza kadar geçerli olduğunu veya yetkili sunucudaki değişikliğin tam o saniyede tüm dünyaya yansıyacağını göstermez; yalnız ilgili kayıt kümesinin yeniden sorgulanmadan kullanılabileceği en uzun süreyi ifade eder. Yanıt bir CNAME zinciri içeriyorsa zincirdeki daha kısa TTL, yanıtın kullanım süresini daha erken bitirebilir. Answer.expiration, bu süreleri dikkate alarak hesaplanan sona erme zamanını tutar; yalnız son RRset'in TTL değerine göre önbellek süresi belirlemek yeterli değildir.

dnspython Resolver nesnesinde yerel önbellek varsayılan olarak etkin değildir. Cache veya LRUCache nesnesi Resolver nesnesinin cache alanına atanarak önbellek etkinleştirilebilir. Bu sınıflar olumlu ve olumsuz yanıtları uygun DNS süreleriyle saklar, süresi dolan yanıtları yeniden kullanmaz. LRUCache ayrıca boyut sınırına ulaşıldığında en uzun süredir kullanılmayan girdileri çıkarır. Uygulama bunların yerine kendi önbelleğini yazıyorsa sorgu adı, kayıt türü ve DNS sınıfını ayırt etmeli; CNAME zincirinin ve olumsuz yanıtların süre kurallarını da uygulamalıdır. Uygulama DNS sorgusu sonucunu TTL değerinden daha uzun saklayacaksa, güncelliğini yitirmiş verinin ne zaman kullanılabileceğini ve kullanıcıya nasıl bildirileceğini açıkça belirlemelidir.

Ham Mesajın Ne Zaman Gerekli Olduğu

Çoğu uygulama için Answer.rrset yeterlidir. Yetki ve ek bölümler, yanıt kodu veya genişletilmiş DNS bilgileri gerektiğinde Answer.response alanındaki QueryMessage incelenebilir. Yanıtın tamamını kullanıcıya göstermek yerine yalnız tanılama ve ölçüm için gereken alanları seçerek kaydetmek daha güvenlidir.

DNS Hatalarını Ayrı Durumlara Dönüştürme

DNS başarısızlıkları tek bir “sorgu yapılamadı” sonucuna indirgenirse uygulama yanlış yeniden deneme yapar ve kullanıcıya hatalı açıklama verir. Aşağıdaki tablo, dnspython resolver arayüzündeki temel durumların uygulamada nasıl ele alınabileceğini gösterir.

Durumdnspython sonucuUygulama davranışı
Alan adı yokNXDOMAINAdın bulunmadığını belirtin; alan adının tam yazımı kontrol edilmeden otomatik tekrar yapmayın.
İstenen kayıt türü yokNoAnswerAlan adının var olabileceğini, fakat sorulan türde RRset bulunmadığını ayrı sonuç olarak gösterin.
Toplam süre dolduLifetimeTimeoutYalnız geçici hata kuralları kapsamında sınırlı yeniden deneme yapın veya kullanımına izin verilen alternatif bir recursive resolver deneyin.
Kullanılabilir sunucu kalmadıNoNameserversSunucu yanıt kodlarını ve taşıma hatalarını uygulama günlüğünde sınıflandırın; kullanıcıya ham istisna döndürmeyin.

NXDOMAIN ile NoAnswer Arasındaki Farklar

NXDOMAIN, sorgulanan adın DNS ad alanında bulunmadığını bildirir. NoAnswer ise adın var olmasına rağmen istenen tür ve sınıfta yanıt RRset'i olmadığını belirtir. Örneğin bir adın A kaydı bulunurken MX kaydı bulunmaması NoAnswer olabilir; bu durum alan adının bütünüyle yok olduğu anlamına gelmez.

Geçici Hatalarda Yeniden Deneme

LifetimeTimeout ve NoNameservers hatasına yol açan bazı durumlar geçici olabilir, ancak sınırsız yeniden deneme DNS hizmetine ve uygulama kaynaklarına yük bindirir. Denemeler toplam bekleme süresi, azami sayı ve artan aralıklarla sınırlandırılmalı; aynı sorgunun eşzamanlı kopyaları mümkünse birleştirilmelidir.

NXDOMAIN ve NoAnswer için kör yeniden deneme genellikle uygun değildir. DNS kayıtlarında değişiklik olması beklendiği için sorgu tekrarlanacaksa bekleme aralığı, önceki yanıtın TTL değeriyle veya olumsuz yanıtın önbellek süresiyle uyumlu olmalıdır.

Beklenmeyen İstisnalar

Resolver'a özgü istisnalar önce yakalanmalı, daha genel DNSException ise ancak son güvenlik ağı olarak kullanılmalıdır. Genel yakalama, programlama hatalarını veya yanlış veri türlerini DNS kesintisi gibi göstermemelidir. Kullanıcı yanıtında dahili dosya yolu, recursive resolver kimlik bilgisi veya ham üçüncü taraf mesajı yer almamalıdır.

Üretim Ortamında Doğrulama ve İzleme

Yerel önbellekten karşılanmayan DNS sorgusu, seçilen DNS sunucusuna erişmeyi gerektirir; bu sunucu yerel cihazda, iç ağda veya internette olabilir. Başarı yalnız kayıt bulunmasıyla ölçülmemelidir. Sorgulanan tam ad, kayıt türü, kullanılan recursive resolver, geçen süre, sonuç türü ve gerekiyorsa yanıt veren DNS sunucusu izleme verisi olarak tutulabilir. Kullanıcı tarafından girilen alan adları gizlilik açısından hassas olabileceği için saklama süresi ve erişim yetkisi sınırlandırılmalıdır.

dnspython Sürümü ile API Belgesinin Eşleştirilmesi

dnspython'ın stable ve latest belgeleri farklı sürümlere ait olabilir. Bağımlılık dosyasında kullanılan sürümü sabitleyin, CI (Continuous Integration) ortamında gerçekten kurulan sürümü raporlayın ve Resolver, Answer ve resolve arayüzleriyle istisna adlarını o sürümün belgesi üzerinden kontrol edin. Bir üst sürüme geçişte gereken en düşük Python sürümü ve değişen varsayılanlar ayrıca incelenmelidir.

dnspython İçin Denetimli DNS Testleri

Testler yalnız bilinen bir A kaydının dönmesini doğrulamamalıdır. Test kapsamına en az bir başarılı çoklu kayıt yanıtı, CNAME zinciri, NoAnswer, NXDOMAIN, zaman aşımı, kullanılamayan recursive resolver ve rrset alanının boş olduğu bir yanıt eklenmelidir. İnternetteki rastgele alan adlarına bağlı testler zamanla değişebileceği için denetimli DNS kayıtları veya test için üretilen kontrollü yanıtlar tercih edilmelidir.

Senkron ve Asenkron DNS Sorguları

Az sayıda sorgu yapan komut veya arka plan işi için senkron resolver yeterli olabilir. Çok sayıda bağımsız sorgunun aynı süreçte beklemesi gerekiyorsa dnspython'ın asenkron resolver arayüzü kullanılabilir; ancak NXDOMAIN, NoAnswer ve zaman aşımı gibi sonuçların anlamı değişmez. Yüksek eşzamanlılık tek başına güvenli ve sürdürülebilir bir performans artışı sağlamaz; oran sınırı ile toplam dış istek sayısı da kontrol edilmelidir.