Saya ingin menjalankan perintah di Linux dengan cara yang tidak dapat membuat atau membuka file apa pun untuk ditulis. Seharusnya masih dapat membaca file seperti biasa (jadi chroot kosong bukan pilihan), dan masih dapat menulis ke file yang sudah terbuka (terutama stdout).
Poin bonus jika menulis file ke direktori tertentu (yaitu direktori saat ini) masih dimungkinkan.
Saya mencari solusi yang merupakan proses-lokal, yaitu tidak melibatkan konfigurasi hal-hal seperti AppArmor atau SELinux untuk seluruh sistem, atau root privilege. Ini mungkin melibatkan pemasangan modul kernel mereka.
Saya melihat kemampuan dan ini akan bagus dan mudah, jika ada kemampuan untuk membuat file. ulimit adalah pendekatan lain yang nyaman, jika mencakup use case ini.
strace
memberi tahu Anda file apa yang sedang dibuka oleh program. Mengapa Anda ingin melakukan ini? Apakah ini program khusus, atau Anda ingin ini untuk pengujian atau yang lainnya? Bisakah Anda menjalankan program sebagai pengguna / grup yang tidak memiliki izin untuk menulis hampir di mana-mana kecuali di direktori saat ini? Distribusi Linux modern menggunakan ide grup untuk setiap pengguna, jadi ini seharusnya relatif mudah diatur.Jawaban:
Bagaimana dengan membuat chroot kosong, lalu mengikat-mount filesystem utama sebagai read-only di dalam chroot?
Mungkin akan menjadi seperti ini untuk membuat bind-mount read-only:
Anda dapat mengikat direktori lain yang Anda ingin memiliki akses tulis bagi penjara. Berhati-hatilah jika Anda perlu untuk me-mount direktori khusus (/ dev /, / proc /, / sys /), memasang mereka apa adanya mungkin tidak aman.
sumber
/foo/
jalur ke sistem file utama?Tampaknya alat yang tepat untuk pekerjaan ini adalah
fseccomp
Berdasarkan padasync-ignoring
kode f oleh Bastian Blank, saya membuat file yang relatif kecil ini yang menyebabkan semua anak-anaknya tidak dapat membuka file untuk menulis:Di sini Anda dapat melihat bahwa masih mungkin untuk membaca file:
Itu tidak mencegah menghapus file, atau memindahkannya, atau operasi file lain selain membuka, tetapi itu bisa ditambahkan.
Alat yang memungkinkan ini tanpa harus menulis kode C adalah syscall_limiter .
sumber
Apakah Anda ingin menulis pengganti
open(…)
fungsi, dan memuatnya menggunakan LD_PRELOAD?sumber
open
... Ya, saya akan mempertimbangkan untuk menggunakan solusi yang ada yang menggunakan pendekatan ini, ya.write(…)
juga.Solusi paling sederhana mungkin adalah program pembungkus yang menciptakan namespace filesystem baru dengan mount filesystem yang relevan read-only dan kemudian mengeksekusi program yang Anda coba batasi.
Inilah yang
systemd
dilakukan ketika Anda menggunakanReadOnlyDirectories=
untuk menandai direktori tertentu sebagai hanya-baca untuk layanan. Ada jugaunshare
perintahutil-linux
yang dapat melakukan pekerjaan menciptakan namespace baru, sehingga Anda dapat melakukan sesuatu seperti:di mana
wrapper
kemudian hanya perlu memount ulang sistem file seperti yang diperlukan sebelum memulai program target nyata.Satu-satunya masalah adalah Anda harus
root
menciptakan namespace baru ...sumber
Anda dapat menjalankannya di chroot, memasang versi khusus
/tmp
dan bagian dalamnya. Mungkin systemd sangat membantu, dan khususnya systemd-nspawn (1) , yang terlihat seperti yang Anda inginkan.sumber
Sebuah mesin virtual akan memungkinkan skrip untuk menulis di mana saja tanpa mempengaruhi sistem host, dan untuk memeriksa ke mana ia sebenarnya mencoba menulis, yang tampaknya menjadi tujuan.
Misalnya, Anda dapat dengan mudah memulai Arch Linux
sumber
Melakukan beberapa pengaturan awal sebagai root adalah cara termudah. Secara khusus, chroot menjadi bind mount read-only adalah jalur dengan resistansi paling rendah.
Anda dapat menggunakan bindf alih-alih
mount --bind
membuat tampilan baca-saja tanpa harus menjadi root. Namun, Anda perlu melakukan sesuatu sebagai root untuk mencegah akses ke file lain, seperti chroot.Pendekatan lain adalah ke
LD_PRELOAD
perpustakaan yang menghubungkan ke dalam pembukaan file dan menolak untuk mengizinkan penulisan. Ini tidak memerlukan hak istimewa. Dari perspektif keamanan, ini dapat di-bypass, tetapi tidak masalah untuk kasus penggunaan Anda di mana Anda hanya perlu memuat fitur tertentu dan bukan kode asli yang arbitrer. Namun, saya tidak tahu perpustakaan yang ada untuk ini.LD_PRELOAD
juga dapat digunakan untuk membatasi program ke tampilan hanya baca yang dibuat denganmount --bind
ataubindfs
; lagi, saya tidak tahu perpustakaan yang ada.Pada Debian dan turunannya, Anda dapat mengatur lingkungan schroot . Schroot adalah root setuid dan perlu dikonfigurasi sebagai root, tetapi dapat dijalankan oleh pengguna yang berwenang.
Metode yang tidak memerlukan kerja sama dari root adalah menjalankan proses di mesin virtual. Anda dapat mengatur KVM atau VirtualBox, atau mode pengguna Linux . Ini agak kelas berat, dan akan berarti konsumsi memori tambahan, tetapi seharusnya tidak mempengaruhi kecepatan perhitungan simbolik mentah secara signifikan.
Bagaimana cara "memenjarakan" suatu proses tanpa menjadi root? mungkin memberikan beberapa inspirasi.
sumber
Salah satu cara untuk setidaknya mencegah proses menulis file (tetapi tidak membuatnya) adalah dengan menelepon
ulimit -f 0
terlebih dahulu. Ini akan membatalkan proses segera setelah mencoba menulis ke file, tetapi membuat file kosong masih mungkin.sumber