Saya sedang mengerjakan proyek yang mengimplementasikan simulasi terdistribusi: kode arbitrer dieksekusi pada banyak node dan hasilnya kemudian dikumpulkan dan dikumpulkan.
Setiap node adalah turunan dari mesin virtual Ubuntu Linux dan menjalankan proses master yang mengurus meneruskan kode yang akan dieksekusi ke sejumlah proses pekerja (1 untuk setiap inti).
Pertanyaan ini adalah tentang bagaimana memastikan bahwa setiap pekerja beroperasi di lingkungan berpasir tanpa menggunakan mesin virtual untuk masing-masing pekerja. Persyaratan pasti untuk pekerja adalah:
- fs : tidak ada izin menulis, izin hanya-baca terbatas pada satu direktori (dan sub-folder)
- net : hanya komunikasi lokal yang diizinkan (IPC, TCP, apa pun ...)
- mem : tutup penggunaan memori (tidak ada memori swap) membunuh jika melebihi batas mem
- cpu : hanya 1 inti yang diizinkan, bunuh jika melebihi batas waktu
Tidak ada batasan lain yang harus dipaksakan: pekerja harus dapat memuat pustaka dinamis (dari folder read-only), menelurkan utas atau proses baru, fungsi sistem panggilan, ecc ecc tetapi batas-batas harus diwariskan oleh entitas spawned / loaded dan harus diterapkan dengan cara yang bijaksana (misalnya kita tidak dapat memiliki pekerja menelurkan dua utas yang menggunakan 800MB masing-masing adalah batas memori untuk pekerja tersebut adalah 1GB).
Tak perlu dikatakan bahwa seharusnya tidak ada cara bagi pekerja untuk meningkatkan haknya.
Saya menghabiskan banyak waktu meninjau alternatif yang tersedia (SELinux, AppArmor, cgroups, ulimit, ruang nama Linux, LXC, Docker, ...) untuk solusi paling sederhana yang memenuhi persyaratan saya tetapi pengalaman saya di lapangan terbatas.
Pemahaman saat ini: LXC dan Docker sedikit di sisi berat untuk kasus penggunaan saya dan tidak sepenuhnya aman 1 . AppArmor lebih disukai daripada SELinux karena konfigurasi yang lebih mudah, gunakan untuk pembatasan fs dan net; cgroups lebih disukai daripada ulimit (yang beroperasi pada satu proses tunggal), menggunakannya untuk pembatasan mem dan cpu.
Apakah ini cara paling sederhana untuk mencapai tujuan saya? Bisakah saya menggunakan AppArmor atau cgroup secara eksklusif? Apakah ada lubang keamanan yang jelas dalam model saya? Pedoman harus "pekerja diizinkan untuk menjatuhkan dirinya sendiri tetapi tidak ada yang lain" .
Jawaban:
Ya, Anda dapat menggunakan cgroups dan SELinux / AppArmor secara eksklusif untuk memantau dan mengontrol kode arbitrer yang akan Anda jalankan.
Dengan cgroup, Anda dapat melakukan hal berikut:
cpuset
subsistemmemory
subsistem, lacak bahkan garpu. Lihat https://github.com/gsauthof/cgmemtime untuk contoh.lo
dengannet_prio
subsistem.Dan dengan SELinux / AppArmor, Anda dapat membatasi akses baca / tulis proses.
Catatan: Saya tidak terbiasa dengan AppArmor, tetapi ini adalah sistem Kontrol Akses Wajib (MAC), artinya menjaga menulis dan membaca adalah tugasnya.
Menggunakan sistem ini adalah masalah penulisan konfigurasi yang tepat. Tentu saja, semua ini jauh lebih mudah diucapkan daripada dilakukan. Jadi, inilah beberapa tautan referensi untuk membantu Anda memulai:
Semoga berhasil!
sumber
Saya akan membuang SELinux untuk AppArmor hanya jika saya menggunakan Ubuntu . (sangat sulit)
LXC tidak aman dengan sendirinya Jika Anda memerlukan keamanan Anda harus menggunakannya melalui libvirt (berdasarkan SELinux MLS ).
Masalah Anda tidak terbatas jadi jangan mencoba untuk menemukan solusi apa pun dari rak dan tanpa waktu yang tak terbatas, ingatlah bahwa bahkan kernel.org dihancurkan dan baru-baru ini FBI menyatakan bahwa seseorang telah menggunakan sistem mereka selama bertahun-tahun tanpa terdeteksi sampai sekarang.
Saya akan menggunakan LXC / libvirt untuk keamanan yang cukup bagus atau saya akan mencoba wadah "baru" intel , yang menggunakan VM sangat ringan untuk wadah Anda dengan penggunaan DAX / KSM yang jelas (saya belum mengujinya tetapi mereka terlihat sangat memang menjanjikan).
Jika Anda khawatir tentang eksploitasi kernel, grsecurity adalah solusi Anda tetapi Anda harus mengintegrasikannya dengan solusi container Anda (pasti sakit kepala).
Jadi tugas yang tidak mudah pasti, LXC / libvirt benar-benar rapi tetapi mungkin wadah yang jelas adalah cara untuk pergi.
Buruh pelabuhan? Saya belum / tidak akan menggunakan buruh pelabuhan untuk lebih dari pengujian lokal ketika tidak ada kotak gelandangan yang tersedia, mereka membutuhkan cara kerja lebih banyak dan cara komunitas yang lebih baik.
Tentu saja systemd container juga bagus, tetapi saya berasumsi Anda tidak suka / menginginkannya karena Anda bahkan tidak menyebutkannya dan itu bukan solusi agnostik vendor.
Jika Anda menginginkan sesuatu yang "lebih mudah" dan lebih amatir, Anda dapat memeriksa firejail , saya telah menggunakannya untuk beberapa "aplikasi" desktop dan melakukan pekerjaannya (cukup mudah untuk membuat templat untuk aplikasi khusus Anda, gunakan "pribadi" pasang di atas dir Anda dan batasi jaringan hanya untuk penggunaan lokal, proses melahirkan mewarisi induk dan terus ...).
Ceria dan bersenang-senang tanpa menjadi gila. ;)
sumber
seccomp-bpf adalah pilihan lain yang bekerja dengan baik untuk OpenSSH, vsftpd dan Chromium hanya memiliki exit (), sigreturn (), read () juga menggunakan write () meskipun memungkinkan penyaringan panggilan sistem menggunakan aturan Filter Packet Berkeley yang dapat dikonfigurasi. Ini juga dapat digunakan bersama dengan cgroup untuk memori, cpu dll ...
https://wiki.mozilla.org/Security/Sandbox/Seccomp
sumber
Anda mungkin ingin melihat ke dalam sistem komputasi grid. Secara khusus, BOINC ( http://boinc.berkeley.edu ) memeriksa hampir semua kotak Anda.
Saya percaya ini beroperasi pada parameter Anda seperti itu:
fs: dapat membaca / menulis ke direktori sendiri, di tempat lain
net: dapat dikonfigurasi untuk hanya mengizinkan akses jaringan ke server BOINC Anda, tetapi tidak default di luar kotak IIRC
mem: ya, pisahkan batas memori untuk mesin idle dan non-idle
cpu: ya, bahkan dapat mengatakan "jangan jalankan jika komputer tidak siaga"
sumber