hostnamectl ve systemd-resolved ile Linux DNS Yapılandırması ve Yönetimi
Bir production sunucusunda DNS ayarları bozulduğunda, saatler içinde onlarca servisin çöktüğüne tanık olmuşsunuzdur muhtemelen. Özellikle systemd’nin hayatımıza girmesiyle birlikte Linux’ta DNS yönetimi hem güçlendi hem de karmaşıklaştı. hostnamectl ve systemd-resolved ikilisi, doğru kullanıldığında bu karmaşıklığı yönetilebilir bir düzene sokuyor. Bu yazıda, gerçek senaryolar üzerinden bu araçların nasıl çalıştığını ve production ortamlarında nasıl yapılandırılması gerektiğini ele alacağız.
systemd-resolved Nedir ve Neden Önemli?
Eski günlerde /etc/resolv.conf dosyasını elle düzenler, işi bitirirdik. Ama modern Linux dağıtımlarında bu dosya artık çoğunlukla bir symlink. Ubuntu 18.04’ten itibaren, Fedora’da, Arch’ta ve diğer systemd tabanlı dağıtımlarda /etc/resolv.conf genellikle /run/systemd/resolve/stub-resolv.conf veya /run/systemd/resolve/resolv.conf dosyasına işaret ediyor.
systemd-resolved, bir stub DNS resolver olarak çalışıyor. Yani 127.0.0.53:53 adresinde dinliyor ve gelen DNS sorgularını cache’liyor, DNSSEC doğrulaması yapıyor, farklı arayüzler için farklı DNS sunucuları kullanıyor. Bu özellikle VPN senaryolarında çok işe yarıyor: bir network arayüzü üzerinden gelen sorgular farklı bir DNS’e, diğerleri farklı bir DNS’e yönlendirilebiliyor.
Servisin durumunu kontrol etmekle başlayalım:
systemctl status systemd-resolved
resolvectl status
resolvectl status komutu size şu an hangi DNS sunucularının kullanıldığını, hangi domain’ler için hangi sunucuların devrede olduğunu ve DNSSEC durumunu detaylıca gösterir. Bunu ilk kez çalıştırdığınızda “bu kadar bilgi nereye gizleniyordu” diye düşünebilirsiniz.
hostnamectl ile Hostname Yönetimi
hostnamectl komutuna çoğu zaman sadece hostname değiştirmek için başvurulur, ama bu araç aslında daha fazlasını yapıyor. Linux’ta üç farklı hostname tipi var:
- Static hostname:
/etc/hostnamedosyasında saklanan, kalıcı hostname. Reboot’tan sonra da geçerli. - Transient hostname: Kernel tarafından tutulan, geçici hostname. DHCP veya mDNS tarafından değiştirilebilir.
- Pretty hostname: İnsan tarafından okunabilir, özel karakter içerebilen isim. Örneğin “Ahmet’in Sunucusu” gibi.
# Mevcut hostname bilgilerini görüntüle
hostnamectl status
# Static hostname'i değiştir
hostnamectl set-hostname prod-web-01.example.com
# Pretty hostname ayarla
hostnamectl set-hostname "Production Web Server 01" --pretty
# Sadece transient hostname'i değiştir (reboot'ta sıfırlanır)
hostnamectl set-hostname test-node --transient
Bir fintech şirketinde çalışırken karşılaştığım bir sorundan bahsedeyim: Uygulama sunucuları kendi hostname’lerini API gateway’e kayıt ettiriyordu. Bir güncelleme sırasında hostnamectl ile static hostname değiştirildi ama /etc/hosts güncellenmedi. Sonuç olarak uygulama kendi kendine ulaşamaz hale geldi. Bu yüzden hostname değişikliklerinde her zaman /etc/hosts dosyasını da kontrol edin:
# Hostname değişikliği sonrası kontrol listesi
hostname -f # FQDN'yi doğrula
cat /etc/hosts # 127.0.1.1 satırını kontrol et
ping -c 1 $(hostname) # Kendi kendine erişimi test et
resolvectl query $(hostname) # DNS çözümlemesini test et
/etc/resolv.conf Meselesi
Bu dosya hakkında ciddi bir kafa karışıklığı var. Sisteminizde şunu çalıştırın:
ls -la /etc/resolv.conf
Eğer şöyle bir çıktı görüyorsanız:
/etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
systemd-resolved’ın stub modunda çalıştığını görüyorsunuzdur. Bu modda tüm DNS sorguları 127.0.0.53‘e yönlendirilir. Eğer şuna işaret ediyorsa:
/etc/resolv.conf -> ../run/systemd/resolve/resolv.conf
Bu durumda systemd-resolved bypass edilmiş, gerçek DNS sunucuları doğrudan kullanılıyor demektir. Her iki modun da avantajları var.
Bazı uygulamalar (özellikle eski Java uygulamaları veya musl libc kullanan Alpine tabanlı containerlar) stub resolver’ı sevmez. Bu tür durumlarda:
# Stub modundan çık, doğrudan DNS kullan
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
# Ya da elle /etc/resolv.conf yaz (systemd-resolved'ı tamamen devre dışı bırak)
sudo systemctl disable --now systemd-resolved
sudo rm /etc/resolv.conf
sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
sudo bash -c 'echo "nameserver 8.8.4.4" >> /etc/resolv.conf'
Ama production’da systemd-resolved’ı tamamen devre dışı bırakmak yerine doğru yapılandırmayı öğrenmek çok daha sağlıklı bir yaklaşım.
systemd-resolved Yapılandırması: /etc/systemd/resolved.conf
Ana yapılandırma dosyası /etc/systemd/resolved.conf. Bu dosyadaki varsayılan değerlerin büyük kısmı yorum satırı olarak gelir. İşte gerçek bir production yapılandırması örneği:
cat /etc/systemd/resolved.conf
[Resolve]
# Birincil ve yedek DNS sunucuları
DNS=1.1.1.1 1.0.0.1
FallbackDNS=8.8.8.8 8.8.4.4
# Arama domain'leri
Domains=example.com internal.example.com
# DNSSEC doğrulaması - production'da allow-downgrade güvenli başlangıç noktası
DNSSEC=allow-downgrade
# DNS over TLS - opportunistic mod önce denesin, olmazsa plain devam etsin
DNSOverTLS=opportunistic
# DNS cache boyutu
Cache=yes
CacheFromLocalhost=no
# mDNS (local network service discovery için)
MulticastDNS=yes
# LLMNR (genellikle kapatılabilir)
LLMNR=no
Yapılandırmayı değiştirdikten sonra servisi yeniden başlatmayı unutmayın:
sudo systemctl restart systemd-resolved
resolvectl status
Split DNS: Kurumsal Ortamlarda Kritik Yapılandırma
Bu bölüm, özellikle VPN kullanan ya da hem iç hem dış DNS çözümlemesi gereken ortamlarda çalışanlar için kritik. systemd-resolved’ın en güçlü özelliklerinden biri per-interface DNS yapılandırması.
Diyelim ki internal.company.com domain’indeki kaynaklar şirket DNS sunucusunda, geri kalan her şey public DNS’te çözümlenmeli. Bunu systemd-networkd ile şöyle yapılandırabilirsiniz:
# /etc/systemd/network/20-wired.network
cat > /etc/systemd/network/20-wired.network << 'EOF'
[Match]
Name=eth0
[Network]
DHCP=yes
DNS=10.0.0.53
Domains=~internal.company.com ~company.local
[DHCP]
UseDNS=false
EOF
Buradaki tilde (~) önemli: ~internal.company.com ifadesi “bu domain için bu DNS’i kullan” anlamına geliyor. Tilde olmadan o domain varsayılan arama listesine eklenir.
Veya NetworkManager kullanıyorsanız:
# NetworkManager bağlantısına DNS ekle
nmcli connection modify "Wired connection 1"
ipv4.dns "10.0.0.53"
ipv4.dns-search "~internal.company.com"
nmcli connection up "Wired connection 1"
Yapılandırmanın doğru çalışıp çalışmadığını test etmek için:
# Belirli bir domain için hangi DNS'in kullanıldığını göster
resolvectl query internal-app.internal.company.com
# DNS çözümleme istatistikleri
resolvectl statistics
# Cache'i temizle
resolvectl flush-caches
# Belirli bir arayüzün DNS ayarlarını göster
resolvectl dns eth0
resolvectl domain eth0
DNS Sorun Giderme: Gerçek Senaryolar
Senaryo 1: Container Ortamında DNS Çözümleme Sorunu
Docker ile çalışırken sık karşılaşılan bir problem: container içinden dış DNS çalışıyor ama iç servisler çözümlenemiyor. Sorun genellikle Docker’ın 127.0.0.53‘ü container içine taşıyamamasından kaynaklanıyor.
# Host'ta durumu kontrol et
resolvectl status | grep -A5 "Global"
# Docker daemon için özel DNS yapılandırması
cat > /etc/docker/daemon.json << 'EOF'
{
"dns": ["10.0.0.53", "1.1.1.1"],
"dns-search": ["internal.company.com"]
}
EOF
sudo systemctl restart docker
Senaryo 2: DNSSEC Hataları
Bazı ortamlarda, özellikle şirket proxy’leri arkasında, DNSSEC doğrulaması başarısız olur ve DNS çözümlemesi tamamen durur.
# DNSSEC durumunu kontrol et
resolvectl status | grep DNSSEC
# Sorunlu domain'i test et
resolvectl query --type=DNSKEY problematic-domain.com
# Geçici olarak DNSSEC'i devre dışı bırak
sudo resolvectl dnssec eth0 no
# Kalıcı çözüm için resolved.conf'u güncelle
sudo sed -i 's/#DNSSEC=.*/DNSSEC=no/' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved
Senaryo 3: DNS Cache Sorunları
Bir domain’in IP’si değişti ama sistem hala eski IP’ye gidiyor:
# Önce cache'i kontrol et
resolvectl query etkilenen-domain.com
# TTL bilgisini de görmek için
resolvectl query --cache=no etkilenen-domain.com
# Cache'i tamamen temizle
sudo resolvectl flush-caches
# İstatistikleri sıfırla
sudo resolvectl reset-statistics
# Doğrulama
resolvectl statistics
Gelişmiş: DNS over HTTPS (DoH) Yapılandırması
systemd-resolved native olarak DNS over HTTPS desteklemiyor, ancak bunun için dnscrypt-proxy ya da local bir DoH proxy kullanabilirsiniz. Ama DNS over TLS (DoT) natively destekleniyor:
# /etc/systemd/resolved.conf'a ekle
sudo tee -a /etc/systemd/resolved.conf > /dev/null << 'EOF'
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com
DNSOverTLS=yes
EOF
sudo systemctl restart systemd-resolved
# DoT bağlantısını doğrula
resolvectl status | grep -i "dns over tls"
DoT yapılandırmasında # işaretinden sonra gelen kısım SNI (Server Name Indication) için kullanılıyor. Bu, TLS sertifikasının doğrulanmasını sağlıyor.
Monitoring ve Logging
Production ortamında DNS’i izlemek kritik. Aniden artan DNS hata oranları bir servis kesintisinin ilk sinyali olabilir:
# systemd-resolved loglarını izle
journalctl -u systemd-resolved -f
# Son 1 saatin logları
journalctl -u systemd-resolved --since "1 hour ago"
# Sadece hataları göster
journalctl -u systemd-resolved -p err
# DNS istatistiklerini periyodik olarak logla (monitoring script)
cat > /usr/local/bin/dns-stats.sh << 'EOF'
#!/bin/bash
echo "=== DNS Statistics $(date) ==="
resolvectl statistics
echo "=== Cache Status ==="
resolvectl status | grep -E "Cache|DNSSEC|DNS Servers"
EOF
chmod +x /usr/local/bin/dns-stats.sh
# Cron ile her 5 dakikada çalıştır
echo "*/5 * * * * root /usr/local/bin/dns-stats.sh >> /var/log/dns-stats.log 2>&1"
| sudo tee /etc/cron.d/dns-monitor
Ansible ile DNS Yapılandırması Otomasyonu
Onlarca sunucuda aynı DNS yapılandırmasını elle yapmak ciddi bir efor. İşte basit bir Ansible playbook:
# dns-config.yml
---
- name: Configure systemd-resolved
hosts: all
become: yes
tasks:
- name: Set hostname
hostname:
name: "{{ inventory_hostname }}"
- name: Configure resolved.conf
copy:
dest: /etc/systemd/resolved.conf
content: |
[Resolve]
DNS=1.1.1.1 1.0.0.1
FallbackDNS=8.8.8.8 8.8.4.4
Domains={{ dns_search_domains | default('example.com') }}
DNSSEC=allow-downgrade
DNSOverTLS=opportunistic
Cache=yes
owner: root
group: root
mode: '0644'
notify: restart systemd-resolved
- name: Ensure stub-resolv.conf symlink
file:
src: /run/systemd/resolve/stub-resolv.conf
dest: /etc/resolv.conf
state: link
force: yes
handlers:
- name: restart systemd-resolved
systemd:
name: systemd-resolved
state: restarted
# Playbook'u çalıştır
ansible-playbook -i inventory dns-config.yml
# Sadece belirli bir grup için
ansible-playbook -i inventory dns-config.yml --limit webservers
Sık Yapılan Hatalar ve Çözümleri
Yıllar içinde gördüğüm en yaygın hataları listeleyeyim:
/etc/resolv.conf‘u elle düzenlemek: systemd-resolved aktifken bu dosya üzerine yazılanlar kaybolur. Her zamanresolved.confveyaresolvectlüzerinden yapılandırın.
127.0.0.53‘ü public IP olarak görmek: Bazı güvenlik taramaları veya monitoring araçları bu adresi garip buluyor. Bu tamamen normal, systemd-resolved’ın stub adresi.
- Hostname ile FQDN karışıklığı:
hostnamectl set-hostnameile kısa isim mi yoksa FQDN mi kullanmalı? Genellikle FQDN kullanın (server01.example.com), kısa isim otomatik türetilir.
- DNS değişikliklerinin uygulanmaması:
systemctl restart systemd-resolvedyeterli değilseresolvectl flush-cachesvenetworkctl reloadkombinasyonunu deneyin.
- VPN sonrası DNS sızıntısı: VPN bağlandıktan sonra
resolvectl statusile hangi interface’in hangi DNS’i kullandığını mutlaka kontrol edin. Split DNS yanlış yapılandırıldığında iç trafiğiniz public DNS’e gidebilir.
Sonuç
hostnamectl ve systemd-resolved, ilk başta karmaşık görünse de aslında Linux’taki DNS yönetimini standartlaştıran ve güçlendiren araçlar. Eski resolv.conf ve nsswitch.conf dünyasına kıyasla çok daha esnek bir yapı sunuyorlar; özellikle split DNS, DNS over TLS ve per-interface yapılandırma konularında.
Kritik nokta şu: Bu araçları anlamadan üretim ortamında çalışmak, bir gün mutlaka sorun yaşamanıza neden olacak. /etc/resolv.conf‘un neden bir symlink olduğunu, 127.0.0.53‘ün nereden geldiğini ve split DNS’in nasıl çalıştığını bilen bir sistem yöneticisi, sorun anında saatlerce değil dakikalarca uğraşır.
Kendi ortamınızdaki DNS yapılandırmasını bugün resolvectl status ile bir kontrol edin. Büyük ihtimalle sürprizlerle karşılaşacaksınız.
