Donanımdan Sanala: NixOS Altında KVM/QEMU, BIOS Ayarları ve Ağ Köprüleri

Masaüstü bilgisayarınızda sanal makine çalıştırmak istediğinizde önünüzde iki temel yol vardır: Ya VirtualBox gibi kullanıcı alanında (user-space) çalışan ve donanımla arasına kalın katmanlar koyan hantal emülatörleri seçeceksiniz ya da Linux çekirdeğinin doğrudan içine entegre edilmiş KVM (Kernel-based Virtual Machine) gücünü arkanıza alacaksınız.

Yeni nesil anakart, işlemci ve ekran kartı içeren sistem güncellememin ardından ilk işim, temiz bir QEMU/KVM sanallaştırma laboratuvarı kurmak oldu. Bu yazıda, anakartın BIOS menüsündeki gizli ayarlardan başlayıp, donanımı NixOS çekirdeği seviyesinde doğrulamaya ve ardından ağ köprüleri ile Windows VM optimizasyonlarına kadar uzanan süreci özetliyorum.


1. Donanım Hazırlığı: BIOS Ayarları

Sanallaştırma performansının “bare-metal” (fiziksel makineye yakın) olabilmesi için ilk kilidi anakart seviyesinde açmamız gerekiyor. BIOS arayüzünde aktif ettiğimiz üç temel donanım standardı var:

İleri Düzey BIOS Optimizasyonları (Power User):

Sanallaştırma altyapısını daha verimli hale getirmek ve Windows 11 gibi katı gereksinimleri olan modern misafir sistemleri hazırlamak için BIOS üzerinde şu opsiyonel ayarlara da odaklanabilirsiniz:


2. Çekirdek (Kernel) Seviyesinde Doğrulama

BIOS ayarlarını yaptıktan sonra Linux çekirdeğinin bu ayarları tanıyıp tanımadığını teyit etmek oldukça önemlidir. Donanım sorgularında çıktıları filtrelemek için POSIX standartlarında en temiz ve kabuk bağımsız sonuç veren awk komutlarını kullanıyoruz.

EXPO RAM Frekans Kontrolü:

RAM’lerin hedeflenen 6400 MT/s hızında çalışıp çalışmadığını kontrol etmek için:

nix shell nixpkgs#dmidecode -c sudo dmidecode -t memory | awk '/Speed:/ || /Configured Memory/'

(Not: dmidecode komutu, korumalı SMBIOS tablolarına erişmek için doğrudan /dev/mem veya /sys/firmware/dmi/tables okumak zorundadır. Bu yüzden nix shell içinde çalıştırılırken bile sudo yetkisi ister.)

IOMMU Kontrolü:

IOMMU’nun kernel tarafından tanınıp tanınmadığını doğrulamak için:

dmesg | awk '/IOMMU/'

SVM (Sanallaştırma) Kontrolü:

Sanallaştırma desteğinin doğrulanması için:

lscpu | awk '/Virtualization/'

3. NixOS Sanallaştırma Yapılandırması (virt.nix)

Tüm donanım doğrulandıktan sonra NixOS tarafında sanallaştırma motorunu ayağa kaldıracak deklaratif modülümüzü (virt.nix) oluşturduk.

{ config, pkgs, ... }:

{
  # QEMU/KVM Sanallaştırma Altyapısı
  virtualisation.libvirtd = {
    enable = true;
    qemu = {
      package = pkgs.qemu_kvm;
      runAsRoot = true;
      swtpm.enable = true; # Windows 11 için Donanımsal TPM Emülasyonu
    };
  };

  # Gerekli Yardımcı Araçlar
  environment.systemPackages = with pkgs; [
    virt-manager  # Görsel yönetim arayüzü
    virt-viewer   # Konsol görüntüleyici
    spice spice-gtk spice-protocol # Akıcı ekran ve ses aktarımı
    virtio-win    # Windows misafirler için performans sürücüleri
    bridge-utils  # Ağ köprüleme araçları
    dnsmasq       # DHCP/DNS yönetimi
    ebtables      # Köprü filtreleme kuralları
  ];

  # USB Cihaz aktarımı için ajan
  services.spice-vdagentd.enable = true;
}

4. NixOS Ağ Köprüsü ve İnternet Çıkmazı (rp_filter)

NixOS üzerinde KVM kuran neredeyse herkesin yaşadığı en büyük sorun: Sanal makine kurulur, host makineye ping atar ama dış dünyaya (internet) bir türlü bağlanamaz.

Bunun suçlusu, NixOS’un siber güvenliği korumak için varsayılan olarak çok katı uyguladığı Reverse Path Filtering (rp_filter) ayarıdır. Sanal makinenin oluşturduğu sanal ağ arayüzünden (virbr0) gelen NAT paketleri, kernel tarafından “şüpheli” (routing tablosundaki en iyi yolla eşleşmeyen) kabul edilip sessizce droplanır.

Bu durumu sistemi savunmasız bırakmadan çözmenin yolu, firewall filtresini tamamen kapatmak değil, sadece esnetmektir:

networking.firewall.checkReversePath = "loose";

loose modu sayesinde kernel, paketin geldiği arayüzün mutlak en iyi rota olup olmadığına bakmaz; sadece geçerli bir dönüş rotası (reverse path) olup olmadığını kontrol eder. Bu da libvirt köprülerinin sorunsuz çalışması için fazlasıyla yeterlidir.

[!TIP] NixOS’un en büyük güzelliği buradadır: Bu tarz kritik ağ ve güvenlik ayarlarını değiştirdikten sonra ağda beklenmedik bir kesinti veya kilitlenme yaşarsanız, nixos-rebuild switch --rollback komutunu çalıştırarak veya sistemi yeniden başlatıp GRUB/systemd-boot menüsünden bir önceki generation’ı seçerek saniyeler içinde eski kararlı halinize dönebilirsiniz.


5. Windows Server Kurulumu ve VirtIO Sürücüleri

KVM üzerinde Windows Server (veya Windows 11) kurarken diski veya ağ kartını standart IDE/SATA/e1000 modunda bırakırsanız KVM’in gerçek hızına ulaşamazsınız. Disk kontrolcüsünü VirtIO Block ve ağ kartını VirtIO olarak seçmek zorundasınız.

Ancak Windows, kurulum ekranında bu modern sürücüleri yerleşik olarak barındırmaz ve disk seçme ekranında karşınıza bomboş bir sayfa gelir. Çözüm:

  1. Sanal makineyi oluştururken ikincil bir CD-ROM ekleyip NixOS’ta sisteme kurduğumuz /run/current-system/sw/share/virtio-win/virtio-win.iso dosyasını bu sürücüye bağlayın.
  2. Windows kurulum ekranında “Load Driver” (Sürücü Yükle) seçeneğine tıklayın.
  3. VirtIO disk sürücüsü için: viostor -> w11 -> amd64 klasörünü seçip diski görünür kılın.
  4. Kurulum bittikten sonra da Aygıt Yöneticisi’ndeki eksik aygıtları aynı ISO içindeki ilgili klasörlerden yükleyin:
    • Ağ kartı için: NetKVM
    • Bellek yönetimi (Memory Ballooning) için: Balloon
    • SPICE / Guest Agent iletişimi için: vioserial

6. Impermanence (Kalıcılık) Entegrasyonu

Benim sistemim her açılışta tamamen sıfırlanan bir RAM-disk (tmpfs root) üzerinde çalışıyor. Haliyle sanal makinelerimizin XML tanımları, ağ konfigürasyonları ve disk imajları eğer önlem almazsak sistem yeniden başladığı an uçup gidecektir.

Sanal makine verilerimizi korumak için impermanence.nix yapılandırmamıza şu dizini kalıcı (/persist) kılacak şekilde ekledik:

  # Sanal makine tanımları ve ayarlarının saklandığı dizin
  directories = [
    "/var/lib/libvirt"
  ];

Ayrıca büyük boyutlu sanal disk imajlarımızın (.qcow2) root disk limitlerimizi doldurmasını engellemek ve impermanence’ın bind-mount katmanında yedekleme karmaşası yaratmasını önlemek için /persist/libvirt-vms adında bir dizin oluşturup storage pool’u oraya yönlendirdik.

Buradaki amaç diskleri fiziksel olarak ayırmak değil (her ikisi de aynı fiziksel NVMe SSD üzerindeki /persist subvolume’undadır), sadece gigabaytlarca yer kaplayan devasa disk dosyalarını küçük XML tanımları ve ağ konfigürasyonlarından izole ederek daha temiz ve yönetilebilir bir yedekleme kapsamı oluşturmaktır.

Sonuç olarak: Sıfır entropili, her boot aşamasında tertemiz açılan ama sanal laboratuvarımızın verilerini donanımsal ivmelendirmeyle birlikte kalıcı olarak barındıran taş gibi bir sanallaştırma altyapımız oldu.


İlgili: NixOS 26.05 ve systemd-initrd: Ephemeral Root Uyumlu mu?

EOF.