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/hostname dosyası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 zaman resolved.conf veya resolvectl ü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-hostname ile 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-resolved yeterli değilse resolvectl flush-caches ve networkctl reload kombinasyonunu deneyin.
  • VPN sonrası DNS sızıntısı: VPN bağlandıktan sonra resolvectl status ile 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.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir