Yazılara geri dön
Yazı

Riskli Komut Testleri için systemd-nspawn ve seccomp Profilleri Kullanımı

systemd-nspawn ile Capabilities= ve SystemCallFilter= seçeneklerini kullanarak chroot'tan daha güvenli yalıtım sağlayın. Tehlikeli komutları güvenli bir ortamda test edin.

Linuxsystemdsecuritysandboxseccomp

Riskli komutlar veya scriptler test etmem gerektiğinde, bunları doğrudan üretim makinelerinde çalıştırmaktan kaçınıyorum. Bunun yerine, systemd-nspawn ile seccomp profillerini kullanarak sıkı bir kontrol altında bir sandbox oluşturuyorum. Bu yöntem, temel bir chroot'a kıyasla daha fazla güvenlik sunar çünkü spesifik Linux yeteneklerini düşürebilir ve sistem çağrılarını çekirdek seviyesinde filtreleyebiliyorum.

Why systemd-nspawn over chroot

Bir chroot sadece kök dosya sistemi görünümünü değiştirir. O jaıl içindeki süreçlerin neler yapabileceğini sınırlamaz. Bir süreç tehlikeye atarsa, doğru yeteneklere sahipse veya tehlikeli sistem çağrılarını yapabiliyorsa ayrıcalık yükseltmesi yapmaya devam edebilir. systemd-nspawn ise, tam bir container bağlamında çalışır, yerleşik kaynak yalıtımı sağlar ve systemd'nin güvenlik özellikleriyle doğrudan entegre olur.

Sık sık savunma derinliğinin saldırı yüzeyini azaltarak başladığını söylerim. Kritik hizmetler için OOM skorunu sınırlama konulu yazımda da bahsettiğim ilkeleri burada da uyguluyorum: bir sürece ihtiyacı kadar fazla erişim vermeyin.

Setting up a minimal sandbox

Container için minimum bir dizin ağacı oluşturarak başlarım. Dağınıza göre debootstrap veya pacstrap kullanabilirsiniz, ama hızlı test için bazen sadece birkaç ikiliyi kopyalarım.

mkdir -p /var/container/test
mkdir -p /var/container/test/{bin,lib,lib64,usr/bin,usr/lib}
cp /bin/bash /var/container/test/bin/
cp /bin/ls /var/container/test/bin/
# Copy required libraries using ldd

Ardından katı varsayılanlarla container'ı başlatırım:

systemd-nspawn \
  --directory=/var/container/test \
  --capability=none \
  --system-call-filter=@system-service \
  --private-network \
  --bind=/tmp:/tmp

--capability=none bayrağı tüm Linux yeteneklerini kaldırır. Container içinde süreç root olarak çalışsa bile, çekirdek modülü yükleme veya ağ arayüzlerini değiştirme gibi ayrıcalıklı işlemler yapamaz.

Filtering system calls with SystemCallFilter=

Gerçek gücün SystemCallFilter= ile geldiği noktadayız. Tüm sistem çağrilarına izin vermek yerine, temel işlem için gerekenleri sadece beyaz listeye alırım. @system-service grubu iyi bir başlangıç noktasıdır—read, write, exit, getpid gibi çağrılarını içerir ancak tehlikeli olanları engeller.

Engellenenleri görmek için, kısıtlı bir sistem çağrısını kullanan bir komutla test ederim:

systemd-nspawn --directory=/var/container/test --capability=none --system-call-filter=@system-service bash -c 'echo 1 > /proc/sys/kernel/sysrq'

Bu komut, /proc/sys yazma işlemi için sys_admin yeteneği gerektiği ve onu düşürdüğümüz için izin reddedildi hatasıyla başarısız olur. Ayrıca temel open/write çağrısı izinli olsa bile, çekirdek kısıtlamayı uygular.

Daha fazla kontrol için özel bir filtre tanımlarım. Örneğin, sadece dosya G/İ ve süreç kontrolüne izin vermek için:

systemd-nspawn --directory=/var/container/test \
  --capability=none \
  --system-call-filter=read,write,open,close,exit,exit_group,fork,clone \
  --bind=/tmp:/tmp

Bu kurulum, socket, connect, bind gibi ağ ile ilgili sistem çağrılarını engeller. Bu sayede ters kabuk veya port tarama gibi işlemler, ikili mevcut olsa bile gerçekleşemez.

Testing risky commands safely

Şimdi curl http://internal-service:8080/admin veya rm -rf / gibi komutları korkmadan çalıştırabilirim. Container komutun başlatmasına izin verebilir ama yasaklanmış bir sistem çağrısı yaptığında başarısız olur.

Bir kez /etc/shadow dosyasını değiştirmeye çalışan bir script test ettim. Container içinde root olarak çalışıyordu ama bu dosyaya yazmak için open sistem çağrısı engellendi çünkü container'ın kök dosya sistemi varsayılan olarak özel ve salt okunurdur, açıkça bağlanmadıkça.

Limitations and gotchas

Bu bir VM yerine geçmez. Çekirdek modülleri veya donanım erişimi test etmeniz gerekiyorsa farklı bir yaklaşım kullanmanız gerekir. Ayrıca, aşırı sıkı sistem çağrısı filtrelemesi, beklenti dışı şekilde meşru ikilileri bozabilir. @system-service ile başlayıp, journal'de SIGSYS hataları gördüğünüzde sadece gereken çağrıları eklemenizi öneririm.

İhlallerini izlemek için şunu kullanabilirsiniz:

journalctl -u [email protected] -f

SECCOMP veya SIGSYS gibi satırlara bakarak hangi sistem çağrısının engellendiğini görebilirsiniz.

When to use this

Bu deseni şu durumlar için kullanırım:

  • Dağıtımdan önce üçüncü taraf scriptleri test etmek
  • Güvenilmeyen giriş işleyicileri çalıştırmak
  • Bilinmeyen bağımlılıkları olan eski araçları yalıtmak

Bir VM'ye göre daha hızlı başlatılır ve görüntü veya katman gerektirmeyen tam bir container çalışma zamanı gibi Docker'dan daha hafiftir.

Final thoughts

systemd-nspawn ve seccomp filtrelemesi, geçici iş yükleri için en küçük ayrıcalık ilkesini uygulamam için pratik bir yol sunar. Mükemmel değil ama yetenek düşürme ve salt okunur bağlamalarla birlikte kullanıldığında, chroot'a kıyasla kaçınılması çok daha zor bir bariyer oluşturur.

Zaten ana makinenizde systemd kullanıyorsanız bu araç zaten kuruludur ve kullanıma hazırdır. Küçük başlayın, filtrelerinizi test edin ve her sandbox'ı kalıcı bir güvenlik garantisi değil geçici bir sınır olarak görünün.


Kapak görseli: personalgraphic.official · CC0 (Openverse / kamu malı) · https://www.flickr.com/photos/198895458@N04/53097628210