DNS kayıtları arasında en az tanınan ama doğru yapılandırıldığında hayat kurtaran kayıt türlerinden biri SRV kaydıdır. Bir servisin hangi sunucuda, hangi portta çalıştığını DNS seviyesinde tanımlamanıza olanak tanıyan bu kayıt türü, özellikle VoIP, anlık mesajlaşma, LDAP ve benzeri protokollerde kritik bir rol oynar. Bugün SRV kaydını tüm detaylarıyla ele alacağız, gerçek dünya senaryolarıyla nasıl yapılandırıldığını göreceğiz.
SRV Kaydı Nedir?
SRV (Service Record), RFC 2782 ile standartlaştırılmış bir DNS kayıt türüdür. Temel amacı bir alan adı altındaki belirli bir servisin, hangi host üzerinde ve hangi TCP/UDP portunda çalıştığını istemcilere bildirmektir.
Klasik bir A kaydı size sadece bir IP adresi döndürür. MX kaydı mail sunucusunu gösterir. Peki ya uygulamanızın dinamik olarak “bu servis nerede çalışıyor?” sorusunu sorması gerekiyorsa? İşte tam burada SRV devreye girer. Özellikle Kubernetes, SIP/VoIP altyapıları, XMPP sunucuları ve Microsoft Active Directory gibi ortamlarda SRV kayıtları olmadan hiçbir şey düzgün çalışmaz.
SRV Kaydının Anatomisi
Bir SRV kaydı şu formatı izler:
_servis._protokol.alan.adı. TTL IN SRV öncelik ağırlık port hedef
Bu formatı daha somut bir örnekle açıklayalım:
_sip._tcp.example.com. 3600 IN SRV 10 20 5060 sip1.example.com.
Bu kaydı parça parça inceleyelim:
- _sip: Servis adı, her zaman alt çizgi ile başlar
- _tcp: Protokol,
_tcpya da_udpolabilir - example.com.: Alan adı, sonundaki nokta önemli
- 3600: TTL değeri (saniye cinsinden, bu örnekte 1 saat)
- IN: Internet sınıfı
- SRV: Kayıt türü
- 10: Öncelik (priority), düşük değer daha yüksek öncelik
- 20: Ağırlık (weight), aynı öncelikteki sunucular arasında yük dağılımı
- 5060: Servisin çalıştığı port numarası
- sip1.example.com.: Hedef hostname, sonundaki nokta unutulmamalı
Priority ve Weight Mantığı
Bu iki parametre çok önemli, iyi anlaşılması gerekiyor.
Priority değeri, istemciye hangi kaydı önce denemesi gerektiğini söyler. Değer ne kadar düşükse o kayıt o kadar önceliklidir. Örneğin priority 10 olan sunucu, priority 20 olan sunucudan önce denenir. Bu sayede failover senaryolarını kolayca kurabilirsiniz.
Weight değeri ise aynı priority değerine sahip kayıtlar arasında yük dağılımını belirler. Ağırlığı yüksek olan sunucu daha fazla bağlantı alır. Örneğin iki sunucunuzdan biri weight 70, diğeri weight 30 ise ilki trafiğin yaklaşık %70’ini alır. Bu, DNS seviyesinde basit bir load balancing yapmak istediğinizde işe yarar.
Gerçek Dünya Kullanım Senaryoları
Senaryo 1: SIP/VoIP Altyapısı
Kurumsal bir VoIP altyapısı kuruyor olduğunuzu düşünelim. Şirketinizin example.com alan adı var ve iki SIP sunucunuz mevcut. Birincil sunucu her zamanki trafiği alacak, ikincisi ise yedek.
# Birincil SIP sunucusu (priority 10)
_sip._tcp.example.com. 3600 IN SRV 10 50 5060 sip-primary.example.com.
# Yedek SIP sunucusu (priority 20, birincil çökerse devreye girer)
_sip._tcp.example.com. 3600 IN SRV 20 50 5060 sip-backup.example.com.
# UDP üzerinden SIP (bazı istemciler UDP kullanır)
_sip._udp.example.com. 3600 IN SRV 10 50 5060 sip-primary.example.com.
_sip._udp.example.com. 3600 IN SRV 20 50 5060 sip-backup.example.com.
# A kayıtları da tanımlanmalı
sip-primary.example.com. 3600 IN A 192.168.1.10
sip-backup.example.com. 3600 IN A 192.168.1.11
Bu yapılandırmayla SIP istemcileri önce sip-primary.example.com:5060 adresini dener, bu sunucu yanıt vermezse otomatik olarak sip-backup.example.com:5060 adresine geçer.
Senaryo 2: Kubernetes Headless Service Keşfi
Kubernetes ortamında pod’lar arası servis keşfi SRV kayıtları üzerinden çalışır. Headless service tanımladığınızda Kubernetes DNS şu formatı kullanır:
# Kubernetes SRV formatı
_port-adı._protokol.servis-adı.namespace.svc.cluster.local.
Bunu test etmek için bir pod içinden sorgulayabilirsiniz:
# Kubernetes pod içinden SRV sorgusu
kubectl exec -it debug-pod -- nslookup -type=SRV _http._tcp.my-service.default.svc.cluster.local
# ya da dig ile daha detaylı
kubectl exec -it debug-pod -- dig SRV _http._tcp.my-service.default.svc.cluster.local
Senaryo 3: Microsoft Active Directory
Active Directory, domain controller’ları bulmak için SRV kayıtlarına tamamen bağımlıdır. Bir Windows client domain’e katılmak istediğinde aslında şu DNS sorgusunu yapar:
# AD domain controller keşfi
_ldap._tcp.dc._msdcs.example.local.
_kerberos._tcp.dc._msdcs.example.local.
_gc._tcp.example.local.
Bu kayıtlar Windows DNS tarafından otomatik oluşturulur ama Linux tabanlı bir DNS (bind, PowerDNS gibi) kullanıyorsanız manuel eklemeniz gerekebilir.
BIND9 ile SRV Kaydı Yapılandırması
En yaygın kullanılan açık kaynak DNS sunucusu BIND9 üzerinde SRV kaydı nasıl eklenir görelim.
# /etc/bind/zones/example.com.zone dosyasını düzenleyin
sudo nano /etc/bind/zones/example.com.zone
Zone dosyasına şunları ekleyin:
; Zone dosyası: example.com
$TTL 3600
@ IN SOA ns1.example.com. admin.example.com. (
2024010101 ; Serial
3600 ; Refresh
1800 ; Retry
604800 ; Expire
300 ) ; Minimum TTL
; NS kayıtları
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
; A kayıtları
ns1 IN A 203.0.113.1
ns2 IN A 203.0.113.2
www IN A 203.0.113.10
; SRV kayıtları - SIP servisi
_sip._tcp IN SRV 10 50 5060 sip1.example.com.
_sip._tcp IN SRV 20 50 5060 sip2.example.com.
_sip._udp IN SRV 10 50 5060 sip1.example.com.
; SRV kayıtları - XMPP (Jabber)
_xmpp-client._tcp IN SRV 5 0 5222 xmpp.example.com.
_xmpp-server._tcp IN SRV 5 0 5269 xmpp.example.com.
; SRV hedefleri için A kayıtları
sip1 IN A 203.0.113.20
sip2 IN A 203.0.113.21
xmpp IN A 203.0.113.30
Değişikliği uyguladıktan sonra BIND’ı reload edin:
# Zone dosyası sözdizimini kontrol et
sudo named-checkzone example.com /etc/bind/zones/example.com.zone
# BIND yapılandırmasını kontrol et
sudo named-checkconf
# BIND'ı yeniden yükle (tam restart gerekmez)
sudo systemctl reload bind9
# Servis durumunu kontrol et
sudo systemctl status bind9
PowerDNS ile SRV Kaydı Ekleme
PowerDNS kullanıyorsanız ve MySQL backend ile çalışıyorsanız SRV kaydını doğrudan veritabanına ekleyebilirsiniz:
# PowerDNS veritabanına SRV kaydı ekleme
mysql -u pdns -p pdns << 'EOF'
INSERT INTO records (domain_id, name, type, content, ttl, prio)
SELECT id, '_sip._tcp.example.com', 'SRV', '50 5060 sip1.example.com', 3600, 10
FROM domains WHERE name = 'example.com';
INSERT INTO records (domain_id, name, type, content, ttl, prio)
SELECT id, '_sip._tcp.example.com', 'SRV', '50 5060 sip2.example.com', 3600, 20
FROM domains WHERE name = 'example.com';
EOF
PowerDNS’in API’sini kullanarak da ekleyebilirsiniz:
# PowerDNS API ile SRV kaydı ekleme
curl -s -X PATCH
-H "X-API-Key: your-api-key"
-H "Content-Type: application/json"
http://localhost:8081/api/v1/servers/localhost/zones/example.com.
-d '{
"rrsets": [{
"name": "_sip._tcp.example.com.",
"type": "SRV",
"ttl": 3600,
"changetype": "REPLACE",
"records": [
{
"content": "10 50 5060 sip1.example.com.",
"disabled": false
},
{
"content": "20 50 5060 sip2.example.com.",
"disabled": false
}
]
}]
}'
SRV Kaydını Test Etme ve Doğrulama
Kayıtları ekledikten sonra mutlaka test edin. Linux üzerinde bunun için birkaç farklı araç kullanabilirsiniz:
# dig ile SRV sorgusu (en detaylı yöntem)
dig SRV _sip._tcp.example.com
# Belirli bir DNS sunucusuna sorgu
dig @8.8.8.8 SRV _sip._tcp.example.com
# Kısa çıktı için
dig +short SRV _sip._tcp.example.com
# nslookup ile
nslookup -type=SRV _sip._tcp.example.com
# host komutu ile
host -t SRV _sip._tcp.example.com
Sağlıklı bir dig çıktısı şöyle görünmelidir:
;; QUESTION SECTION:
;_sip._tcp.example.com. IN SRV
;; ANSWER SECTION:
_sip._tcp.example.com. 3600 IN SRV 10 50 5060 sip1.example.com.
_sip._tcp.example.com. 3600 IN SRV 20 50 5060 sip2.example.com.
;; ADDITIONAL SECTION:
sip1.example.com. 3600 IN A 203.0.113.20
sip2.example.com. 3600 IN A 203.0.113.21
Additional section’da A kayıtlarının da gelmesi önemlidir. DNS sunucusu bunu otomatik olarak ekler, buna “additional records” veya “glue records” denir. Eğer additional section boşsa hedef hostname’ler için A kayıtlarınızı gözden geçirin.
Yaygın Hatalar ve Çözümleri
Nokta Unutmak
En sık yapılan hata, hedef hostname’in sonundaki noktayı unutmaktır:
# YANLIS - sonunda nokta yok
_sip._tcp.example.com. 3600 IN SRV 10 50 5060 sip1.example.com
# DOGRU - sonunda nokta var
_sip._tcp.example.com. 3600 IN SRV 10 50 5060 sip1.example.com.
Eğer noktayı unutursanız DNS sunucusu bu hostname’i alan adınızın altında arar. Yani sip1.example.com yerine sip1.example.com.example.com gibi bir şey arar, bu da hiçbir zaman çözümlenmez.
Hedefi IP Adresi Olarak Girmek
SRV kaydının hedefi her zaman bir hostname olmalıdır, IP adresi giremezsiniz:
# YANLIS - hedef IP adresi
_sip._tcp.example.com. 3600 IN SRV 10 50 5060 192.168.1.10.
# DOGRU - hedef hostname
_sip._tcp.example.com. 3600 IN SRV 10 50 5060 sip1.example.com.
RFC 2782 bunu açıkça yasaklar. Hedef olarak “.” (tek nokta) girerseniz bu “bu servis mevcut değil” anlamına gelir ve istemciler başka kayıt aramayı durdurur.
CNAME Hedef Kullanmak
Hedef olarak CNAME kaydı olan bir hostname kullanamazsınız. SRV hedefi doğrudan bir A veya AAAA kaydına işaret etmelidir:
# Bu calismaz - mail.example.com bir CNAME ise
_imap._tcp.example.com. 3600 IN SRV 10 0 143 mail.example.com.
# Bunun yerine CNAME'in hedefini kullanin
_imap._tcp.example.com. 3600 IN SRV 10 0 143 mailserver1.example.com.
Load Balancing Senaryo Örneği
Diyelim ki üç LDAP sunucunuz var ve aralarında ağırlıklı yük dağılımı yapmak istiyorsunuz. Birinci sunucu toplam trafiğin %50’sini, ikinci %30’unu, üçüncü ise %20’sini alacak:
# Hepsi aynı priority (10), farklı weight değerleri
_ldap._tcp.example.com. 300 IN SRV 10 50 389 ldap1.example.com.
_ldap._tcp.example.com. 300 IN SRV 10 30 389 ldap2.example.com.
_ldap._tcp.example.com. 300 IN SRV 10 20 389 ldap3.example.com.
# Felaket kurtarma: eğer hepsi çökerse başka data center'a yönlendir
_ldap._tcp.example.com. 300 IN SRV 50 0 389 ldap-dr.example.com.
# A kayıtları
ldap1.example.com. 300 IN A 10.0.1.10
ldap2.example.com. 300 IN A 10.0.1.11
ldap3.example.com. 300 IN A 10.0.1.12
ldap-dr.example.com. 300 IN A 10.1.1.10
TTL değerini 300 saniye (5 dakika) olarak düşük tuttuğumuza dikkat edin. Yük dağılımı senaryolarında istemcilerin güncel sunucu bilgisini hızlıca alması için kısa TTL tercih edilir.
Python ile SRV Kaydı Sorgulama
Uygulamalarınızda SRV kaydı sorgulamak için Python’da dnspython kütüphanesini kullanabilirsiniz:
# dnspython kurulumu
pip install dnspython
# srv_lookup.py
import dns.resolver
def srv_lookup(service, proto, domain):
srv_record = f"_{service}._{proto}.{domain}"
try:
answers = dns.resolver.resolve(srv_record, 'SRV')
results = []
for answer in answers:
results.append({
'priority': answer.priority,
'weight': answer.weight,
'port': answer.port,
'target': str(answer.target)
})
# Önce priority'e göre, aynı priority'de weight'e göre sirala
results.sort(key=lambda x: (x['priority'], -x['weight']))
return results
except dns.resolver.NXDOMAIN:
print(f"SRV kaydı bulunamadı: {srv_record}")
return []
except Exception as e:
print(f"Sorgu hatası: {e}")
return []
# Kullanim
sunucular = srv_lookup('sip', 'tcp', 'example.com')
for s in sunucular:
print(f"Hedef: {s['target']}:{s['port']} "
f"(Priority: {s['priority']}, Weight: {s['weight']})")
Popüler Servisler için Standart SRV Formatları
Her servisin kendine ait standart servis ve protokol adları vardır. Bunları RFC belgelerinden ya da IANA’nın servis adı veritabanından bulabilirsiniz. Sık kullanılanlar şunlardır:
- _sip._tcp ve _sip._udp: SIP/VoIP, port 5060
- _sips._tcp: Güvenli SIP (TLS), port 5061
- _xmpp-client._tcp: XMPP istemci bağlantısı, port 5222
- _xmpp-server._tcp: XMPP sunucular arası, port 5269
- _ldap._tcp: LDAP dizin servisi, port 389
- _ldaps._tcp: Güvenli LDAP, port 636
- _imap._tcp: IMAP mail, port 143
- _imaps._tcp: Güvenli IMAP, port 993
- _submission._tcp: Mail gönderimi, port 587
- _kerberos._tcp: Kerberos kimlik doğrulama, port 88
- _minecraft._tcp: Minecraft sunucu keşfi, port 25565
- _caldavs._tcp: CalDAV takvim servisi, port 443
- _carddavs._tcp: CardDAV rehber servisi, port 443
Kendi özel uygulamanız için SRV kaydı tanımlıyorsanız IANA’ya kayıtlı olmayan servis adlarında başına _ ekleyip açıklayıcı bir isim seçin. Örneğin _myapp._tcp.example.com gibi.
Güvenlik Notları
SRV kayıtları DNS güvenliği açısından birkaç noktada dikkat gerektirir.
DNSSEC kullanıyorsanız SRV kayıtları da diğer kayıt türleri gibi imzalanır ve bu önemlidir. Özellikle kurumsal ortamlarda bir saldırgan sahte SRV kayıtları enjekte ederek VoIP trafiğini ya da LDAP kimlik doğrulama isteklerini kendi sunucusuna yönlendirebilir.
TTL değerlerini seçerken dikkatli olun. Çok yüksek TTL değerleri failover sürelerini uzatır, çok düşük değerler ise DNS sunucunuza fazladan yük bindirir ve dış resolver’ların cache’ini hızlı tüketir. Üretim ortamları için 300-900 saniye arası genellikle makul bir değerdir.
Hedef hostname’lerinizin başka alan adlarına ait olmasına izin vermeyin. Örneğin SRV kaydınızın hedefini sip1.third-party-company.com gibi kontrol edemediğiniz bir hostname’e yönlendirirseniz o şirketin DNS’ini değiştirmesi sizi doğrudan etkiler.
Sonuç
SRV kaydı, DNS’in sunduğu en güçlü araçlardan biri olmasına karşın birçok sysadmin tarafından göz ardı edilir. Oysa doğru kullanıldığında uygulama katmanında hiçbir değişiklik yapmadan failover, load balancing ve servis keşfi gibi kritik işlevleri sağlayabilirsiniz.
Özetlemek gerekirse şunları aklınızda tutun:
- SRV kayıtları
_servis._protokol.alan.adıformatını izler - Priority düşüklüğü yüksek öncelik demektir, weight yüksekliği daha fazla trafik demektir
- Hedef her zaman hostname olmalı, IP adresi veya CNAME olmamalı
- Sonundaki noktayı asla unutmayın
- Hedef hostname’ler için A/AAAA kayıtlarını mutlaka tanımlayın
dig SRVkomutu en güvenilir test aracınızdır
Active Directory ortamı kuruyorsanız, VoIP altyapısı yapılandırıyorsanız ya da mikroservis mimarilerinde servis keşfine ihtiyaç duyuyorsanız SRV kayıtlarını doğru anlamak ve doğru yapılandırmak size ciddi zaman kazandıracaktır. Bir sonraki DNS sorun giderme oturumunuzda önce SRV kayıtlarını kontrol etmeyi alışkanlık haline getirin.