Korumalı alana alma

Bu makalede, Bazel'de korumalı alana alma, sandboxfs yükleme ve korumalı alan ortamınızdaki hata ayıklama işlemleri açıklanmaktadır.

Korumalı alan, işlemleri birbirlerinden veya bir sistemdeki kaynaklardan izole eden bir izin kısıtlama stratejisidir. Bazel için bu, dosya sistemi erişimini kısıtlamak anlamına gelir.

Bazel'in dosya sistemi korumalı alanı, yalnızca bilinen girişleri içeren bir çalışma dizininde işlemleri çalıştırır. Örneğin, derleyiciler ve diğer araçlar, mutlak yolları bilmedikleri sürece erişmemeleri gereken kaynak dosyaları görmezler.

Korumalı alan oluşturma, ana makine ortamını hiçbir şekilde gizlemez. İşlemler, dosya sistemindeki tüm dosyalara serbestçe erişebilir. Ancak, kullanıcı ad alanlarını destekleyen platformlarda işlemler, çalışma dizini dışındaki dosyaları değiştiremez. Bu, derleme grafiğinde, derlemenin yeniden oluşturulabilirliğini etkileyebilecek gizli bağımlılıklar olmamasını sağlar.

Bazel, her işlem için yürütme sırasında işlemin çalışma dizini görevi gören bir execroot/ dizini oluşturur. execroot/, işlem için kullanılan tüm giriş dosyalarını içerir ve oluşturulan tüm çıkışlar için kapsayıcı görevi görür. Daha sonra Bazel, işletim sistemi tarafından sağlanan bir teknik olan Linux'taki container'ları ve macOS'teki sandbox-exec öğesini execroot/ içindeki işlemi sınırlandırmak için kullanır.

Korumalı alana alma nedenleri

  • İşlem korumalı alanı olmadan Bazel, bir aracın beyan edilmemiş giriş dosyaları (işlemin bağımlılıklarında açıkça listelenmeyen dosyalar) kullanıp kullanmadığını bilmez. Beyan edilmemiş giriş dosyalarından biri değiştiğinde Bazel hâlâ yapının güncel olduğunu ve aksiyonu yeniden oluşturmayacağını düşünüyor. Bu durum, hatalı bir artımlı derlemeye yol açabilir.

  • Önbellek girişlerinin yanlış şekilde yeniden kullanılması, uzaktan önbelleğe alma sırasında sorunlara yol açar. Paylaşılan bir önbellekteki kötü bir önbellek girişi projedeki her geliştiriciyi etkiler ve uzak önbelleğin tamamının temizlenmesi uygun bir çözüm değildir.

  • Korumalı alan oluşturma, uzaktan yürütme davranışını taklit eder. Bir derleme, korumalı alan ile sorunsuz çalışıyorsa uzaktan yürütmeyle de çalışır. Uzaktan yürütmenin tüm gerekli dosyaları (yerel araçlar dahil) yüklemesini sağlayarak yeni bir derleyiciyi denemek veya mevcut bir araçta değişiklik yapmak istediğinizde araçları kümedeki her makineye yükleme zorunluluğuna kıyasla derleme kümelerinin bakım maliyetlerini önemli ölçüde azaltabilirsiniz.

Kullanılacak korumalı alan stratejisi

Strateji bayraklarıyla, varsa ne tür bir korumalı alan kullanmak istediğinizi seçebilirsiniz. sandboxed stratejisini kullanan Bazel, aşağıda listelenen korumalı alan uygulamalarından birini seçer ve işletim sistemine özel bir korumalı alanı daha az genel olan genel bir korumalı alana tercih eder. --worker_sandboxing işaretini geçerseniz kalıcı çalışanlar genel bir korumalı alanda çalışır.

local (diğer adıyla standalone) stratejisi, herhangi bir korumalı alan oluşturmaz. Yalnızca eylemin komut satırını, çalışma dizini çalışma alanınızın execroot değerine ayarlanmış olarak yürütür.

processwrapper-sandbox, herhangi bir "gelişmiş" özellik gerektirmeyen bir korumalı alan stratejisidir. Kullanıma hazır tüm POSIX sistemlerinde çalışmalıdır. Orijinal kaynak dosyalarını işaret eden sembolik bağlantılardan oluşan bir korumalı alan dizini oluşturur. İşlemin komut satırını, çalışma dizini execroot yerine bu dizine ayarlanmış şekilde yürütür, ardından bilinen çıkış yapılarını korumalı alanın dışına taşıyarak korumalı alanı siler. Bu, işlemin bildirilmemiş giriş dosyalarını yanlışlıkla kullanmasını ve execroot'u bilinmeyen çıkış dosyalarıyla doldurmasını önler.

linux-sandbox bir adım daha ileri giderek processwrapper-sandbox temellerini sağlamlaştırır. Docker'ın arka planda yaptığı gibi, işlemi ana makineden izole etmek için Linux Ad Alanlarını (Kullanıcı, Ekleme, PID, Ağ ve IPC ad alanları) kullanır. Yani korumalı alan dizini hariç tüm dosya sistemini salt okunur hale getirir. Böylece işlem, ana makine dosya sistemindeki hiçbir şeyi yanlışlıkla değiştiremez. Bu, $Home dizininizi yanlışlıkla rm--rf olarak çalıştıran hatalı bir test gibi durumları önler. İsteğe bağlı olarak, işlemin ağa erişmesini de engelleyebilirsiniz. linux-sandbox, eylemin diğer işlemleri görmesini engellemek ve sondaki tüm işlemleri (işlem tarafından oluşturulan arka plan programları da dahil) güvenilir bir şekilde sona erdirmek için PID ad alanlarını kullanır.

darwin-sandbox de benzer ancak macOS için geçerlidir. Linux korumalı alanı ile hemen hemen aynı performansı göstermek için Apple'ın sandbox-exec aracını kullanır.

İşletim sistemleri tarafından sağlanan mekanizmalardaki kısıtlamalar nedeniyle linux-sandbox ve darwin-sandbox, "iç içe yerleştirilmiş" bir senaryoda çalışmaz. Docker, container büyüsü için Linux ad alanlarını da kullandığından docker run --privileged kullanmadığınız sürece linux-sandbox eklentisini bir Docker container'ında kolayca çalıştıramazsınız. macOS'te, sandbox-exec dosyasını zaten korumalı alana alınmış bir işlemin içinde çalıştıramazsınız. Bu nedenle, bu durumlarda Bazel otomatik olarak processwrapper-sandbox kullanmaya başlar.

Yanlışlıkla daha katı bir yürütme stratejisiyle derlememe gibi bir derleme hatası almayı tercih ediyorsanız Bazel'ın kullanmaya çalıştığı yürütme stratejileri listesini açıkça değiştirin (örneğin, bazel build --spawn_strategy=worker,linux-sandbox).

Dinamik yürütme genellikle yerel yürütme için korumalı alan gerektirir. Devre dışı bırakmak için --experimental_local_lockfree_output işaretini iletin. Dinamik yürütme, kalıcı çalışanları sessiz bir şekilde korumalı alana alır.

Korumalı alana almanın olumsuz yönleri

  • Korumalı alana alma, ek kurulum ve söküm maliyetine neden olur. Bu maliyetin ne kadar büyük olacağı, derlemenin şekli ve ana makine işletim sisteminin performansı gibi birçok faktöre bağlıdır. Linux'ta korumalı derlemeler nadiren yüzde birkaçdan daha yavaştır. --reuse_sandbox_directories ayarlamak kurulum ve ayırma maliyetini azaltabilir.

  • Korumalı alan, aracın sahip olabileceği tüm önbelleği etkili bir şekilde devre dışı bırakır. Daha zayıf korumalı alan garantileri karşılığında kalıcı çalışanlar kullanarak bu durumu azaltabilirsiniz.

  • Multiplex çalışanlar için açık çalışan desteğinin korumalı alana alınması gerekir. Multiplex korumalı alan oluşturmayı desteklemeyen çalışanlar, dinamik yürütme altında singleplex çalışanlar olarak çalışır. Bu da ek bellek maliyetine neden olabilir.

sandboxfs

sandboxfs, temel dosya sisteminin rastgele bir görünümünü zaman cezası olmadan sunan bir FUSE dosya sistemidir. Bazel, her işlem için anında execroot/ oluşturmak amacıyla sandboxfs kullanarak binlerce sistem çağrısı yapma maliyetinden kurtulur. FUSE ek yükü nedeniyle execroot/ içinde daha fazla G/Ç daha yavaş olabilir.

Sandboxf yükleme

sandboxfs uygulamasını yüklemek ve bununla bir Bazel derlemesi gerçekleştirmek için aşağıdaki adımları uygulayın:

İndir

sandboxfs ikili programının PATH içinde yer alması için sandboxfs indirip yükleyin.

Çalıştırma sandboxfs

  1. (yalnızca macOS) OSXFUSE uygulamasını yükleyin.
  2. (yalnızca macOS) Çalıştır:

    sudo sysctl -w vfs.generic.osxfuse.tunables.allow_other=1
    

    Temel macOS sistem hizmetlerinin korumalı alan üzerinden çalıştığından emin olmak için bu işlemi kurulumdan sonra ve her yeniden başlatmadan sonra yapmanız gerekir.

  3. --experimental_use_sandboxfs ile Bazel derlemesi çalıştırın.

    bazel build target --experimental_use_sandboxfs
    

Sorun giderme

Yürütülen işlemler için ek açıklama olarak darwin-sandbox veya linux-sandbox yerine local ifadesini görürseniz bu, korumalı alanın devre dışı bırakıldığı anlamına gelebilir. Etkinleştirmek için --genrule_strategy=sandboxed --spawn_strategy=sandboxed değerini iletin.

Hata ayıklama

Korumalı alanla ilgili sorunları gidermek için aşağıdaki stratejileri uygulayın.

Devre dışı bırakılmış ad alanları

Google Kubernetes Engine küme düğümleri veya Debian gibi bazı platformlarda, güvenlikle ilgili endişeler nedeniyle kullanıcı ad alanları varsayılan olarak devre dışı bırakılır. /proc/sys/kernel/unprivileged_userns_clone dosyası mevcutsa ve 0 değerini içeriyorsa aşağıdaki komutu çalıştırarak kullanıcı ad alanlarını etkinleştirebilirsiniz:

   sudo sysctl kernel.unprivileged_userns_clone=1

Kural çalıştırma hataları

Korumalı alan, sistem kurulumu nedeniyle kuralları yürütemeyebilir. namespace-sandbox.c:633: execvp(argv[0], argv): No such file or directory gibi bir mesaj görürseniz korumalı alanı, geneller için --strategy=Genrule=local ve diğer kurallar için --spawn_strategy=local ile devre dışı bırakmayı deneyin.

Derleme hataları için ayrıntılı hata ayıklama

Derlemeniz başarısız olduysa --verbose_failures ve --sandbox_debug kullanarak Bazel'ın korumalı alanı ayarlayan bölüm de dahil olmak üzere derlemeniz başarısız olduğunda çalıştırılan komutu tam olarak göstermesini sağlayın.

Örnek hata mesajı:

ERROR: path/to/your/project/BUILD:1:1: compilation of rule
'//path/to/your/project:all' failed:

Sandboxed execution failed, which may be legitimate (such as a compiler error),
or due to missing dependencies. To enter the sandbox environment for easier
debugging, run the following command in parentheses. On command failure, a bash
shell running inside the sandbox will then automatically be spawned

namespace-sandbox failed: error executing command
  (cd /some/path && \
  exec env - \
    LANG=en_US \
    PATH=/some/path/bin:/bin:/usr/bin \
    PYTHONPATH=/usr/local/some/path \
  /some/path/namespace-sandbox @/sandbox/root/path/this-sandbox-name.params --
  /some/path/to/your/some-compiler --some-params some-target)

Artık oluşturulan korumalı alan dizinini inceleyebilir, Bazel'ın oluşturduğu dosyaları görebilir ve nasıl davrandığını görmek için komutu tekrar çalıştırabilirsiniz.

--sandbox_debug kullandığınızda Bazel'in korumalı alan dizinini silmediğini unutmayın. Aktif olarak hata ayıklama yapmıyorsanız zaman içinde diskinizi doldurduğundan --sandbox_debug'yi devre dışı bırakmanız gerekir.