DNS Çözümleme Sorunları: Linux’ta Adım Adım Hata Ayıklama
Bir production sunucusunda aniden web sitelerine erişilemiyor, uygulamalar harici servislere bağlanamıyor ve kullanıcılar şikayet yağmuruna tutuyor. Logları açıyorsun, her yerde “Could not resolve host” veya “Name or service not known” hataları. DNS sorunları tam da böyle gelir: ani, sinir bozucu ve bazen gereksiz yere uzun süren bir hata ayıklama maratonu. Bu yazıda Linux sistemlerde DNS çözümleme sorunlarını sistematik bir şekilde nasıl teşhis edip çözeceğini, gerçek dünya senaryoları üzerinden anlatacağım.
DNS Nasıl Çalışır, Nerede Bozulur?
Önce temel akışı netleştirelim. Bir Linux sisteminde bir domain adı çözümlenmeye çalışıldığında şu adımlar gerçekleşir:
- Uygulama
getaddrinfo()gibi bir sistem çağrısı yapar nsswitch.confhangi kaynakların kullanılacağını belirler- Genellikle önce
/etc/hostsdosyası kontrol edilir - Ardından
/etc/resolv.confiçindeki DNS sunucularına sorgu gönderilir - Eğer systemd-resolved kullanılıyorsa, sorgu önce yerel cache’e gider
- Yanıt gelirse uygulamaya döner, gelmezse timeout
Bu zincirin herhangi bir halkasında bir sorun olabilir. Yani “DNS çalışmıyor” dediğimizde aslında çok farklı şeyler ifade edebiliriz.
İlk Adım: Basit Teşhis Araçları
Panik yapmadan önce birkaç basit komutla durumu anlayalım.
ping ile Başla
ping -c 3 google.com
ping -c 3 8.8.8.8
Eğer IP adresine ping atabiliyorsun ama domain adına atamıyorsun, sorun kesinlikle DNS’te. Eğer her ikisine de atamıyorsun, network bağlantısını önce kontrol etmen gerekiyor.
nslookup ve dig ile Sorgula
# Temel sorgu
nslookup google.com
# Belirli bir DNS sunucusunu kullanarak sorgu
nslookup google.com 8.8.8.8
# dig ile detaylı sorgu
dig google.com
# Kısa çıktı için
dig +short google.com
# Belirli DNS sunucusuna sor
dig @8.8.8.8 google.com
# Trace ile tüm çözümleme zincirini gör
dig +trace google.com
dig komutu DNS hata ayıklamasının vazgeçilmez aracıdır. ANSWER SECTION kısmında sonuç görüyorsan çözümleme başarılıdır. SERVFAIL veya NXDOMAIN görüyorsan sorunun kaynağını anlamaya başlayabilirsin.
host Komutu
host google.com
host google.com 8.8.8.8
host -v google.com
/etc/resolv.conf Kontrolü
Bu dosya DNS yapılandırmasının kalbidir. Boş, hatalı veya yanlış sunucu adresleri içeriyorsa hiçbir şey çalışmaz.
cat /etc/resolv.conf
Tipik ve sağlıklı bir resolv.conf şöyle görünür:
nameserver 8.8.8.8
nameserver 8.8.4.4
search example.com
options ndots:5
Dikkat etmen gereken durumlar:
- nameserver satırı yoksa: DNS sunucusu tanımlı değil demektir
- 127.0.0.53 varsa: systemd-resolved kullanılıyor demektir
- 127.0.0.1 varsa: Yerel bir DNS önbelleği (dnsmasq gibi) çalışıyor olabilir
- Dosya semboli link ise:
ls -la /etc/resolv.confile nereye işaret ettiğine bak
Sistemin resolv.conf dosyası boşsa veya sadece yorum satırları varsa, hemen bir nameserver ekleyebilirsin:
# Geçici çözüm - sistem yeniden başlayınca kaybolabilir
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
echo "nameserver 1.1.1.1" >> /etc/resolv.conf
Ama dikkat, bu dosya bazı sistemlerde otomatik olarak yönetilir ve değişiklikleriniz üzerine yazılabilir.
/etc/nsswitch.conf Kontrolü
Bu dosya göz ardı edilen ama kritik bir yapılandırma dosyasıdır. hosts satırına bak:
grep hosts /etc/nsswitch.conf
Beklenen çıktı şuna benzer olmalı:
hosts: files dns myhostname
Bu sıra önemlidir:
- files:
/etc/hostsdosyasına bak - dns: DNS sunucularına sor
- myhostname: Sistemin kendi hostname’ini çöz
Eğer dns bu listede yoksa, sistem DNS sorgusu hiç yapmıyor demektir. Bu nadir ama gördüğüm gerçek bir sorun. Özellikle bazı minimal container imajlarında bu satır kırpılmış gelir.
systemd-resolved Sorunları
Modern Ubuntu, Fedora, Debian sistemlerinde systemd-resolved varsayılan DNS yöneticisidir. Pek çok DNS sorunu burada yaşanır.
Durumu Kontrol Et
# Servis durumunu kontrol et
systemctl status systemd-resolved
# Detaylı DNS durumu
resolvectl status
# İstatistikler
resolvectl statistics
# Cache'i göster
resolvectl dns
resolvectl status çıktısında her network arayüzü için hangi DNS sunucularının kullanıldığını görebilirsin. Boş görünüyorsa sorun buradadır.
Cache Temizleme
DNS sorunlarının önemli bir kısmı hatalı cache kayıtlarından gelir. Özellikle bir IP değişikliği yaptıktan sonra eski kayıtlar sorun çıkarır.
# systemd-resolved cache'ini temizle
sudo resolvectl flush-caches
# Eski komut satırı alternatifi
sudo systemd-resolve --flush-caches
# Cache istatistiklerini kontrol et
resolvectl statistics
resolv.conf ve systemd-resolved Çakışması
Bu çok sık karşılaştığım bir senaryo. Sistem systemd-resolved kullanıyor ama /etc/resolv.conf yanlış yapılandırılmış.
# resolv.conf'un nereye işaret ettiğini kontrol et
ls -la /etc/resolv.conf
# Eğer link değilse ve systemd-resolved varsa, düzelt:
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
Alternatif olarak systemd-resolved‘in tam çıktısını veren dosyayı kullanabilirsin:
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
İkisi arasındaki fark: stub-resolv.conf 127.0.0.53’ü gösterir ve systemd-resolved üzerinden gider. resolv.conf ise gerçek upstream DNS sunucularını gösterir ve systemd-resolved bypass edilir.
NetworkManager DNS Sorunları
Masaüstü sistemlerde veya NetworkManager kullanan serverlarda DNS yapılandırması burada yönetilir.
# Mevcut bağlantıların DNS ayarlarını gör
nmcli con show
nmcli con show "Bağlantı Adı" | grep DNS
# DNS sunucusu ayarla
sudo nmcli con mod "Bağlantı Adı" ipv4.dns "8.8.8.8 8.8.4.4"
sudo nmcli con mod "Bağlantı Adı" ipv4.ignore-auto-dns yes
# Değişikliği uygula
sudo nmcli con up "Bağlantı Adı"
NetworkManager bazen DHCP’den aldığı DNS sunucularını siler veya üzerine yazar. Loglara bak:
journalctl -u NetworkManager --since "1 hour ago" | grep -i dns
DHCP ile Gelen DNS Ayarları
Sunucu DHCP kullanıyorsa ve DNS sunucusu yanlış geliyor olabilir. Bunu anlamak için:
# dhclient ile gelen DNS'i gör
cat /var/lib/dhclient/dhclient.leases | grep domain-name-servers
# systemd-networkd kullanan sistemlerde
networkctl status
# journald'da DHCP olaylarını ara
journalctl | grep -i "dhcp" | grep -i "dns|nameserver" | tail -20
Eğer DHCP’den hatalı DNS geliyorsa ve bunu ezmen gerekiyorsa, NetworkManager üzerinden ipv4.ignore-auto-dns yes ayarı işe yarar.
Gerçek Dünya Senaryosu 1: Container İçinde DNS Çalışmıyor
Docker container’ı başlattın, içeride apt update yapıyorsun, “Temporary failure in name resolution” hatası alıyorsun. Bu çok yaygın bir durum.
# Container içinde kontrol
docker exec -it container_adi cat /etc/resolv.conf
docker exec -it container_adi ping 8.8.8.8
docker exec -it container_adi nslookup google.com
# Host DNS durumunu kontrol et
cat /etc/resolv.conf
# Docker daemon DNS ayarını kontrol et
cat /etc/docker/daemon.json
Eğer /etc/docker/daemon.json yoksa veya DNS ayarı yoksa:
sudo tee /etc/docker/daemon.json > /dev/null <<EOF
{
"dns": ["8.8.8.8", "8.8.4.4"],
"dns-search": []
}
EOF
sudo systemctl restart docker
Host sistemde systemd-resolved çalışıyorsa ve Docker 127.0.0.53’ü almaya çalışıyorsa container içinden bu adrese erişilemez çünkü loopback adresi container içinde farklı anlam ifade eder.
Gerçek Dünya Senaryosu 2: VPN Bağlantısı Sonrası DNS Kırılması
VPN bağlandıktan sonra internal domain’ler çözülüyor ama internet domain’leri çözülemiyor veya tam tersi. Bu split-DNS yapılandırması sorunudur.
# Hangi arayüzde hangi DNS kullanılıyor?
resolvectl status
# Routing tablosunu kontrol et
ip route show
# DNS politikasını kontrol et
resolvectl dns
resolvectl domain
VPN ile gelen DNS ayarlarının hangi domain’ler için kullanılacağını belirlemek gerekebilir:
# Belirli domain'i belirli DNS ile çöz
dig @10.0.0.1 internal.company.com
# Split-DNS için systemd-resolved yapılandırması
# /etc/systemd/resolved.conf.d/vpn.conf dosyası oluştur
sudo mkdir -p /etc/systemd/resolved.conf.d/
sudo tee /etc/systemd/resolved.conf.d/vpn.conf > /dev/null <<EOF
[Resolve]
DNS=10.0.0.1
Domains=~company.com
EOF
sudo systemctl restart systemd-resolved
Gerçek Dünya Senaryosu 3: Yüksek Gecikmeli DNS Sorguları
Uygulama yavaş çalışıyor, log’lara baktığında her DNS sorgusunun 2-3 saniye sürdüğünü görüyorsun. Bu genellikle IPv6 DNS sorunudur.
# DNS sorgu süresini ölç
time dig google.com
time dig google.com @8.8.8.8
# IPv6 sorgusunu test et
dig AAAA google.com
time dig AAAA google.com
# strace ile uygulamanın DNS çağrılarını izle
strace -e trace=network -f uygulama_adi 2>&1 | grep -i "connect|send|recv" | head -30
Eğer AAAA sorguları çok uzun sürüyorsa ve IPv6 kullanmıyorsan, resolv.conf veya resolved.conf‘a şunu ekleyebilirsin:
# /etc/systemd/resolved.conf içine ekle
sudo tee -a /etc/systemd/resolved.conf > /dev/null <<EOF
[Resolve]
LLMNR=no
MulticastDNS=no
EOF
# Ya da resolv.conf'a options satırı ekle
echo "options single-request-reopen" | sudo tee -a /etc/resolv.conf
ndots değeri de gecikmeye neden olabilir. options ndots:5 ayarı, nokta sayısı 5’ten az olan her domain için önce search domain’leri dener. Bu gereksiz sorgulara yol açar:
# ndots değerini düşür
echo "options ndots:1" | sudo tee -a /etc/resolv.conf
nscd ve dnsmasq ile Cache Sorunları
Bazı sistemlerde nscd (Name Service Cache Daemon) veya dnsmasq yerel DNS cache olarak çalışır.
# nscd çalışıyor mu?
systemctl status nscd
# nscd cache'ini temizle
sudo nscd -i hosts
# dnsmasq durumu
systemctl status dnsmasq
# dnsmasq loglarını kontrol et
journalctl -u dnsmasq --since "30 min ago"
# dnsmasq cache boyutunu kontrol et
dig +short chaos txt cachesize.bind @127.0.0.1
Hem systemd-resolved hem de nscd aynı anda çalışıyorsa çakışma yaşanabilir. Hangisini kullanacağına karar ver ve diğerini devre dışı bırak.
hosts Dosyasındaki Çakışmalar
# hosts dosyasını kontrol et
cat /etc/hosts
# Belirli bir kayıt var mı?
grep "google.com" /etc/hosts
# getent ile çözümlemenin nasıl yapıldığını test et
getent hosts google.com
getent hosts localhost
getent hosts komutu nsswitch.conf‘a göre tam çözümleme sürecini simüle eder. DNS yerine bu komutla test yapmak daha güvenilir sonuç verir çünkü dig ve nslookup nsswitch.conf‘u kullanmaz, direkt DNS’e gider.
Firewall ve iptables DNS Engellemesi
Bazen sorun DNS servislerin kendisinde değil, güvenlik duvarının 53 numaralı portu engellemesidir.
# iptables kurallarını kontrol et
sudo iptables -L -n | grep -i "53|dns"
sudo iptables -t nat -L -n | grep 53
# UDP 53'e gidip gelmediğini kontrol et
sudo tcpdump -i any -n port 53 &
dig google.com
# Ctrl+C ile durdur
# nftables kullanan sistemlerde
sudo nft list ruleset | grep -A 2 -B 2 "53"
Eğer tcpdump çıktısında sorgu gönderildiğini ama yanıt gelmediğini görüyorsan, ya DNS sunucusu yanıt vermiyor ya da firewall cevabı engelliyor demektir.
# DNS sunucusuna UDP ile ulaşılabiliyor mu?
nc -zuv 8.8.8.8 53
nc -zuv 8.8.4.4 53
# TCP fallback çalışıyor mu?
nc -zv 8.8.8.8 53
dig +tcp google.com @8.8.8.8
systemd-resolved Detaylı Debug
# Debug log seviyesini artır
sudo resolvectl log-level debug
# Logları takip et
journalctl -u systemd-resolved -f
# Sorgu yap ve logları gözlemle
dig google.com
# Log seviyesini geri al
sudo resolvectl log-level info
Bu çok detaylı log üretir ama neyin nereye gittiğini tam olarak görmeni sağlar. Özellikle “DNSSEC validation failed” gibi mesajlar görebilirsin. DNSSEC sorunları için:
# DNSSEC'i geçici olarak devre dışı bırak
sudo resolvectl dnssec off
# resolved.conf'ta kalıcı olarak kapat
# /etc/systemd/resolved.conf içinde:
# DNSSEC=no
Özet Teşhis Akışı
Sorunla karşılaştığında takip edeceğin mantıksal sıra şöyle olmalı:
- Ağ bağlantısı:
ping 8.8.8.8ile IP bağlantısı var mı? - DNS sorgusu:
dig @8.8.8.8 google.comile dış DNS doğrudan çalışıyor mu? - Yerel yapılandırma:
cat /etc/resolv.confvecat /etc/nsswitch.confdoğru mu? - Cache servisler:
systemctl status systemd-resolved nscd dnsmasqçalışıyor mu? - Getent testi:
getent hosts google.comtüm zinciri test ediyor - Firewall:
tcpdump port 53ile UDP/TCP 53 trafiği geçiyor mu? - Uygulama özelinde: Container, VPN veya özel servis yapılandırması var mı?
Sonuç
DNS sorunları çoğu zaman göründüğünden daha basittir ama karmaşık sistemlerde, özellikle systemd-resolved, NetworkManager, VPN istemcileri ve container runtime’larının bir arada çalıştığı ortamlarda katmanlar arası çakışmalar can sıkıcı hale gelebilir. En büyük hata, hemen resolv.conf‘u elle düzenleyip işi çözüldü zannetmektir. Çünkü bu dosya sistem yeniden başladığında veya NetworkManager devreye girdiğinde sıfırlanabilir.
Kalıcı çözüm için her zaman yapılandırmanın hangi katmanda yönetildiğini anla: NetworkManager mı, systemd-resolved mi, DHCP istemcisi mi? Oradan müdahale et. getent hosts ve dig +trace komutlarını sevmeye başlarsan, DNS sorunları artık seni o kadar korkutmaz. Ve bir sonraki “DNS çalışmıyor” panik çağrısında herkes ekranlara bakarken sen sakin bir şekilde resolvectl flush-caches yazıp sorunu dakikalar içinde çözersin.
