Mengamankan lapisan virtualisasi dengan sVirt berbasis SELinux dan AppArmor profiles untuk QEMU, konfigurasi security_driver libvirt, sandbox proses dan seccomp, serta best practice meminimalkan device dan argumen yang berisiko

VM adalah proses — dan proses bisa dibajak. Episode 17 membahas pertahanan lapisan virtualisasi: bagaimana SELinux/AppArmor membungkus proses QEMU, bagaimana libvirt menerapkan label keamanan (sVirt), dan praktik isolasi yang membuat satu VM yang dikompromi tidak otomatis berarti host ikut jatuh.
Ini bukan sekadar teori: kerentanan seperti bug di device emulation bisa dieksploitasi dari guest ke host. Lapisan keamanan yang benar adalah yang membatasi blast radius dari eksploitasi semacam itu.
Ketika guest mengirim I/O jahat ke device emulasi, eksploitasi bisa terjadi di proses QEMU (user-space). Dari sana, penyerang bisa mencoba:
/proc//dev yang terbuka.Target pertahanan: membuat proses QEMU hanya bisa menyentuh yang memang milik VM itu — file image-nya, socket-nya, dan tidak lebih.
sVirt adalah integrasi SELinux dengan libvirt. Setiap VM dilabeli dengan tipe svirt_t dan MCS category unik (svirt_image_t:s0:c123,c456). Dua VM dengan category berbeda tidak bisa membaca file satu sama lain, bahkan oleh root di dalam guest.
Cek label pada VM dan image:
ps -eZ | grep qemu
ls -Z /var/lib/libvirt/images/web1.qcow2Contoh output — perhatikan category unik c100,c200:
system_u:system_r:svirt_t:s0:c100,c200 ... qemu-system-x86_64
system_u:system_r:svirt_image_t:s0:c100,c200 ... web1.qcow2Kedua label harus cocok. Jika ls -Z menampilkan svirt_image_t:s0 tanpa category, berarti MCS belum aktif — cek security_driver libvirt.
Pada Ubuntu/Debian, AppArmor menggantikan peran SELinux. Paket libvirt-daemon-system mengaktifkan profile untuk QEMU secara otomatis:
sudo aa-status | grep -i qemuOutput harus memuat libvirt-... dan qemu dalam status enforce. Profile ini membatasi path yang boleh dibuka QEMU — image di luar /var/lib/libvirt/images butuh izin tambahan.
Warning
Jika AppArmor dalam mode complain atau profile tidak ada, QEMU bisa membaca file apa pun yang bisa dibaca user. Verifikasi aa-status secara berkala — terutama setelah update paket yang bisa me-reset profil.
Jika kalian menyimpan image di luar lokasi default, izinkan path tersebut:
# Tambahkan ke /etc/apparmor.d/local/usr.lib.libvirt.virt-aa-helper
/data/vms/ r,
/data/vms/** rwk,Lalu sudo systemctl reload apparmor.
libvirt memilih mekanisme label lewat konfigurasi security_driver. Lihat yang aktif:
sudo virsh net-edit default # contoh, atau:
sudo cat /etc/libvirt/qemu.conf | grep -i security_driverDi /etc/libvirt/qemu.conf, bisa diatur:
security_driver = "selinux" # RHEL/Fedora
security_driver = "apparmor" # Ubuntu/Debian
security_driver = "none" # ❌ hindari di produksi"none" menonaktifkan pelabelan — VM bisa saling akses. Untuk produksi, pastikan driver yang sesuai aktif dan konsisten dengan distro.
Di luar MAC (SELinux/AppArmor), QEMU juga punya sandbox bawaan:
-sandbox on — mengunci perilaku QEMU (misal menolak exec, mencegah proses fork baru).Pada libvirt, sandbox diatur di XML:
<seclabel type='dynamic' model='selinux' relabel='yes'/>
<qemu:commandline>
<qemu:arg value='-sandbox'/>
<qemu:arg value='on,obsolete=deny,elevateprivileges=deny,spawn=deny'/>
</qemu:commandline>elevateprivileges=deny menolak peningkatan privilege; spawn=deny mencegah QEMU menjalankan proses tambahan. Ini memperkecil permukaan serangan jika QEMU dikompromi.
Rangkuman praktik yang harus menjadi kebiasaan:
-no-reboot/-no-shutdown tanpa kebutuhan; periksa semua argumen yang memperluas akses host.qemu-guest-agent dengan hati-hati: agent memberi akses dalam guest — pasang hanya bila dibutuhkan, dengan protokol terkontrol.ps -eZ vs ls -Z.aa-status, sestatus, dan log libvirt secara berkala.Tip
Latih kebiasaan "prinsip least privilege" di level VM: beri tiap VM device, network, dan storage seminimal mungkin. Ini bahasa yang sama dengan pola yang akan kalian temui di sVirt & seccomp pada container.
security_driver = none: mudah, tapi membuka VM satu sama lain — jangan untuk produksi.audit/dmesg.-sandbox yang terlalu ketat: beberapa fitur (misal -nic tap helper) butuh izin — uji perubahan di staging dulu.Pada episode 17 ini, kalian telah membangun pertahanan lapisan virtualisasi.
Inti yang harus dibawa pulang:
security_driver di qemu.conf menentukan mekanisme; jangan none di produksi.-sandbox on mempersempit syscall dan privilege QEMU.Di episode 18 selanjutnya, kita akan membahas PCI/GPU passthrough dengan VFIO — mengaktifkan IOMMU, binding driver vfio-pci, -device vfio-pci,host=XX:XX, passthrough GPU untuk workload berat, dan perbedaannya dengan virtio-gpu. Sampai jumpa di episode 18!